mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
sql parser support with subquery, orginaize testcase code imports
This commit is contained in:
@@ -21,15 +21,24 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLSelect extends SQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected SQLSelectQuery query;
|
||||
protected SQLOrderBy orderBy;
|
||||
protected SQLWithSubqueryClause withSubQuery;
|
||||
protected SQLSelectQuery query;
|
||||
protected SQLOrderBy orderBy;
|
||||
|
||||
public SQLSelect(){
|
||||
|
||||
}
|
||||
|
||||
public SQLWithSubqueryClause getWithSubQuery() {
|
||||
return withSubQuery;
|
||||
}
|
||||
|
||||
public void setWithSubQuery(SQLWithSubqueryClause withSubQuery) {
|
||||
this.withSubQuery = withSubQuery;
|
||||
}
|
||||
|
||||
public SQLSelectQuery getQuery() {
|
||||
return this.query;
|
||||
}
|
||||
|
||||
+91
-102
@@ -1,102 +1,91 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
|
||||
public class SubqueryFactoringClause extends OracleSQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static class Entry extends OracleSQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SQLIdentifierExpr name;
|
||||
private final List<SQLName> columns = new ArrayList<SQLName>();
|
||||
private SQLSelectQuery subQuery;
|
||||
private SearchClause searchClause;
|
||||
private CycleClause cycleClause;
|
||||
|
||||
public CycleClause getCycleClause() {
|
||||
return cycleClause;
|
||||
}
|
||||
|
||||
public void setCycleClause(CycleClause cycleClause) {
|
||||
this.cycleClause = cycleClause;
|
||||
}
|
||||
|
||||
public SearchClause getSearchClause() {
|
||||
return searchClause;
|
||||
}
|
||||
|
||||
public void setSearchClause(SearchClause searchClause) {
|
||||
this.searchClause = searchClause;
|
||||
}
|
||||
|
||||
public SQLIdentifierExpr getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SQLIdentifierExpr name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SQLSelectQuery getSubQuery() {
|
||||
return subQuery;
|
||||
}
|
||||
|
||||
public void setSubQuery(SQLSelectQuery subQuery) {
|
||||
this.subQuery = subQuery;
|
||||
}
|
||||
|
||||
public List<SQLName> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
acceptChild(visitor, columns);
|
||||
acceptChild(visitor, subQuery);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, entries);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLWithSubqueryClause extends SQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Boolean recursive;
|
||||
private final List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public Boolean getRecursive() {
|
||||
return recursive;
|
||||
}
|
||||
|
||||
public void setRecursive(Boolean recursive) {
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, entries);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public static class Entry extends SQLObjectImpl {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected SQLIdentifierExpr name;
|
||||
protected final List<SQLName> columns = new ArrayList<SQLName>();
|
||||
protected SQLSelectQuery subQuery;
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
acceptChild(visitor, columns);
|
||||
acceptChild(visitor, subQuery);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLIdentifierExpr getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SQLIdentifierExpr name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SQLSelectQuery getSubQuery() {
|
||||
return subQuery;
|
||||
}
|
||||
|
||||
public void setSubQuery(SQLSelectQuery subQuery) {
|
||||
this.subQuery = subQuery;
|
||||
}
|
||||
|
||||
public List<SQLName> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause.Entry;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleWithSubqueryEntry extends Entry implements OracleSQLObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SearchClause searchClause;
|
||||
private CycleClause cycleClause;
|
||||
|
||||
public CycleClause getCycleClause() {
|
||||
return cycleClause;
|
||||
}
|
||||
|
||||
public void setCycleClause(CycleClause cycleClause) {
|
||||
this.cycleClause = cycleClause;
|
||||
}
|
||||
|
||||
public SearchClause getSearchClause() {
|
||||
return searchClause;
|
||||
}
|
||||
|
||||
public void setSearchClause(SearchClause searchClause) {
|
||||
this.searchClause = searchClause;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
acceptChild(visitor, columns);
|
||||
acceptChild(visitor, subQuery);
|
||||
acceptChild(visitor, searchClause);
|
||||
acceptChild(visitor, cycleClause);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@@ -24,7 +23,6 @@ public class OracleSelect extends SQLSelect {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SubqueryFactoringClause factoring;
|
||||
private OracleSelectForUpdate forUpdate;
|
||||
private OracleSelectRestriction restriction;
|
||||
|
||||
@@ -32,14 +30,6 @@ public class OracleSelect extends SQLSelect {
|
||||
|
||||
}
|
||||
|
||||
public SubqueryFactoringClause getFactoring() {
|
||||
return factoring;
|
||||
}
|
||||
|
||||
public void setFactoring(SubqueryFactoringClause factoring) {
|
||||
this.factoring = factoring;
|
||||
}
|
||||
|
||||
public OracleSelectRestriction getRestriction() {
|
||||
return this.restriction;
|
||||
}
|
||||
@@ -71,7 +61,7 @@ public class OracleSelect extends SQLSelect {
|
||||
|
||||
protected void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.factoring);
|
||||
acceptChild(visitor, this.withSubQuery);
|
||||
acceptChild(visitor, this.query);
|
||||
acceptChild(visitor, this.restriction);
|
||||
acceptChild(visitor, this.orderBy);
|
||||
|
||||
@@ -23,11 +23,13 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
@@ -46,10 +48,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ModelRulesCla
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.QueryPartitionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReferenceModelClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause.ReturnRowsClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleWithSubqueryEntry;
|
||||
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.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
|
||||
@@ -82,78 +84,7 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
public OracleSelect select() {
|
||||
OracleSelect select = new OracleSelect();
|
||||
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
|
||||
SubqueryFactoringClause subqueryFactoringClause = new SubqueryFactoringClause();
|
||||
for (;;) {
|
||||
SubqueryFactoringClause.Entry entry = new SubqueryFactoringClause.Entry();
|
||||
entry.setName((SQLIdentifierExpr) this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
exprParser.names(entry.getColumns());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.AS);
|
||||
accept(Token.LPAREN);
|
||||
entry.setSubQuery(query());
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (identifierEquals("SEARCH")) {
|
||||
lexer.nextToken();
|
||||
SearchClause searchClause = new SearchClause();
|
||||
|
||||
if (lexer.token() != Token.IDENTIFIER) {
|
||||
throw new SQLParseException("syntax erorr : " + lexer.token());
|
||||
}
|
||||
|
||||
searchClause.setType(SearchClause.Type.valueOf(lexer.stringVal()));
|
||||
lexer.nextToken();
|
||||
|
||||
acceptIdentifier("FIRST");
|
||||
accept(Token.BY);
|
||||
|
||||
searchClause.getItems().add((OracleOrderByItem) exprParser.parseSelectOrderByItem());
|
||||
|
||||
while (lexer.token() == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
searchClause.getItems().add((OracleOrderByItem) exprParser.parseSelectOrderByItem());
|
||||
}
|
||||
|
||||
accept(Token.SET);
|
||||
|
||||
searchClause.setOrderingColumn((SQLIdentifierExpr) exprParser.name());
|
||||
|
||||
entry.setSearchClause(searchClause);
|
||||
}
|
||||
|
||||
if (identifierEquals("CYCLE")) {
|
||||
lexer.nextToken();
|
||||
CycleClause cycleClause = new CycleClause();
|
||||
exprParser.exprList(cycleClause.getAliases());
|
||||
accept(Token.SET);
|
||||
cycleClause.setMark(exprParser.expr());
|
||||
acceptIdentifier("TO");
|
||||
cycleClause.setValue(exprParser.expr());
|
||||
accept(Token.DEFAULT);
|
||||
cycleClause.setDefaultValue(exprParser.expr());
|
||||
entry.setCycleClause(cycleClause);
|
||||
}
|
||||
|
||||
subqueryFactoringClause.getEntries().add(entry);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
select.setFactoring(subqueryFactoringClause);
|
||||
}
|
||||
withSubquery(select);
|
||||
|
||||
select.setQuery(query());
|
||||
select.setOrderBy(this.parseOrderBy());
|
||||
@@ -226,6 +157,81 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
return select;
|
||||
}
|
||||
|
||||
protected void withSubquery(SQLSelect select) {
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLWithSubqueryClause subqueryFactoringClause = new SQLWithSubqueryClause();
|
||||
for (;;) {
|
||||
OracleWithSubqueryEntry entry = new OracleWithSubqueryEntry();
|
||||
entry.setName((SQLIdentifierExpr) this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
exprParser.names(entry.getColumns());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.AS);
|
||||
accept(Token.LPAREN);
|
||||
entry.setSubQuery(query());
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (identifierEquals("SEARCH")) {
|
||||
lexer.nextToken();
|
||||
SearchClause searchClause = new SearchClause();
|
||||
|
||||
if (lexer.token() != Token.IDENTIFIER) {
|
||||
throw new SQLParseException("syntax erorr : " + lexer.token());
|
||||
}
|
||||
|
||||
searchClause.setType(SearchClause.Type.valueOf(lexer.stringVal()));
|
||||
lexer.nextToken();
|
||||
|
||||
acceptIdentifier("FIRST");
|
||||
accept(Token.BY);
|
||||
|
||||
searchClause.getItems().add((OracleOrderByItem) exprParser.parseSelectOrderByItem());
|
||||
|
||||
while (lexer.token() == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
searchClause.getItems().add((OracleOrderByItem) exprParser.parseSelectOrderByItem());
|
||||
}
|
||||
|
||||
accept(Token.SET);
|
||||
|
||||
searchClause.setOrderingColumn((SQLIdentifierExpr) exprParser.name());
|
||||
|
||||
entry.setSearchClause(searchClause);
|
||||
}
|
||||
|
||||
if (identifierEquals("CYCLE")) {
|
||||
lexer.nextToken();
|
||||
CycleClause cycleClause = new CycleClause();
|
||||
exprParser.exprList(cycleClause.getAliases());
|
||||
accept(Token.SET);
|
||||
cycleClause.setMark(exprParser.expr());
|
||||
acceptIdentifier("TO");
|
||||
cycleClause.setValue(exprParser.expr());
|
||||
accept(Token.DEFAULT);
|
||||
cycleClause.setDefaultValue(exprParser.expr());
|
||||
entry.setCycleClause(cycleClause);
|
||||
}
|
||||
|
||||
subqueryFactoringClause.getEntries().add(entry);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
select.setWithSubQuery(subqueryFactoringClause);
|
||||
}
|
||||
}
|
||||
|
||||
public SQLSelectQuery query() {
|
||||
if (lexer.token() == (Token.LPAREN)) {
|
||||
lexer.nextToken();
|
||||
@@ -644,7 +650,7 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
if (identifierEquals("NOCYCLE")) {
|
||||
hierachical.setNoCycle(true);
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
if (lexer.token() == Token.PRIOR) {
|
||||
lexer.nextToken();
|
||||
hierachical.setPrior(true);
|
||||
@@ -679,7 +685,7 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
if (identifierEquals("NOCYCLE")) {
|
||||
hierachical.setNoCycle(true);
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
if (lexer.token() == Token.PRIOR) {
|
||||
lexer.nextToken();
|
||||
hierachical.setPrior(true);
|
||||
|
||||
@@ -29,10 +29,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitionByRangeCla
|
||||
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.OracleWithSubqueryEntry;
|
||||
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.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
|
||||
@@ -266,13 +266,9 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(GroupingSetExpr x);
|
||||
|
||||
boolean visit(SubqueryFactoringClause x);
|
||||
boolean visit(OracleWithSubqueryEntry x);
|
||||
|
||||
void endVisit(SubqueryFactoringClause x);
|
||||
|
||||
boolean visit(SubqueryFactoringClause.Entry x);
|
||||
|
||||
void endVisit(SubqueryFactoringClause.Entry x);
|
||||
void endVisit(OracleWithSubqueryEntry x);
|
||||
|
||||
boolean visit(SearchClause x);
|
||||
|
||||
|
||||
+3
-15
@@ -37,11 +37,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitionByRangeCla
|
||||
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.OracleWithSubqueryEntry;
|
||||
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.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.Entry;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
|
||||
@@ -539,24 +538,13 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SubqueryFactoringClause x) {
|
||||
public boolean visit(OracleWithSubqueryEntry x) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SubqueryFactoringClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(Entry x) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(Entry x) {
|
||||
public void endVisit(OracleWithSubqueryEntry x) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
+8
-23
@@ -62,10 +62,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitionByRangeCla
|
||||
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.OracleWithSubqueryEntry;
|
||||
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.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
|
||||
@@ -192,7 +192,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
return;
|
||||
}
|
||||
|
||||
if(isPrettyFormat()) {
|
||||
if (isPrettyFormat()) {
|
||||
if (x.getParent() != null) {
|
||||
print(";");
|
||||
} else {
|
||||
@@ -213,12 +213,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
public boolean visit(OracleAggregateExpr expr) {
|
||||
print(expr.getMethodName());
|
||||
print("(");
|
||||
|
||||
|
||||
if (expr.getOption() != null) {
|
||||
print(expr.getOption().toString());
|
||||
print(' ');
|
||||
}
|
||||
|
||||
|
||||
printAndAccept(expr.getArguments(), ", ");
|
||||
print(")");
|
||||
|
||||
@@ -394,8 +394,8 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
}
|
||||
|
||||
public boolean visit(OracleSelect x) {
|
||||
if (x.getFactoring() != null) {
|
||||
x.getFactoring().accept(this);
|
||||
if (x.getWithSubQuery() != null) {
|
||||
x.getWithSubQuery().accept(this);
|
||||
println();
|
||||
}
|
||||
|
||||
@@ -1122,7 +1122,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SubqueryFactoringClause.Entry x) {
|
||||
public boolean visit(OracleWithSubqueryEntry x) {
|
||||
x.getName().accept(this);
|
||||
|
||||
if (x.getColumns().size() > 0) {
|
||||
@@ -1154,22 +1154,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SubqueryFactoringClause.Entry x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SubqueryFactoringClause x) {
|
||||
print("WITH");
|
||||
incrementIndent();
|
||||
println();
|
||||
printlnAndAccept(x.getEntries(), ", ");
|
||||
decrementIndent();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SubqueryFactoringClause x) {
|
||||
public void endVisit(OracleWithSubqueryEntry x) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
+4
-16
@@ -58,11 +58,10 @@ import com.alibaba.druid.sql.dialect.oracle.ast.clause.OraclePartitionByRangeCla
|
||||
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.OracleWithSubqueryEntry;
|
||||
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.SubqueryFactoringClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SubqueryFactoringClause.Entry;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
|
||||
@@ -281,7 +280,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
x.getOrderBy().setParent(x);
|
||||
}
|
||||
|
||||
accept(x.getFactoring());
|
||||
accept(x.getWithSubQuery());
|
||||
accept(x.getQuery());
|
||||
|
||||
setCurrentTable(x, (String) x.getQuery().getAttribute("table"));
|
||||
@@ -810,18 +809,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SubqueryFactoringClause x) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SubqueryFactoringClause x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(Entry x) {
|
||||
public boolean visit(OracleWithSubqueryEntry x) {
|
||||
Map<String, String> aliasMap = getAliasMap();
|
||||
if (aliasMap != null) {
|
||||
String alias = null;
|
||||
@@ -839,7 +827,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(Entry x) {
|
||||
public void endVisit(OracleWithSubqueryEntry x) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.parser;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
@@ -29,8 +30,10 @@ import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
|
||||
public class SQLSelectParser extends SQLParser {
|
||||
|
||||
protected SQLExprParser exprParser;
|
||||
|
||||
public SQLSelectParser(String sql){
|
||||
@@ -40,7 +43,7 @@ public class SQLSelectParser extends SQLParser {
|
||||
public SQLSelectParser(Lexer lexer){
|
||||
super(lexer);
|
||||
}
|
||||
|
||||
|
||||
public SQLSelectParser(SQLExprParser exprParser){
|
||||
super(exprParser.getLexer());
|
||||
this.exprParser = exprParser;
|
||||
@@ -49,6 +52,8 @@ public class SQLSelectParser extends SQLParser {
|
||||
public SQLSelect select() {
|
||||
SQLSelect select = new SQLSelect();
|
||||
|
||||
withSubquery(select);
|
||||
|
||||
select.setQuery(query());
|
||||
select.setOrderBy(parseOrderBy());
|
||||
|
||||
@@ -159,6 +164,46 @@ public class SQLSelectParser extends SQLParser {
|
||||
return queryRest(queryBlock);
|
||||
}
|
||||
|
||||
protected void withSubquery(SQLSelect select) {
|
||||
if (lexer.token() == Token.WITH) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLWithSubqueryClause withQueryClause = new SQLWithSubqueryClause();
|
||||
|
||||
if (lexer.token == Token.RECURSIVE || identifierEquals("RECURSIVE")) {
|
||||
lexer.nextToken();
|
||||
withQueryClause.setRecursive(true);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
|
||||
entry.setName((SQLIdentifierExpr) this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
exprParser.names(entry.getColumns());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.AS);
|
||||
accept(Token.LPAREN);
|
||||
entry.setSubQuery(query());
|
||||
accept(Token.RPAREN);
|
||||
|
||||
withQueryClause.getEntries().add(entry);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
select.setWithSubQuery(withQueryClause);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseWhere(SQLSelectQueryBlock queryBlock) {
|
||||
if (lexer.token() == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
@@ -221,7 +266,7 @@ public class SQLSelectParser extends SQLParser {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
SQLTableSource tableSource;
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
if (lexer.token() == Token.SELECT || lexer.token() == Token.WITH) {
|
||||
SQLSelect select = select();
|
||||
accept(Token.RPAREN);
|
||||
queryRest(select.getQuery());
|
||||
|
||||
@@ -98,6 +98,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
|
||||
public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
|
||||
@@ -550,6 +551,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLSelect x) {
|
||||
x.getQuery().setParent(x);
|
||||
|
||||
if (x.getWithSubQuery() != null) {
|
||||
x.getWithSubQuery().accept(this);
|
||||
println();
|
||||
}
|
||||
|
||||
x.getQuery().accept(this);
|
||||
|
||||
if (x.getOrderBy() != null) {
|
||||
@@ -1193,4 +1200,40 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
print(" UNIQUE INDEX");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWithSubqueryClause x) {
|
||||
print("WITH");
|
||||
if (x.getRecursive() == Boolean.TRUE) {
|
||||
print(" RECURSIVE");
|
||||
}
|
||||
incrementIndent();
|
||||
println();
|
||||
printlnAndAccept(x.getEntries(), ", ");
|
||||
decrementIndent();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWithSubqueryClause.Entry x) {
|
||||
x.getName().accept(this);
|
||||
|
||||
if (x.getColumns().size() > 0) {
|
||||
print(" (");
|
||||
printAndAccept(x.getColumns(), ", ");
|
||||
print(")");
|
||||
}
|
||||
println();
|
||||
print("AS");
|
||||
println();
|
||||
print("(");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getSubQuery().accept(this);
|
||||
decrementIndent();
|
||||
println();
|
||||
print(")");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
|
||||
public interface SQLASTVisitor {
|
||||
|
||||
@@ -405,4 +406,12 @@ public interface SQLASTVisitor {
|
||||
void endVisit(SQLColumnUniqueIndex x);
|
||||
|
||||
boolean visit(SQLColumnUniqueIndex x);
|
||||
|
||||
void endVisit(SQLWithSubqueryClause x);
|
||||
|
||||
boolean visit(SQLWithSubqueryClause x);
|
||||
|
||||
void endVisit(SQLWithSubqueryClause.Entry x);
|
||||
|
||||
boolean visit(SQLWithSubqueryClause.Entry x);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
|
||||
public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
@@ -735,4 +736,22 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
public boolean visit(SQLColumnUniqueIndex x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLWithSubqueryClause x) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWithSubqueryClause x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLWithSubqueryClause.Entry x) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLWithSubqueryClause.Entry x) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user