支持subquery_factoring_clause

git-svn-id: http://code.alibabatech.com/svn/druid/trunk@164 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
wenshao
2011-05-20 18:47:26 +00:00
parent 511edb5b63
commit 98053e1252
19 changed files with 564 additions and 80 deletions
@@ -19,7 +19,7 @@ import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@SuppressWarnings("serial")
@@ -52,7 +52,7 @@ public class SQLOrderBy extends SQLObjectImpl {
if (i != 0) {
buf.append(", ");
}
((OracleSelectOrderByItem) this.items.get(i)).output(buf);
((OracleOrderByItem) this.items.get(i)).output(buf);
}
}
}
@@ -16,7 +16,7 @@
package com.alibaba.druid.sql.dialect.oracle.ast;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
public class OracleOrderBy extends SQLOrderBy {
@@ -57,7 +57,7 @@ public class OracleOrderBy extends SQLOrderBy {
if (i != 0) {
buf.append(", ");
}
((OracleSelectOrderByItem) this.items.get(i)).output(buf);
((OracleOrderByItem) this.items.get(i)).output(buf);
}
}
}
@@ -0,0 +1,58 @@
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
public class CycleClause extends OracleSQLObject {
private static final long serialVersionUID = 1L;
private final List<SQLExpr> aliases = new ArrayList<SQLExpr>();
private SQLExpr mark;
private SQLExpr value;
private SQLExpr defaultValue;
public SQLExpr getMark() {
return mark;
}
public void setMark(SQLExpr mark) {
this.mark = mark;
}
public SQLExpr getValue() {
return value;
}
public void setValue(SQLExpr value) {
this.value = value;
}
public SQLExpr getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(SQLExpr defaultValue) {
this.defaultValue = defaultValue;
}
public List<SQLExpr> getAliases() {
return aliases;
}
@Override
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, aliases);
acceptChild(visitor, mark);
acceptChild(visitor, value);
acceptChild(visitor, defaultValue);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,54 @@
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
public class SearchClause extends OracleSQLObject {
private static final long serialVersionUID = 1L;
public static enum Type {
DEPTH, BREADTH
}
private Type type;
private final List<OracleOrderByItem> items = new ArrayList<OracleOrderByItem>();
private SQLIdentifierExpr orderingColumn;
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public List<OracleOrderByItem> getItems() {
return items;
}
public SQLIdentifierExpr getOrderingColumn() {
return orderingColumn;
}
public void setOrderingColumn(SQLIdentifierExpr orderingColumn) {
this.orderingColumn = orderingColumn;
}
@Override
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, items);
acceptChild(visitor, orderingColumn);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,87 @@
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.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
public class SubqueryFactoringClause extends OracleSQLObject {
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 OracleSQLObject {
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
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, columns);
acceptChild(visitor, subQuery);
}
visitor.endVisit(this);
}
}
@Override
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, entries);
}
visitor.endVisit(this);
}
}
@@ -20,13 +20,13 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleSelectOrderByItem extends SQLSelectOrderByItem {
public class OracleOrderByItem extends SQLSelectOrderByItem {
private static final long serialVersionUID = 1L;
private NullsOrderType nullsOrderType;
public OracleSelectOrderByItem(){
public OracleOrderByItem(){
}
@@ -16,6 +16,7 @@
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.ast.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -23,6 +24,7 @@ public class OracleSelect extends SQLSelect {
private static final long serialVersionUID = 1L;
private SubqueryFactoringClause factoring;
private OracleSelectForUpdate forUpdate;
private OracleSelectRestriction restriction;
@@ -30,6 +32,14 @@ public class OracleSelect extends SQLSelect {
}
public SubqueryFactoringClause getFactoring() {
return factoring;
}
public void setFactoring(SubqueryFactoringClause factoring) {
this.factoring = factoring;
}
public OracleSelectRestriction getRestriction() {
return this.restriction;
}
@@ -52,25 +62,14 @@ public class OracleSelect extends SQLSelect {
if (this.orderBy != null) this.orderBy.output(buf);
}
protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof OracleASTVisitor) {
accept0((OracleASTVisitor) visitor);
return;
}
if (visitor.visit(this)) {
acceptChild(visitor, this.query);
acceptChild(visitor, this.restriction);
acceptChild(visitor, this.orderBy);
acceptChild(visitor, this.forUpdate);
}
visitor.endVisit(this);
protected void accept0(SQLASTVisitor visitor) {
accept0((OracleASTVisitor) visitor);
}
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.factoring);
acceptChild(visitor, this.query);
acceptChild(visitor, this.restriction);
acceptChild(visitor, this.orderBy);
@@ -19,11 +19,14 @@ import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeInterval;
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;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.GroupingSetExpr;
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;
@@ -46,6 +49,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateViewStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForeignKey;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRefDataType;
@@ -53,7 +57,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleReferencesConstaint;
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.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
@@ -157,7 +160,7 @@ public interface OracleASTVisitor extends SQLASTVisitor {
void endVisit(OracleSelectJoin x);
void endVisit(OracleSelectOrderByItem x);
void endVisit(OracleOrderByItem x);
void endVisit(OracleSelectPivot x);
@@ -277,7 +280,7 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleSelectJoin x);
boolean visit(OracleSelectOrderByItem x);
boolean visit(OracleOrderByItem x);
boolean visit(OracleSelectPivot x);
@@ -314,28 +317,44 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(SampleClause x);
void endVisit(SampleClause x);
boolean visit(OracleSelectTableReference x);
void endVisit(OracleSelectTableReference x);
boolean visit(PartitionExtensionClause x);
void endVisit(PartitionExtensionClause x);
boolean visit(VersionsFlashbackQueryClause x);
void endVisit(VersionsFlashbackQueryClause x);
boolean visit(AsOfFlashbackQueryClause x);
void endVisit(AsOfFlashbackQueryClause x);
boolean visit(GroupingSetExpr x);
void endVisit(GroupingSetExpr x);
boolean visit(OraclePriorExpr x);
void endVisit(OraclePriorExpr x);
boolean visit(SubqueryFactoringClause x);
void endVisit(SubqueryFactoringClause x);
boolean visit(SubqueryFactoringClause.Entry x);
void endVisit(SubqueryFactoringClause.Entry x);
boolean visit(SearchClause x);
void endVisit(SearchClause x);
boolean visit(CycleClause x);
void endVisit(CycleClause x);
}
@@ -31,11 +31,14 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeInterval;
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;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.GroupingSetExpr;
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;
@@ -72,6 +75,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleConstraintState;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateViewStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForeignKey;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePrimaryKey;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleRefDataType;
@@ -80,7 +84,6 @@ 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.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
@@ -496,6 +499,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
public boolean visit(OracleSelect x) {
if (x.getFactoring() != null) {
x.getFactoring().accept(this);
println();
}
x.getQuery().accept(this);
if (x.getRestriction() != null) {
@@ -567,7 +575,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
return false;
}
public boolean visit(OracleSelectOrderByItem x) {
public boolean visit(OracleOrderByItem x) {
x.getExpr().accept(this);
if (x.getType() != null) {
print(" ");
@@ -717,22 +725,22 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
if (x.isOnly()) {
print("ONLY (");
x.getExpr().accept(this);
if (x.getPartition() != null) {
print(" ");
x.getPartition().accept(this);
}
print(")");
} else {
x.getExpr().accept(this);
if (x.getPartition() != null) {
print(" ");
x.getPartition().accept(this);
}
}
if (x.getSampleClause() != null) {
print(" ");
x.getSampleClause().accept(this);
@@ -746,7 +754,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
decrementIndent();
}
if (x.getFlashback() != null) {
println();
x.getFlashback().accept(this);
@@ -1392,7 +1400,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
@Override
public void endVisit(OracleSelectOrderByItem x) {
public void endVisit(OracleOrderByItem x) {
}
@@ -1479,32 +1487,32 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public boolean visit(SampleClause x) {
print("SAMPLE ");
if (x.isBlock()) {
print("BLOCK ");
}
print("(");
print(x.getPercent());
print(")");
if (x.getSeedValue() != null) {
print(" SEED (");
x.getSeedValue().accept(this);
print(")");
}
return false;
}
@Override
public void endVisit(SampleClause x) {
}
@Override
public void endVisit(OracleSelectTableReference x) {
}
@Override
@@ -1514,7 +1522,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
} else {
print("PARTITION ");
}
if (x.getPartition() != null) {
print("(");
x.getPartition().accept(this);
@@ -1529,7 +1537,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public void endVisit(PartitionExtensionClause x) {
}
@Override
@@ -1545,7 +1553,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public void endVisit(VersionsFlashbackQueryClause x) {
}
@Override
@@ -1560,9 +1568,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public void endVisit(AsOfFlashbackQueryClause x) {
}
@Override
public boolean visit(GroupingSetExpr x) {
print("GROUPING SETS");
@@ -1571,10 +1579,10 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
print(")");
return false;
}
@Override
public void endVisit(GroupingSetExpr x) {
}
@Override
@@ -1586,7 +1594,95 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public void endVisit(OraclePriorExpr x) {
}
@Override
public boolean visit(SubqueryFactoringClause.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(")");
if (x.getSearchClause() != null) {
println();
x.getSearchClause().accept(this);
}
if (x.getCycleClause() != null) {
println();
x.getCycleClause().accept(this);
}
return false;
}
@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) {
}
@Override
public boolean visit(SearchClause x) {
print("SEARCH ");
print(x.getType().name());
print(" FIRST BY ");
printAndAccept(x.getItems(), ", ");
print(" SET ");
x.getOrderingColumn().accept(this);
return false;
}
@Override
public void endVisit(SearchClause x) {
}
@Override
public boolean visit(CycleClause x) {
print("CYCLE ");
printAndAccept(x.getAliases(), ", ");
print(" SET ");
x.getMark().accept(this);
print(" TO ");
x.getValue().accept(this);
print(" DEFAULT ");
x.getDefaultValue().accept(this);
return false;
}
@Override
public void endVisit(CycleClause x) {
}
}
@@ -26,7 +26,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OraclePriorExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleOrderByItem;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
@@ -234,8 +234,8 @@ public class OracleExprParser extends SQLExprParser {
}
@Override
protected OracleSelectOrderByItem parseSelectOrderByItem() {
OracleSelectOrderByItem item = new OracleSelectOrderByItem();
public OracleOrderByItem parseSelectOrderByItem() {
OracleOrderByItem item = new OracleOrderByItem();
item.setExpr(expr());
@@ -251,10 +251,10 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
if (identifierEquals("FIRST")) {
lexer.nextToken();
item.setNullsOrderType(OracleSelectOrderByItem.NullsOrderType.NullsFirst);
item.setNullsOrderType(OracleOrderByItem.NullsOrderType.NullsFirst);
} else if (identifierEquals("LAST")) {
lexer.nextToken();
item.setNullsOrderType(OracleSelectOrderByItem.NullsOrderType.NullsLast);
item.setNullsOrderType(OracleOrderByItem.NullsOrderType.NullsLast);
} else {
throw new ParserException("TODO " + lexer.token());
}
@@ -85,6 +85,7 @@ public class OracleLexer extends Lexer {
map.put("START", Token.START);
map.put("CONNECT", Token.CONNECT);
map.put("PRIOR", Token.PRIOR);
map.put("WITH", Token.WITH);
DEFAULT_ORACLE_KEYWORDS = new Keywords(map);
}
@@ -25,12 +25,16 @@ 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.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.GroupingSetExpr;
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;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectHierachicalQueryClause;
@@ -44,7 +48,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLParseException;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
@@ -59,13 +62,86 @@ public class OracleSelectParser extends SQLSelectParser {
super(lexer);
}
protected SQLExprParser createExprParser() {
protected OracleExprParser createExprParser() {
return new OracleExprParser(lexer);
}
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) createExprParser().name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
createExprParser().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) createExprParser().parseSelectOrderByItem());
while (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
searchClause.getItems().add((OracleOrderByItem) createExprParser().parseSelectOrderByItem());
}
accept(Token.SET);
searchClause.setOrderingColumn((SQLIdentifierExpr) createExprParser().name());
entry.setSearchClause(searchClause);
}
if (identifierEquals("CYCLE")) {
lexer.nextToken();
CycleClause cycleClause = new CycleClause();
createExprParser().exprList(cycleClause.getAliases());
accept(Token.SET);
cycleClause.setMark(createExprParser().expr());
acceptIdentifier("TO");
cycleClause.setValue(createExprParser().expr());
accept(Token.DEFAULT);
cycleClause.setDefaultValue(createExprParser().expr());
entry.setCycleClause(cycleClause);
}
subqueryFactoringClause.getEntries().add(entry);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
select.setFactoring(subqueryFactoringClause);
}
select.setQuery(query());
select.setOrderBy(this.parseOrderBy());
@@ -93,7 +169,7 @@ public class OracleSelectParser extends SQLSelectParser {
select.setOrderBy(this.createExprParser().parseOrderBy());
}
if (identifierEquals("WITH")) {
if (lexer.token() == Token.WITH) {
lexer.nextToken();
if (identifierEquals("READ")) {
@@ -278,7 +354,7 @@ public class OracleSelectParser extends SQLSelectParser {
if (hierachical == null) {
hierachical = new OracleSelectHierachicalQueryClause();
}
acceptIdentifier("WITH");
accept(Token.WITH);
hierachical.setStartWith(this.createExprParser().expr());
}
@@ -102,6 +102,11 @@ public class OracleStatementParser extends SQLStatementParser {
if (lexer.token() == Token.ALTER) {
throw new ParserException("TODO");
}
if (lexer.token() == Token.WITH) {
statementList.add(new SQLSelectStatement(new OracleSelectParser(this.lexer).select()));
continue;
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
@@ -618,7 +618,7 @@ public class SQLExprParser extends SQLParser {
return null;
}
protected SQLSelectOrderByItem parseSelectOrderByItem() throws ParserException {
public SQLSelectOrderByItem parseSelectOrderByItem() throws ParserException {
SQLSelectOrderByItem item = new SQLSelectOrderByItem();
item.setExpr(expr());
@@ -102,6 +102,7 @@ public enum Token {
START("START"),
PRIOR("PRIOR"),
CONNECT("CONNECT"),
WITH("WITH"),
EOF,
ERROR,