improved odps sql parser, support distribute by

This commit is contained in:
高铁
2015-08-26 19:39:56 +08:00
parent 883b1fbc64
commit e0ad248845
11 changed files with 313 additions and 104 deletions
@@ -29,10 +29,13 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
private SQLOrderBy orderBy;
private SQLExpr limit;
private SQLExpr limit;
protected List<SQLHint> hints;
protected SQLExpr distributeBy;
protected SQLExpr sortBy;
public OdpsSelectQueryBlock(){
}
@@ -45,6 +48,22 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
this.orderBy = orderBy;
}
public SQLExpr getDistributeBy() {
return distributeBy;
}
public void setDistributeBy(SQLExpr distributeBy) {
this.distributeBy = distributeBy;
}
public SQLExpr getSortBy() {
return sortBy;
}
public void setSortBy(SQLExpr sortBy) {
this.sortBy = sortBy;
}
public SQLExpr getLimit() {
return limit;
}
@@ -75,11 +94,11 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
} else if (!limit.equals(other.limit)) return false;
return true;
}
public List<SQLHint> getHintsDirect() {
return hints;
}
public List<SQLHint> getHints() {
if (hints == null) {
hints = new ArrayList<SQLHint>(2);
@@ -109,6 +128,8 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
acceptChild(visitor, this.where);
acceptChild(visitor, this.groupBy);
acceptChild(visitor, this.orderBy);
acceptChild(visitor, this.distributeBy);
acceptChild(visitor, this.sortBy);
acceptChild(visitor, this.limit);
acceptChild(visitor, this.into);
}
@@ -44,6 +44,7 @@ public class OdpsLexer extends Lexer {
map.put("OVER", Token.OVER);
map.put("LIMIT", Token.LIMIT);
map.put("IF", Token.IF);
map.put("DISTRIBUTE", Token.DISTRIBUTE);
DEFAULT_ODPS_KEYWORDS = new Keywords(map);
}
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.odps.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
@@ -76,6 +77,21 @@ public class OdpsSelectParser extends SQLSelectParser {
parseGroupBy(queryBlock);
queryBlock.setOrderBy(this.exprParser.parseOrderBy());
if (lexer.token() == Token.DISTRIBUTE) {
lexer.nextToken();
accept(Token.BY);
SQLExpr distributeBy = this.expr();
queryBlock.setDistributeBy(distributeBy);
if (identifierEquals("SORT")) {
lexer.nextToken();
accept(Token.BY);
SQLExpr sortBy = this.expr();
queryBlock.setSortBy(sortBy);
}
}
if (lexer.token() == Token.LIMIT) {
lexer.nextToken();
@@ -520,6 +520,17 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
println();
x.getOrderBy().accept(this);
}
if (x.getDistributeBy() != null) {
println();
print("DISTRIBUTE BY ");
x.getDistributeBy().accept(this);
if (x.getSortBy() != null) {
print(" SORT BY ");
x.getSortBy().accept(this);
}
}
if (x.getLimit() != null) {
println();
@@ -223,6 +223,7 @@ public enum Token {
TOP("TOP"),
ARRAY("ARRAY"),
DISTRIBUTE("DISTRIBUTE"),
// hive
@@ -9,27 +9,34 @@ import com.alibaba.druid.stat.TableStat;
import com.aliyun.odps.udf.UDF;
public class ExportColumns extends UDF {
public String evaluate(String sql) {
return evaluate(sql, null);
}
public String evaluate(String sql, String dbType) {
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, dbType);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
}
StringBuffer buf = new StringBuffer();
for (TableStat.Column column : visitor.getColumns()) {
if (buf.length() != 0) {
buf.append(',');
try {
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, dbType);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
}
buf.append(column.toString());
StringBuffer buf = new StringBuffer();
for (TableStat.Column column : visitor.getColumns()) {
if (buf.length() != 0) {
buf.append(',');
}
buf.append(column.toString());
}
return buf.toString();
} catch (Exception ex) {
System.err.println("error sql : " + sql);
ex.printStackTrace();
return null;
}
return buf.toString();
}
}
@@ -10,29 +10,36 @@ import com.alibaba.druid.stat.TableStat;
import com.aliyun.odps.udf.UDF;
public class ExportTables extends UDF {
public String evaluate(String sql) {
return evaluate(sql, null);
}
public String evaluate(String sql, String dbType) {
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, dbType);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
}
StringBuffer buf = new StringBuffer();
for (Map.Entry<TableStat.Name, TableStat> entry : visitor.getTables().entrySet()) {
TableStat.Name name = entry.getKey();
if (buf.length() != 0) {
buf.append(',');
try {
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, dbType);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
}
buf.append(name.toString());
StringBuffer buf = new StringBuffer();
for (Map.Entry<TableStat.Name, TableStat> entry : visitor.getTables().entrySet()) {
TableStat.Name name = entry.getKey();
if (buf.length() != 0) {
buf.append(',');
}
buf.append(name.toString());
}
return buf.toString();
} catch (Exception ex) {
System.err.println("error sql : " + sql);
ex.printStackTrace();
return null;
}
return buf.toString();
}
}