mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved odps sql parser, support distribute by
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user