improved sql parser. support create materialized view

This commit is contained in:
wenshao
2017-06-30 11:25:11 +08:00
parent 2c52661fe9
commit 6cfba1a0b9
9 changed files with 667 additions and 2 deletions
@@ -0,0 +1,282 @@
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wenshao on 30/06/2017.
*/
public class SQLCreateMaterializedViewStatement extends SQLStatementImpl implements OracleSegmentAttributes {
private SQLName name;
private List<SQLName> columns = new ArrayList<SQLName>();
private boolean refreshFast;
private boolean refreshComlete;
private boolean refreshForce;
private boolean refreshOnCommit;
private boolean refreshOnDemand;
private boolean buildImmediate;
private boolean buildDeferred;
private SQLSelect query;
// oracle
private Integer pctfree;
private Integer pctused;
private Integer initrans;
private Integer maxtrans;
private Integer pctincrease;
private Integer freeLists;
private Boolean compress;
private Integer compressLevel;
private boolean compressForOltp;
private Integer pctthreshold;
private Boolean logging;
protected SQLName tablespace;
protected SQLObject storage;
private Boolean parallel;
private Integer parallelValue;
private Boolean enableQueryRewrite;
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
this.name = name;
}
public List<SQLName> getColumns() {
return columns;
}
public SQLSelect getQuery() {
return query;
}
public void setQuery(SQLSelect query) {
if (query != null) {
query.setParent(this);
}
this.query = query;
}
public boolean isBuildImmediate() {
return buildImmediate;
}
public void setBuildImmediate(boolean buildImmediate) {
this.buildImmediate = buildImmediate;
}
public boolean isBuildDeferred() {
return buildDeferred;
}
public void setBuildDeferred(boolean buildDeferred) {
this.buildDeferred = buildDeferred;
}
public boolean isRefresh() {
return this.refreshFast || refreshComlete || refreshForce || refreshOnDemand || refreshOnCommit;
}
public boolean isRefreshFast() {
return refreshFast;
}
public void setRefreshFast(boolean refreshFast) {
this.refreshFast = refreshFast;
}
public boolean isRefreshComlete() {
return refreshComlete;
}
public void setRefreshComlete(boolean refreshComlete) {
this.refreshComlete = refreshComlete;
}
public boolean isRefreshForce() {
return refreshForce;
}
public void setRefreshForce(boolean refreshForce) {
this.refreshForce = refreshForce;
}
public boolean isRefreshOnCommit() {
return refreshOnCommit;
}
public void setRefreshOnCommit(boolean refreshOnCommit) {
this.refreshOnCommit = refreshOnCommit;
}
public boolean isRefreshOnDemand() {
return refreshOnDemand;
}
public void setRefreshOnDemand(boolean refreshOnDemand) {
this.refreshOnDemand = refreshOnDemand;
}
public Integer getPctfree() {
return pctfree;
}
public void setPctfree(Integer pctfree) {
this.pctfree = pctfree;
}
public Integer getPctused() {
return pctused;
}
public void setPctused(Integer pctused) {
this.pctused = pctused;
}
public Integer getInitrans() {
return initrans;
}
public void setInitrans(Integer initrans) {
this.initrans = initrans;
}
public Integer getMaxtrans() {
return maxtrans;
}
public void setMaxtrans(Integer maxtrans) {
this.maxtrans = maxtrans;
}
public Integer getPctincrease() {
return pctincrease;
}
public void setPctincrease(Integer pctincrease) {
this.pctincrease = pctincrease;
}
public Integer getFreeLists() {
return freeLists;
}
public void setFreeLists(Integer freeLists) {
this.freeLists = freeLists;
}
public Boolean getCompress() {
return compress;
}
public void setCompress(Boolean compress) {
this.compress = compress;
}
public Integer getCompressLevel() {
return compressLevel;
}
public void setCompressLevel(Integer compressLevel) {
this.compressLevel = compressLevel;
}
public boolean isCompressForOltp() {
return compressForOltp;
}
public void setCompressForOltp(boolean compressForOltp) {
this.compressForOltp = compressForOltp;
}
public Integer getPctthreshold() {
return pctthreshold;
}
public void setPctthreshold(Integer pctthreshold) {
this.pctthreshold = pctthreshold;
}
public Boolean getLogging() {
return logging;
}
public void setLogging(Boolean logging) {
this.logging = logging;
}
public SQLName getTablespace() {
return tablespace;
}
public void setTablespace(SQLName tablespace) {
if (tablespace != null) {
tablespace.setParent(this);
}
this.tablespace = tablespace;
}
public SQLObject getStorage() {
return storage;
}
public void setStorage(SQLObject storage) {
if (storage != null) {
storage.setParent(this);
}
this.storage = storage;
}
public Boolean getParallel() {
return parallel;
}
public void setParallel(Boolean parallel) {
this.parallel = parallel;
}
public Integer getParallelValue() {
return parallelValue;
}
public void setParallelValue(Integer parallelValue) {
this.parallelValue = parallelValue;
}
public Boolean getEnableQueryRewrite() {
return enableQueryRewrite;
}
public void setEnableQueryRewrite(Boolean enableQueryRewrite) {
this.enableQueryRewrite = enableQueryRewrite;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, columns);
acceptChild(visitor, query);
}
visitor.endVisit(this);
}
}
@@ -32,6 +32,7 @@ import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent;
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
@@ -1842,11 +1843,89 @@ public class SQLStatementParser extends SQLParser {
} else if (identifierEquals("BITMAP")) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateIndex(true);
} else if (identifierEquals("MATERIALIZED")) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateMaterializedView();
}
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateMaterializedView() {
accept(Token.CREATE);
acceptIdentifier("MATERIALIZED");
accept(Token.VIEW);
SQLCreateMaterializedViewStatement stmt = new SQLCreateMaterializedViewStatement();
stmt.setName(this.exprParser.name());
for (;;) {
if (exprParser instanceof OracleExprParser) {
((OracleExprParser) exprParser).parseSegmentAttributes(stmt);
}
if (identifierEquals("REFRESH")) {
lexer.nextToken();
for (; ; ) {
if (identifierEquals("FAST")) {
lexer.nextToken();
stmt.setRefreshFast(true);
} else if (identifierEquals("COMPLETE")) {
lexer.nextToken();
stmt.setRefreshComlete(true);
} else if (identifierEquals("FORCE")) {
lexer.nextToken();
stmt.setRefreshForce(true);
} else if (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.token() == Token.COMMIT) {
lexer.nextToken();
stmt.setRefreshOnCommit(true);
} else {
acceptIdentifier("DEMAND");
stmt.setRefreshOnDemand(true);
}
} else {
break;
}
}
} else if (identifierEquals("BUILD")) {
lexer.nextToken();
if (identifierEquals("IMMEDIATE") || lexer.token() == Token.IMMEDIATE) {
lexer.nextToken();
stmt.setBuildImmediate(true);
} else {
acceptIdentifier("DEFERRED");
stmt.setBuildDeferred(true);
}
} else if (identifierEquals("PARALLEL")) {
lexer.nextToken();
stmt.setParallel(true);
if (lexer.token() == Token.LITERAL_INT) {
stmt.setParallelValue(lexer.integerValue().intValue());
lexer.nextToken();
}
} else {
break;
}
}
if (lexer.token() == Token.ENABLE) {
lexer.nextToken();
acceptIdentifier("QUERY");
acceptIdentifier("REWRITE");
stmt.setEnableQueryRewrite(true);
}
accept(Token.AS);
SQLSelect select = this.createSQLSelectParser().select();
stmt.setQuery(select);
return stmt;
}
public SQLStatement parseCreateDbLink() {
throw new ParserException("TODO " + lexer.token());
}
@@ -4584,4 +4584,64 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
return false;
}
public boolean visit(SQLCreateMaterializedViewStatement x) {
print0(ucase ? "CREATE MATERIALIZED VIEW " : "create materialized view ");
x.getName().accept(this);
this.printOracleSegmentAttributes(x);
println();
Boolean parallel = x.getParallel();
if (parallel != null) {
if (parallel) {
print(ucase ? "PARALLEL" : "parallel");
Integer parallelValue = x.getParallelValue();
if (parallelValue != null) {
print(' ');
print(parallelValue);
}
} else {
print(ucase ? "NOPARALLEL" : "noparallel");
}
println();
}
if (x.isBuildImmediate()) {
println(ucase ? "BUILD IMMEDIATE" : "build immediate");
}
if (x.isRefresh()) {
print(ucase ? "REFRESH" : "refresh");
if (x.isRefreshFast()) {
print(ucase ? " FAST" : " fast");
} else if (x.isRefreshComlete()) {
print(ucase ? " COMPLETE" : " complete");
} else if (x.isRefreshForce()) {
print(ucase ? " FORCE" : " force");
}
if (x.isRefreshOnCommit()) {
print(ucase ? " ON COMMIT" : " on commit");
} else if (x.isRefreshOnDemand()) {
print(ucase ? " ON DEMAND" : " on demand");
}
println();
}
Boolean enableQueryRewrite = x.getEnableQueryRewrite();
if (enableQueryRewrite != null) {
if (enableQueryRewrite) {
print(ucase ? "ENABLE QUERY REWRITE" : "enable query rewrite");
} else {
print(ucase ? "DISABLE QUERY REWRITE" : "disable query rewrite");
}
println();
}
println(ucase ? "AS" : "as");
x.getQuery().accept(this);
return false;
}
}
@@ -727,9 +727,12 @@ public interface SQLASTVisitor {
void endVisit(SQLCommitStatement x);
boolean visit(SQLFlashbackExpr x);
void endVisit(SQLFlashbackExpr x);
boolean visit(SQLCreateMaterializedViewStatement x);
void endVisit(SQLCreateMaterializedViewStatement x);
//
}
@@ -1662,4 +1662,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
public void endVisit(SQLFlashbackExpr x) {
}
@Override
public boolean visit(SQLCreateMaterializedViewStatement x) {
return true;
}
@Override
public void endVisit(SQLCreateMaterializedViewStatement x) {
}
}