oracle sql parser support keep

This commit is contained in:
高铁
2016-03-11 22:08:13 +08:00
parent b66c366f93
commit 9dc9c808f6
9 changed files with 217 additions and 11 deletions
@@ -0,0 +1,42 @@
package com.alibaba.druid.sql.ast;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLKeep extends SQLObjectImpl {
protected DenseRank denseRank;
protected SQLOrderBy orderBy;
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.orderBy);
}
visitor.endVisit(this);
}
public DenseRank getDenseRank() {
return denseRank;
}
public void setDenseRank(DenseRank denseRank) {
this.denseRank = denseRank;
}
public SQLOrderBy getOrderBy() {
return orderBy;
}
public void setOrderBy(SQLOrderBy orderBy) {
if (orderBy != null) {
orderBy.setParent(this);
}
this.orderBy = orderBy;
}
public static enum DenseRank {
FIRST, //
LAST
}
}
@@ -21,6 +21,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLOver;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -31,6 +32,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
protected String methodName;
protected SQLAggregateOption option;
protected final List<SQLExpr> arguments = new ArrayList<SQLExpr>();
protected SQLKeep keep;
protected SQLOver over;
protected SQLOrderBy withinGroup;
protected boolean ignoreNulls = false;
@@ -88,9 +90,23 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
}
public void setOver(SQLOver over) {
if (over != null) {
over.setParent(this);
}
this.over = over;
}
public SQLKeep getKeep() {
return keep;
}
public void setKeep(SQLKeep keep) {
if (keep != null) {
keep.setParent(this);
}
this.keep = keep;
}
public boolean isIgnoreNulls() {
return this.ignoreNulls;
}
@@ -20,6 +20,8 @@ import java.math.BigInteger;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLKeep.DenseRank;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
@@ -753,6 +755,28 @@ public class OracleExprParser extends SQLExprParser {
aggregateExpr.setWithinGroup(withinGroup);
accept(Token.RPAREN);
}
if (lexer.token() == Token.KEEP) {
lexer.nextToken();
SQLKeep keep = new SQLKeep();
accept(Token.LPAREN);
acceptIdentifier("DENSE_RANK");
if (identifierEquals("FIRST")) {
lexer.nextToken();
keep.setDenseRank(DenseRank.FIRST);
} else {
acceptIdentifier("LAST");
keep.setDenseRank(DenseRank.LAST);
}
SQLOrderBy orderBy = this.parseOrderBy();
keep.setOrderBy(orderBy);
aggregateExpr.setKeep(keep);
accept(Token.RPAREN);
}
if (lexer.token() == Token.OVER) {
OracleAnalytic over = new OracleAnalytic();
@@ -30,6 +30,7 @@ import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
@@ -566,9 +567,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
x.getWithinGroup().accept(this);
print(')');
}
if (x.getKeep() != null) {
print(' ');
x.getKeep().accept(this);
}
if (x.getOver() != null) {
print0(" ");
print(' ');
x.getOver().accept(this);
}
return false;
@@ -1630,6 +1636,20 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
print(')');
return false;
}
@Override
public boolean visit(SQLKeep x) {
if (x.getDenseRank() == SQLKeep.DenseRank.FIRST) {
print0(ucase ? "KEEP (DENSE_RANK FIRST " : "keep (dense_rank first ");
} else {
print0(ucase ? "KEEP (DENSE_RANK LAST " : "keep (dense_rank last ");
}
x.getOrderBy().accept(this);
print(')');
return false;
}
@Override
public boolean visit(SQLColumnPrimaryKey x) {
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.visitor;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLOver;
@@ -354,6 +355,10 @@ public interface SQLASTVisitor {
void endVisit(SQLOver x);
boolean visit(SQLOver x);
void endVisit(SQLKeep x);
boolean visit(SQLKeep x);
void endVisit(SQLColumnPrimaryKey x);
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLKeep;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLOver;
@@ -652,6 +653,15 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
public boolean visit(SQLOver x) {
return true;
}
@Override
public void endVisit(SQLKeep x) {
}
@Override
public boolean visit(SQLKeep x) {
return true;
}
@Override
public void endVisit(SQLColumnPrimaryKey x) {