improved sql parser.

This commit is contained in:
wenshao
2017-06-29 15:19:57 +08:00
parent 2f6e406e33
commit bdbc39ec3c
39 changed files with 963 additions and 185 deletions
@@ -23,6 +23,8 @@ public class SQLSubPartition extends SQLObjectImpl {
protected SQLPartitionValue values;
private SQLName tableSpace;
public SQLName getName() {
return name;
}
@@ -45,10 +47,22 @@ public class SQLSubPartition extends SQLObjectImpl {
this.values = values;
}
public SQLName getTableSpace() {
return tableSpace;
}
public void setTableSpace(SQLName tableSpace) {
if (tableSpace != null) {
tableSpace.setParent(this);
}
this.tableSpace = tableSpace;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, tableSpace);
acceptChild(visitor, values);
}
visitor.endVisit(this);
@@ -22,9 +22,9 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
private String name;
protected String name;
private transient String lowerName;
private transient String lowerName;
private transient Boolean parameter;
public SQLIdentifierExpr(){
@@ -132,4 +132,8 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
public SQLIdentifierExpr clone() {
return new SQLIdentifierExpr(this.name);
}
public String normalizedName() {
return SQLUtils.normalize(name);
}
}
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.SQLName;
@@ -138,4 +139,18 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
return false;
}
public String normalizedName() {
String ownerName;
if (owner instanceof SQLIdentifierExpr) {
ownerName = ((SQLIdentifierExpr) owner).normalizedName();
} else if (owner instanceof SQLPropertyExpr) {
ownerName = ((SQLPropertyExpr) owner).normalizedName();
} else {
ownerName = owner.toString();
}
return ownerName + '.' + SQLUtils.normalize(name);
}
}
@@ -944,6 +944,7 @@ public class MySqlExprParser extends SQLExprParser {
lexer.nextToken();
SQLExpr seperator = this.primary();
seperator.setParent(aggregateExpr);
aggregateExpr.putAttribute("SEPARATOR", seperator);
}
@@ -18,17 +18,22 @@ 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.SQLPartition;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import java.util.ArrayList;
import java.util.List;
public class OracleCreateIndexStatement extends SQLCreateIndexStatement implements OracleDDLStatement, OracleSegmentAttributes {
private boolean online = false;
private boolean indexOnlyTopLevel = false;
private boolean cluster = false;
private boolean noParallel;
@@ -47,6 +52,7 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
private Integer pctthreshold;
private Boolean logging;
private Boolean sort;
protected SQLName tablespace;
protected SQLObject storage;
@@ -83,6 +89,17 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
this.indexOnlyTopLevel = indexOnlyTopLevel;
}
public Boolean getSort() {
return sort;
}
public void setSort(Boolean sort) {
this.sort = sort;
}
private List<SQLPartition> localPartitions = new ArrayList<SQLPartition>();
private List<SQLPartition> globalPartitions = new ArrayList<SQLPartition>();
protected void accept0(SQLASTVisitor visitor) {
accept0((OracleASTVisitor) visitor);
}
@@ -124,6 +141,14 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
this.online = online;
}
public boolean isCluster() {
return cluster;
}
public void setCluster(boolean cluster) {
this.cluster = cluster;
}
//////////////
public SQLName getTablespace() {
@@ -233,4 +258,11 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
this.compressForOltp = compressForOltp;
}
public List<SQLPartition> getLocalPartitions() {
return localPartitions;
}
public List<SQLPartition> getGlobalPartitions() {
return globalPartitions;
}
}
@@ -1471,6 +1471,11 @@ public class OracleExprParser extends SQLExprParser {
subPartition.setValues(values);
}
if (lexer.token() == Token.TABLESPACE) {
lexer.nextToken();
subPartition.setTableSpace(this.name());
}
return subPartition;
}
@@ -1956,20 +1956,33 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.ON);
if (identifierEquals("CLUSTER")) {
lexer.nextToken();
stmt.setCluster(true);
}
stmt.setTable(this.exprParser.name());
accept(Token.LPAREN);
if (lexer.token() == Token.IDENTIFIER) {
String alias = lexer.stringVal();
stmt.getTable().setAlias(alias);
lexer.nextToken();
}
for (;;) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (; ; ) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
break;
accept(Token.RPAREN);
}
accept(Token.RPAREN);
for (;;) {
this.getExprParser().parseSegmentAttributes(stmt);
@@ -2005,6 +2018,32 @@ public class OracleStatementParser extends SQLStatementParser {
acceptIdentifier("TOPLEVEL");
stmt.setIndexOnlyTopLevel(true);
continue;
} else if (identifierEquals("SORT")) {
lexer.nextToken();
stmt.setSort(Boolean.TRUE);
continue;
} else if (identifierEquals("NOSORT")) {
lexer.nextToken();
stmt.setSort(Boolean.FALSE);
continue;
} else if (identifierEquals("LOCAL")) {
lexer.nextToken();
accept(Token.LPAREN);
for (;;) {
SQLPartition partition = this.getExprParser().parsePartition();
partition.setParent(stmt);
stmt.getLocalPartitions().add(partition);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else if (lexer.token() == Token.RPAREN) {
lexer.nextToken();
break;
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
break;
} else {
break;
}
@@ -1748,10 +1748,19 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
x.getName().accept(this);
print0(ucase ? " ON " : " on ");
if (x.isCluster()) {
print0(ucase ? "CLUSTER " : "cluster ");
}
x.getTable().accept(this);
print('(');
printAndAccept(x.getItems(), ", ");
print(')');
List<SQLSelectOrderByItem> items = x.getItems();
if (items.size() > 0) {
print('(');
printAndAccept(items, ", ");
print(')');
}
if (x.isIndexOnlyTopLevel()) {
println();
@@ -1780,8 +1789,28 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
x.getParallel().accept(this);
}
Boolean sort = x.getSort();
if (sort != null) {
if (sort.booleanValue()) {
print0(ucase ? " SORT" : " sort");
} else {
print0(ucase ? " NOSORT" : " nosort");
}
}
this.printOracleSegmentAttributes(x);
if (x.getLocalPartitions().size() > 0) {
println();
print0(ucase ? "LOCAL (" : "local (");
incrementIndent();
println();
printlnAndAccept(x.getLocalPartitions(), ",");
decrementIndent();
println();
print(')');
}
return false;
}
@@ -128,7 +128,7 @@ public class ParameterizedOutputVisitorUtils {
if (parent instanceof SQLDataType //
|| parent instanceof SQLColumnDefinition //
|| parent instanceof SQLServerTop //
//|| parent instanceof SQLAssignItem //
|| parent instanceof SQLAggregateExpr //
|| parent instanceof SQLSelectOrderByItem //
) {
return false;
@@ -1484,7 +1484,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
if (tableMapping != null && expr instanceof SQLName) {
String tableName = expr.toString();
String tableName;
if (expr instanceof SQLIdentifierExpr) {
tableName = ((SQLIdentifierExpr) expr).normalizedName();
} else if (expr instanceof SQLPropertyExpr) {
tableName = ((SQLPropertyExpr) expr).normalizedName();
} else {
tableName = expr.toString();
}
String destTableName = tableMapping.get(tableName);
if (destTableName == null) {
@@ -3841,8 +3848,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
if (x.getSubPartitions().size() > 0) {
println();
print('(');
print(" (");
incrementIndent();
for (int i = 0; i < x.getSubPartitions().size(); ++i) {
if (i != 0) {
@@ -3883,8 +3889,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
printPartitionsCountAndSubPartitions(x);
println();
print('(');
print(" (");
incrementIndent();
for (int i = 0, size = x.getPartitions().size(); i < size; ++i) {
if (i != 0) {
@@ -4052,6 +4057,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
x.getValues().accept(this);
}
SQLName tableSpace = x.getTableSpace();
if (tableSpace != null) {
print0(ucase ? " TABLESPACE " : " tablespace ");
tableSpace.accept(this);
}
return false;
}
@@ -4414,6 +4425,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
} else if (x.getCompress() == Boolean.TRUE) {
println();
print0(ucase ? "COMPRESS" : "compress");
if (x.getCompressLevel() != null) {
print(' ');
print(x.getCompressLevel());
}
}
if (x.getLogging() == Boolean.TRUE) {