improved sql parser.

This commit is contained in:
wenshao
2017-05-21 19:39:29 +08:00
parent 8b51ecf021
commit b5b5d66015
39 changed files with 3622 additions and 94 deletions
@@ -423,12 +423,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(SQLCharacterDataType x) {
print0(x.getName());
if (!x.getArguments().isEmpty()) {
print('(');
printAndAccept(x.getArguments(), ", ");
print(')');
}
printDataType(x);
if (x.isHasBinary()) {
print0(ucase ? " BINARY " : " binary ");
@@ -15,9 +15,11 @@
*/
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.SQLObject;
import com.alibaba.druid.sql.ast.SQLPartitionBy;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
@@ -299,6 +301,12 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
public static class Organization extends OracleSegmentAttributesImpl implements OracleSegmentAttributes, OracleSQLObject {
public String type;
private SQLName externalType;
private SQLExpr externalDirectory;
private OracleExternalRecordFormat externalDirectoryRecordFormat;
private List<SQLExpr> externalDirectoryLocation = new ArrayList<SQLExpr>();
private SQLExpr externalRejectLimit;
protected void accept0(SQLASTVisitor visitor) {
this.accept0((OracleASTVisitor) visitor);
}
@@ -319,5 +327,82 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.type = type;
}
public SQLName getExternalType() {
return externalType;
}
public void setExternalType(SQLName externalType) {
this.externalType = externalType;
}
public SQLExpr getExternalDirectory() {
return externalDirectory;
}
public void setExternalDirectory(SQLExpr externalDirectory) {
this.externalDirectory = externalDirectory;
}
public OracleExternalRecordFormat getExternalDirectoryRecordFormat() {
return externalDirectoryRecordFormat;
}
public void setExternalDirectoryRecordFormat(OracleExternalRecordFormat recordFormat) {
if (recordFormat != null) {
recordFormat.setParent(this);
}
this.externalDirectoryRecordFormat = recordFormat;
}
public SQLExpr getExternalRejectLimit() {
return externalRejectLimit;
}
public void setExternalRejectLimit(SQLExpr externalRejectLimit) {
if (externalRejectLimit != null) {
externalRejectLimit.setParent(this);
}
this.externalRejectLimit = externalRejectLimit;
}
public List<SQLExpr> getExternalDirectoryLocation() {
return externalDirectoryLocation;
}
}
public static class OracleExternalRecordFormat extends OracleSQLObjectImpl {
private SQLExpr delimitedBy;
private SQLExpr terminatedBy;
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, delimitedBy);
acceptChild(visitor, terminatedBy);
}
visitor.endVisit(this);
}
public SQLExpr getDelimitedBy() {
return delimitedBy;
}
public void setDelimitedBy(SQLExpr delimitedBy) {
if (delimitedBy != null) {
delimitedBy.setParent(this);
}
this.delimitedBy = delimitedBy;
}
public SQLExpr getTerminatedBy() {
return terminatedBy;
}
public void setTerminatedBy(SQLExpr terminatedBy) {
if (terminatedBy != null) {
terminatedBy.setParent(this);
}
this.terminatedBy = terminatedBy;
}
}
}
@@ -26,6 +26,7 @@ import com.alibaba.druid.sql.ast.SQLSubPartition;
import com.alibaba.druid.sql.ast.SQLSubPartitionBy;
import com.alibaba.druid.sql.ast.SQLSubPartitionByHash;
import com.alibaba.druid.sql.ast.SQLSubPartitionByList;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
@@ -247,7 +248,80 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
organization.setType("EXTERNAL");
accept(Token.LPAREN);
throw new ParserException("TODO " + lexer.info());
if (identifierEquals("TYPE")) {
lexer.nextToken();
organization.setExternalType(this.exprParser.name());
}
accept(Token.DEFAULT);
acceptIdentifier("DIRECTORY");
organization.setExternalDirectory(this.exprParser.expr());
if (identifierEquals("ACCESS")) {
lexer.nextToken();
acceptIdentifier("PARAMETERS");
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
OracleCreateTableStatement.OracleExternalRecordFormat recordFormat = new OracleCreateTableStatement.OracleExternalRecordFormat();
if (identifierEquals("RECORDS")) {
lexer.nextToken();
if (identifierEquals("DELIMITED")) {
lexer.nextToken();
accept(Token.BY);
if (identifierEquals("NEWLINE")) {
lexer.nextToken();
recordFormat.setDelimitedBy(new SQLIdentifierExpr("NEWLINE"));
} else {
throw new ParserException("TODO " + lexer.info());
}
} else {
throw new ParserException("TODO " + lexer.info());
}
}
if (identifierEquals("FIELDS")) {
lexer.nextToken();
if (identifierEquals("TERMINATED")) {
lexer.nextToken();
accept(Token.BY);
recordFormat.setTerminatedBy(this.exprParser.primary());
} else {
throw new ParserException("TODO " + lexer.info());
}
}
organization.setExternalDirectoryRecordFormat(recordFormat);
accept(Token.RPAREN);
} else if (lexer.token() == Token.USING) {
lexer.nextToken();
acceptIdentifier("CLOB");
throw new ParserException("TODO " + lexer.info());
}
}
acceptIdentifier("LOCATION");
accept(Token.LPAREN);
this.exprParser.exprList(organization.getExternalDirectoryLocation(), organization);
accept(Token.RPAREN);
accept(Token.RPAREN);
if (lexer.token() == Token.REJECT) {
lexer.nextToken();
accept(Token.LIMIT);
organization.setExternalRejectLimit(this.exprParser.primary());
}
//
} else {
throw new ParserException("TODO " + lexer.info());
}
@@ -452,4 +452,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleCreateTableStatement.Organization x);
void endVisit(OracleCreateTableStatement.Organization x);
boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x);
void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x);
}
@@ -1094,4 +1094,12 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
public void endVisit(OracleCreateTableStatement.Organization x) {
}
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
return true;
}
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
}
@@ -2175,63 +2175,58 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleStorageClause x) {
print0(ucase ? "STORAGE (" : "storage (");
boolean first = true;
incrementIndent();
if (x.getInitial() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "INITIAL " : "initial ");
x.getInitial().accept(this);
first = false;
}
if (x.getMaxSize() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "MAXSIZE " : "maxsize ");
x.getMaxSize().accept(this);
first = false;
}
if (x.getFreeLists() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "FREELISTS " : "freelists ");
x.getFreeLists().accept(this);
first = false;
}
if (x.getFreeListGroups() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "FREELIST GROUPS " : "freelist groups ");
x.getFreeListGroups().accept(this);
first = false;
}
if (x.getBufferPool() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "BUFFER_POOL " : "buffer_pool ");
x.getBufferPool().accept(this);
first = false;
}
if (x.getObjno() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "OBJNO " : "objno ");
x.getObjno().accept(this);
first = false;
}
if (x.getFlashCache() != null) {
println();
print0(ucase ? "FLASH_CACHE " : "flash_cache ");
print0(ucase ? x.getFlashCache().name() : x.getFlashCache().name().toLowerCase());
}
if (x.getCellFlashCache() != null) {
println();
print0(ucase ? "CELL_FLASH_CACHE " : "cell_flash_cache ");
print0(ucase ? x.getCellFlashCache().name() : x.getCellFlashCache().name().toLowerCase());
}
decrementIndent();
println();
print(')');
return false;
}
@@ -2837,108 +2832,87 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleLobStorageClause x) {
print0(ucase ? "LOB (" : "lob (");
printAndAccept(x.getItems(), ",");
print0(ucase ? ") STORE AS " : ") store as ");
print0(ucase ? ") STORE AS" : ") store as");
if (x.isSecureFile()) {
print0(ucase ? "SECUREFILE " : "securefile ");
print0(ucase ? " SECUREFILE" : " securefile");
}
if (x.isBasicFile()) {
print0(ucase ? "BASICFILE " : "basicfile ");
print0(ucase ? " BASICFILE" : " basicfile");
}
boolean first = true;
print('(');
print0(" (");
incrementIndent();
if (x.getTableSpace() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "TABLESPACE " : "tablespace ");
x.getTableSpace().accept(this);
first = false;
}
if (x.getEnable() != null) {
if (!first) {
print(' ');
}
println();
if (x.getEnable().booleanValue()) {
print0(ucase ? "ENABLE STORAGE IN ROW" : "enable storage in row");
} else {
print0(ucase ? "DISABLE STORAGE IN ROW" : "disable storage in row");
}
first = false;
}
if (x.getStorageClause() != null) {
if (!first) {
print(' ');
}
println();
x.getStorageClause().accept(this);
first = false;
}
if (x.getChunk() != null) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "CHUNK " : "chunk ");
x.getChunk().accept(this);
first = false;
}
if (x.getCache() != null) {
if (!first) {
print(' ');
}
println();
if (x.getCache().booleanValue()) {
print0(ucase ? "CACHE" : "cache");
} else {
print0(ucase ? "NOCACHE" : "nocache");
}
}
if (x.getLogging() != null) {
if (x.getLogging().booleanValue()) {
print0(ucase ? " LOGGING" : " logging");
} else {
print0(ucase ? " NOLOGGING" : " nologging");
}
if (x.getLogging() != null) {
println();
if (x.getLogging().booleanValue()) {
print0(ucase ? "LOGGING" : "logging");
} else {
print0(ucase ? "NOLOGGING" : "nologging");
}
first = false;
}
if (x.getCompress() != null) {
if (!first) {
print(' ');
}
println();
if (x.getCompress().booleanValue()) {
print0(ucase ? "COMPRESS" : "compress");
} else {
print0(ucase ? "NOCOMPRESS" : "nocompress");
}
first = false;
}
if (x.getKeepDuplicate() != null) {
if (!first) {
print(' ');
}
println();
if (x.getKeepDuplicate().booleanValue()) {
print0(ucase ? "KEEP_DUPLICATES" : "keep_duplicates");
} else {
print0(ucase ? "DEDUPLICATE" : "deduplicate");
}
first = false;
}
if (x.isRetention()) {
if (!first) {
print(' ');
}
println();
print0(ucase ? "RETENTION" : "retention");
first = false;
}
decrementIndent();
println();
print(')');
return false;
}
@@ -3097,11 +3071,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
public boolean visit(OracleCreateTableStatement.Organization x) {
String type = x.getType();
print0(ucase ? "ORGANIZATION " : "organization ");
print0(ucase ? x.getType() : x.getType().toLowerCase());
print0(ucase ? type : type.toLowerCase());
printOracleSegmentAttributes(x);
@@ -3110,10 +3085,75 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
print0(ucase ? "PCTTHRESHOLD " : "pctthreshold ");
print(x.getPctfree());
}
if ("EXTERNAL".equalsIgnoreCase(type)) {
print0(" (");
incrementIndent();
if (x.getExternalType() != null) {
println();
print0(ucase ? "TYPE " : "type ");
x.getExternalType().accept(this);
}
if (x.getExternalDirectory() != null) {
println();
print0(ucase ? "DEFAULT DIRECTORY " : "default directory ");
x.getExternalDirectory().accept(this);
}
if (x.getExternalDirectoryRecordFormat() != null) {
println();
incrementIndent();
print0(ucase ? "ACCESS PARAMETERS (" : "access parameters (");
x.getExternalDirectoryRecordFormat().accept(this);
decrementIndent();
println();
print(')');
}
if (x.getExternalDirectoryLocation().size() > 0) {
println();
print0(ucase ? "LOCATION (" : " location(");
printAndAccept(x.getExternalDirectoryLocation(), ", ");
print(')');
}
decrementIndent();
println();
print(')');
if (x.getExternalRejectLimit() != null) {
println();
print0(ucase ? "REJECT LIMIT " : "reject limit ");
x.getExternalRejectLimit().accept(this);
}
}
return false;
}
public void endVisit(OracleCreateTableStatement.Organization x) {
}
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
if (x.getDelimitedBy() != null) {
println();
print0(ucase ? "RECORDS DELIMITED BY " : "records delimited by ");
x.getDelimitedBy().accept(this);
}
if (x.getTerminatedBy() != null) {
println();
print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by ");
x.getTerminatedBy().accept(this);
}
return false;
}
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
}
@@ -1427,4 +1427,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(OracleCreateTableStatement.Organization x) {
}
@Override
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
return false;
}
@Override
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
}
}
@@ -582,14 +582,18 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public boolean visit(SQLDataType x) {
printDataType(x);
return false;
}
protected void printDataType(SQLDataType x) {
print0(x.getName());
if (x.getArguments().size() > 0) {
print('(');
printAndAccept(x.getArguments(), ", ");
print(')');
}
return false;
}
public boolean visit(SQLCharacterDataType x) {
@@ -4155,6 +4159,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print(x.getPctfree());
}
if (x.getPctused() != null) {
println();
print0(ucase ? "PCTUSED " : "pctused ");
print(x.getPctused());
}
if (x.getInitrans() != null) {
println();
print0(ucase ? "INITRANS " : "initrans ");