mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -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 ");
|
||||
|
||||
+85
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+75
-1
@@ -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);
|
||||
}
|
||||
|
||||
+8
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+113
-73
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -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 ");
|
||||
|
||||
Reference in New Issue
Block a user