improved oracle sql parser.

This commit is contained in:
wenshao
2017-05-22 00:13:09 +08:00
parent b5b5d66015
commit c3f84859da
38 changed files with 1338 additions and 304 deletions
@@ -54,4 +54,8 @@ public interface OracleSegmentAttributes extends SQLObject {
SQLObject getStorage();
void setStorage(SQLObject storage);
boolean isCompressForOltp();
void setCompressForOltp(boolean compressForOltp);
}
@@ -32,6 +32,7 @@ public abstract class OracleSegmentAttributesImpl extends SQLObjectImpl implemen
private Integer freeLists;
private Boolean compress;
private Integer compressLevel;
private boolean compressForOltp;
private Integer pctthreshold;
private Boolean logging;
@@ -137,4 +138,12 @@ public abstract class OracleSegmentAttributesImpl extends SQLObjectImpl implemen
public void setStorage(SQLObject storage) {
this.storage = storage;
}
public boolean isCompressForOltp() {
return compressForOltp;
}
public void setCompressForOltp(boolean compressForOltp) {
this.compressForOltp = compressForOltp;
}
}
@@ -20,17 +20,19 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributesImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleLobStorageClause extends OracleSQLObjectImpl {
public class OracleLobStorageClause extends OracleSegmentAttributesImpl implements OracleSQLObject {
private final List<SQLName> items = new ArrayList<SQLName>();
private boolean secureFile = false;
private boolean basicFile = false;
private SQLName tableSpace;
private Boolean enable;
@@ -47,11 +49,15 @@ public class OracleLobStorageClause extends OracleSQLObjectImpl {
private SQLExpr pctversion;
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, items);
acceptChild(visitor, tableSpace);
acceptChild(visitor, tablespace);
}
visitor.endVisit(this);
}
@@ -92,14 +98,6 @@ public class OracleLobStorageClause extends OracleSQLObjectImpl {
this.basicFile = basicFile;
}
public SQLName getTableSpace() {
return tableSpace;
}
public void setTableSpace(SQLName tableSpace) {
this.tableSpace = tableSpace;
}
public Boolean getCache() {
return cache;
}
@@ -59,6 +59,7 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
private Boolean logging;
private Boolean compress;
private Integer compressLevel;
private boolean compressForOltp;
private boolean onCommit;
private boolean preserveRows;
@@ -68,14 +69,15 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
private DeferredSegmentCreation deferredSegmentCreation;
private boolean forOLTP;
private Boolean enableRowMovement;
private List<SQLName> clusterColumns = new ArrayList<SQLName>();
private SQLName cluster;
private Organization organization;
private SQLName of;
private OIDIndex oidIndex;
public OracleCreateTableStatement() {
super (JdbcConstants.ORACLE);
@@ -240,12 +242,34 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.storage = (OracleStorageClause) storage;
}
public boolean isForOLTP() {
return forOLTP;
public SQLName getOf() {
return of;
}
public void setForOLTP(boolean forOLTP) {
this.forOLTP = forOLTP;
public void setOf(SQLName of) {
if (of != null) {
of.setParent(this);
}
this.of = of;
}
public OIDIndex getOidIndex() {
return oidIndex;
}
public void setOidIndex(OIDIndex oidIndex) {
if (oidIndex != null) {
oidIndex.setParent(this);
}
this.oidIndex = oidIndex;
}
public boolean isCompressForOltp() {
return compressForOltp;
}
public void setCompressForOltp(boolean compressForOltp) {
this.compressForOltp = compressForOltp;
}
public Boolean getEnableRowMovement() {
@@ -405,4 +429,33 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.terminatedBy = terminatedBy;
}
}
public static class OIDIndex extends OracleSegmentAttributesImpl implements OracleSQLObject{
private SQLName name;
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, tablespace);
acceptChild(visitor, storage);
}
visitor.endVisit(this);
}
protected void accept0(SQLASTVisitor visitor) {
accept0((OracleASTVisitor) visitor);
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
this.name = name;
}
}
}
@@ -18,32 +18,24 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLPartition;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributesImpl;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleStorageClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;
public class OracleUsingIndexClause extends OracleSQLObjectImpl {
public class OracleUsingIndexClause extends OracleSegmentAttributesImpl implements OracleSQLObject {
private SQLName index;
private SQLName tablespace;
private SQLExpr ptcfree;
private SQLExpr pctused;
private SQLExpr initrans;
private SQLExpr maxtrans;
private Boolean enable = null;
private boolean computeStatistics = false;
private OracleStorageClause storage;
private Integer compress = null;
private boolean nocompress = false;
private Boolean logging = null;
private boolean reverse;
private List<SQLPartition> localPartitionIndex = new ArrayList<SQLPartition>();
@@ -51,6 +43,10 @@ public class OracleUsingIndexClause extends OracleSQLObjectImpl {
}
protected void accept0(SQLASTVisitor visitor) {
accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -61,14 +57,6 @@ public class OracleUsingIndexClause extends OracleSQLObjectImpl {
visitor.endVisit(this);
}
public OracleStorageClause getStorage() {
return storage;
}
public void setStorage(OracleStorageClause storage) {
this.storage = storage;
}
public Boolean getEnable() {
return enable;
}
@@ -93,68 +81,12 @@ public class OracleUsingIndexClause extends OracleSQLObjectImpl {
this.index = index;
}
public SQLName getTablespace() {
return tablespace;
public boolean isReverse() {
return reverse;
}
public void setTablespace(SQLName tablespace) {
this.tablespace = tablespace;
}
public SQLExpr getPtcfree() {
return ptcfree;
}
public void setPtcfree(SQLExpr ptcfree) {
this.ptcfree = ptcfree;
}
public SQLExpr getPctused() {
return pctused;
}
public void setPctused(SQLExpr pctused) {
this.pctused = pctused;
}
public SQLExpr getInitrans() {
return initrans;
}
public void setInitrans(SQLExpr initrans) {
this.initrans = initrans;
}
public SQLExpr getMaxtrans() {
return maxtrans;
}
public void setMaxtrans(SQLExpr maxtrans) {
this.maxtrans = maxtrans;
}
public Integer getCompress() {
return compress;
}
public void setCompress(Integer compress) {
this.compress = compress;
}
public boolean isNocompress() {
return nocompress;
}
public void setNocompress(boolean nocompress) {
this.nocompress = nocompress;
}
public Boolean getLogging() {
return logging;
}
public void setLogging(Boolean logging) {
this.logging = logging;
public void setReverse(boolean reverse) {
this.reverse = reverse;
}
public List<SQLPartition> getLocalPartitionIndex() {
@@ -56,6 +56,26 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
public OracleCreateTableStatement parseCrateTable(boolean acceptCreate) {
OracleCreateTableStatement stmt = (OracleCreateTableStatement) super.parseCrateTable(acceptCreate);
if (lexer.token() == Token.OF) {
lexer.nextToken();
stmt.setOf(this.exprParser.name());
if (identifierEquals("OIDINDEX")) {
lexer.nextToken();
OracleCreateTableStatement.OIDIndex oidIndex = new OracleCreateTableStatement.OIDIndex();
if (lexer.token() != Token.LPAREN) {
oidIndex.setName(this.exprParser.name());
}
accept(Token.LPAREN);
this.getExprParser().parseSegmentAttributes(oidIndex);
accept(Token.RPAREN);
stmt.setOidIndex(oidIndex);
}
}
for (;;) {
this.getExprParser().parseSegmentAttributes(stmt);
@@ -101,31 +121,6 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
}
//stmt.setEnable(Boolean.FALSE);
continue;
} else if (lexer.token() == Token.NOCOMPRESS || identifierEquals("NOCOMPRESS")) {
lexer.nextToken();
stmt.setCompress(Boolean.FALSE);
continue;
} else if (identifierEquals("COMPRESS")) {
lexer.nextToken();
stmt.setCompress(Boolean.TRUE);
if (lexer.token() == Token.LITERAL_INT) {
int compressLevel = ((SQLNumericLiteralExpr)this.exprParser.primary()).getNumber().intValue();
stmt.setCompressLevel(compressLevel);
}
continue;
} else if (lexer.token() == Token.FOR) {
lexer.nextToken();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
throw new ParserException("TODO : " + lexer.info());
} else if (identifierEquals("OLTP")) {
lexer.nextToken();
stmt.setForOLTP(true);
} else {
throw new ParserException("TODO : " + lexer.info());
}
continue;
} else if (lexer.token() == Token.ON) {
lexer.nextToken();
accept(Token.COMMIT);
@@ -151,10 +146,10 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
this.exprParser.names(stmt.getClusterColumns(), cluster);
accept(Token.RPAREN);
continue;
} else if (lexer.token() == Token.STORAGE) {
OracleStorageClause storage = ((OracleExprParser) this.exprParser).parseStorage();
stmt.setStorage(storage);
continue;
// } else if (lexer.token() == Token.STORAGE) {
// OracleStorageClause storage = ((OracleExprParser) this.exprParser).parseStorage();
// stmt.setStorage(storage);
// continue;
} else if (lexer.token() == Token.LOB) {
OracleLobStorageClause lobStorage = ((OracleExprParser) this.exprParser).parseLobStorage();
stmt.setLobStorage(lobStorage);
@@ -1030,23 +1030,9 @@ public class OracleExprParser extends SQLExprParser {
OracleUsingIndexClause using = new OracleUsingIndexClause();
for (;;) {
if (lexer.token() == Token.TABLESPACE) {
lexer.nextToken();
using.setTablespace(this.name());
continue;
} else if (lexer.token() == Token.PCTFREE) {
lexer.nextToken();
using.setPtcfree(this.expr());
continue;
} else if (lexer.token() == Token.INITRANS) {
lexer.nextToken();
using.setInitrans(this.expr());
continue;
} else if (lexer.token() == Token.MAXTRANS) {
lexer.nextToken();
using.setMaxtrans(this.expr());
continue;
} else if (lexer.token() == Token.COMPUTE) {
this.parseSegmentAttributes(using);
if (lexer.token() == Token.COMPUTE) {
lexer.nextToken();
acceptIdentifier("STATISTICS");
using.setComputeStatistics(true);
@@ -1055,14 +1041,14 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
using.setEnable(true);
continue;
} else if (identifierEquals("REVERSE")) {
lexer.nextToken();
using.setReverse(true);
continue;
} else if (lexer.token() == Token.DISABLE) {
lexer.nextToken();
using.setEnable(false);
continue;
} else if (lexer.token() == Token.STORAGE) {
OracleStorageClause storage = parseStorage();
using.setStorage(storage);
continue;
} else if (identifierEquals("LOCAL")) {
lexer.nextToken();
accept(Token.LPAREN);
@@ -1084,23 +1070,9 @@ public class OracleExprParser extends SQLExprParser {
}
accept(Token.RPAREN);
continue;
} else if (identifierEquals("NOLOGGING")) {
lexer.nextToken();
using.setLogging(Boolean.FALSE);
continue;
} else if (identifierEquals("COMPRESS")) {
throw new ParserException("TODO " + lexer.token());
} else if (lexer.token() == Token.IDENTIFIER) {
using.setTablespace(this.name());
break;
} else if (lexer.token() == Token.NOCOMPRESS || identifierEquals("NOCOMPRESS")) {
lexer.nextToken();
using.setNocompress(true);
continue;
} else if (lexer.token() == Token.LOGGING || identifierEquals("LOGGING")) {
lexer.nextToken();
using.setLogging(Boolean.TRUE);
continue;
} else {
break;
}
@@ -1175,11 +1147,7 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
for (;;) {
if (lexer.token() == Token.TABLESPACE) {
lexer.nextToken();
clause.setTableSpace(this.name());
continue;
}
this.parseSegmentAttributes(clause);
if (lexer.token() == Token.ENABLE) {
lexer.nextToken();
@@ -1212,13 +1180,7 @@ public class OracleExprParser extends SQLExprParser {
}
continue;
}
if (lexer.token() == Token.NOCOMPRESS) {
lexer.nextToken();
clause.setCompress(false);
continue;
}
if (lexer.token() == Token.KEEP_DUPLICATES) {
lexer.nextToken();
clause.setKeepDuplicate(true);
@@ -1528,6 +1490,14 @@ public class OracleExprParser extends SQLExprParser {
} else if (identifierEquals("BASIC")) {
lexer.nextToken();
// TODO COMPRESS BASIC
} else if (lexer.token() == Token.FOR) {
lexer.nextToken();
if (identifierEquals("OLTP")) {
lexer.nextToken();
attributes.setCompressForOltp(true);
} else {
throw new ParserException("TODO : " + lexer.info());
}
}
continue;
} else if (identifierEquals("NOCOMPRESS")) {
@@ -456,4 +456,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x);
void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x);
boolean visit(OracleCreateTableStatement.OIDIndex x);
void endVisit(OracleCreateTableStatement.OIDIndex x);
}
@@ -1101,5 +1101,12 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
return true;
}
public void endVisit(OracleCreateTableStatement.OIDIndex x) {
}
}
@@ -2093,6 +2093,17 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleCreateTableStatement x) {
this.visit((SQLCreateTableStatement) x);
if (x.getOf() != null) {
println();
print0(ucase ? "OF " : "of ");
x.getOf().accept(this);
}
if (x.getOidIndex() != null) {
println();
x.getOidIndex().accept(this);
}
if (x.getOrganization() != null) {
println();
incrementIndent();
@@ -2760,66 +2771,31 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
if (x.getIndex() != null) {
print(' ');
x.getIndex().accept(this);
} else {
if (x.getPtcfree() != null) {
println();
print0(ucase ? "PCTFREE " : "pctfree ");
x.getPtcfree().accept(this);
}
}
if (x.getInitrans() != null) {
println();
print0(ucase ? "INITRANS " : "initrans ");
x.getInitrans().accept(this);
}
printOracleSegmentAttributes(x);
if (x.getMaxtrans() != null) {
println();
print0(ucase ? "MAXTRANS " : "maxtrans ");
x.getMaxtrans().accept(this);
}
if (x.isComputeStatistics()) {
println();
print0(ucase ? "COMPUTE STATISTICS" : "compute statistics");
}
if (x.isComputeStatistics()) {
if (x.getEnable() != null) {
if (x.getEnable().booleanValue()) {
println();
print0(ucase ? "COMPUTE STATISTICS" : "compute statistics");
}
if (x.getTablespace() != null) {
print0(ucase ? "ENABLE" : "enable");
} else {
println();
print0(ucase ? "TABLESPACE " : "tablespace ");
x.getTablespace().accept(this);
}
if (x.getEnable() != null) {
if (x.getEnable().booleanValue()) {
println();
print0(ucase ? "ENABLE" : "enable");
} else {
println();
print0(ucase ? "DISABLE" : "disable");
}
}
if (x.getStorage() != null) {
println();
x.getStorage().accept(this);
}
if (x.isNocompress()) {
println();
print0(ucase ? "NOCOMPRESS" : "nocompress");
}
if (x.getLogging() != null) {
println();
if (x.getLogging().booleanValue()) {
print0(ucase ? "LOGGING" : "logging");
} else {
print0(ucase ? "NOLOGGING" : "nologging");
}
print0(ucase ? "DISABLE" : "disable");
}
}
if (x.isReverse()) {
println();
print0(ucase ? "REVERSE" : "reverse");
}
return false;
}
@@ -2844,11 +2820,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
print0(" (");
incrementIndent();
if (x.getTableSpace() != null) {
println();
print0(ucase ? "TABLESPACE " : "tablespace ");
x.getTableSpace().accept(this);
}
printOracleSegmentAttributes(x);
if (x.getEnable() != null) {
println();
@@ -2859,11 +2831,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
}
if (x.getStorageClause() != null) {
println();
x.getStorageClause().accept(this);
}
if (x.getChunk() != null) {
println();
print0(ucase ? "CHUNK " : "chunk ");
@@ -2879,24 +2846,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
}
if (x.getLogging() != null) {
println();
if (x.getLogging().booleanValue()) {
print0(ucase ? "LOGGING" : "logging");
} else {
print0(ucase ? "NOLOGGING" : "nologging");
}
}
if (x.getCompress() != null) {
println();
if (x.getCompress().booleanValue()) {
print0(ucase ? "COMPRESS" : "compress");
} else {
print0(ucase ? "NOCOMPRESS" : "nocompress");
}
}
if (x.getKeepDuplicate() != null) {
println();
if (x.getKeepDuplicate().booleanValue()) {
@@ -3156,4 +3105,24 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
print0(ucase ? "OIDINDEX" : "oidindex");
if (x.getName() != null) {
print(' ');
x.getName().accept(this);
}
print(" (");
incrementIndent();
printOracleSegmentAttributes(x);
decrementIndent();
println();
print(")");
return false;
}
public void endVisit(OracleCreateTableStatement.OIDIndex x) {
}
}
@@ -1437,4 +1437,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
@Override
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
return false;
}
@Override
public void endVisit(OracleCreateTableStatement.OIDIndex x) {
}
}
@@ -381,6 +381,7 @@ public class SQLExprParser extends SQLParser {
case IDENTITY:
case EXTRACT:
case DESC:
case DO:
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
break;
@@ -1037,6 +1038,7 @@ public class SQLExprParser extends SQLParser {
case OVER:
case ORDER:
case DO:
case JOIN:
identName = lexer.stringVal();
lexer.nextToken();
break;
@@ -2249,7 +2251,7 @@ public class SQLExprParser extends SQLParser {
expr = this.primaryRest(expr);
expr = this.exprRest(expr);
}
} else if (lexer.token() == Token.DO) {
} else if (lexer.token() == Token.DO || lexer.token() == Token.JOIN) {
expr = this.name();
} else {
expr = expr();
@@ -120,6 +120,7 @@ public class SQLParser {
case END:
case DEFERRED:
case OUTER:
case DO:
alias = lexer.stringVal();
lexer.nextToken();
break;