Merge pull request #901 from wenshao/master

improved odps sql parser support 'read ...'
This commit is contained in:
高铁
2015-07-12 22:50:24 +08:00
7 changed files with 222 additions and 38 deletions
@@ -0,0 +1,61 @@
package com.alibaba.druid.sql.dialect.odps.ast;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
public class OdpsReadStatement extends OdpsStatementImpl {
private SQLExprTableSource table;
private List<SQLAssignItem> partition = new ArrayList<SQLAssignItem>();
private List<SQLName> columns = new ArrayList<SQLName>();
private SQLExpr rowCount;
@Override
protected void accept0(OdpsASTVisitor visitor) {
if (visitor.visit(this)) {
this.acceptChild(visitor, table);
this.acceptChild(visitor, columns);
this.acceptChild(visitor, partition);
this.acceptChild(visitor, rowCount);
}
visitor.endVisit(this);
}
public SQLExprTableSource getTable() {
return table;
}
public void setTable(SQLExprTableSource table) {
if (table != null) {
table.setParent(table);
}
this.table = table;
}
public void setTable(SQLName table) {
this.setTable(new SQLExprTableSource(table));
}
public List<SQLAssignItem> getPartition() {
return partition;
}
public List<SQLName> getColumns() {
return columns;
}
public SQLExpr getRowCount() {
return rowCount;
}
public void setRowCount(SQLExpr rowCount) {
this.rowCount = rowCount;
}
}
@@ -32,6 +32,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt;
@@ -131,6 +132,33 @@ public class OdpsStatementParser extends SQLStatementParser {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
if (identifierEquals("READ")) {
lexer.nextToken();
OdpsReadStatement stmt = new OdpsReadStatement();
stmt.setTable(this.exprParser.name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
this.exprParser.names(stmt.getColumns(), stmt);
accept(Token.RPAREN);
}
if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
accept(Token.LPAREN);
parseAssignItems(stmt.getPartition(), stmt);
accept(Token.RPAREN);
}
if (lexer.token() == Token.LITERAL_INT) {
stmt.setRowCount(this.exprParser.primary());
}
statementList.add(stmt);
return true;
}
return false;
}
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
@@ -98,4 +99,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor {
void endVisit(OdpsStatisticClause.ColumnMin x);
boolean visit(OdpsStatisticClause.ColumnMin x);
void endVisit(OdpsReadStatement x);
boolean visit(OdpsReadStatement x);
}
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
@@ -201,5 +202,15 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA
public boolean visit(OdpsStatisticClause.ColumnMin x) {
return true;
}
@Override
public void endVisit(OdpsReadStatement x) {
}
@Override
public boolean visit(OdpsReadStatement x) {
return true;
}
}
@@ -34,6 +34,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
@@ -106,7 +107,7 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
print("LIFECYCLE ");
x.getLifecycle().accept(this);
}
if (x.getSelect() != null) {
println();
x.getSelect().accept(this);
@@ -241,17 +242,17 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
incrementIndent();
for (int i = 0, size = selectList.size(); i < size; ++i) {
SQLSelectItem selectItem = selectList.get(i);
if (i != 0) {
print(", ");
printComment(selectList.get(i - 1).getAfterCommentsDirect(), "\n");
println();
}
selectItem.accept(this);
if (i == selectList.size() - 1 && selectItem.hasAfterComment()) {
print(' ');
printComment(selectItem.getAfterCommentsDirect(), "\n");
@@ -397,10 +398,10 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
printComment(x.getBeforeCommentsDirect(), "\n");
println();
}
print("SELECT ");
List<SQLHint> hints= x.getHintsDirect();
List<SQLHint> hints = x.getHintsDirect();
if (hints != null) {
printAndAccept(hints, " ");
print(' ');
@@ -442,7 +443,7 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
println();
x.getOrderBy().accept(this);
}
if (x.getLimit() != null) {
println();
print("LIMIT ");
@@ -451,7 +452,7 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
return false;
}
public boolean visit(SQLOrderBy x) {
int itemSize = x.getItems().size();
if (itemSize > 0) {
@@ -471,28 +472,28 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
@Override
public void endVisit(OdpsAnalyzeTableStatement x) {
}
@Override
public boolean visit(OdpsAnalyzeTableStatement x) {
print("ANALYZE TABLE ");
x.getTable().accept(this);
if (x.getPartition().size() > 0) {
print(" PARTITION (");
printAndAccept(x.getPartition(), ", ");
print(")");
}
print(" COMPUTE STATISTICS");
return false;
}
@Override
public void endVisit(OdpsAddStatisticStatement x) {
}
@Override
@@ -501,93 +502,123 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
x.getTable().accept(this);
print(" ");
x.getStatisticClause().accept(this);
return false;
}
@Override
public void endVisit(OdpsRemoveStatisticStatement x) {
}
@Override
public boolean visit(OdpsRemoveStatisticStatement x) {
print("REMOVE STATISTIC ");
x.getTable().accept(this);
print(" ");
x.getStatisticClause().accept(this);
return false;
}
@Override
public void endVisit(OdpsStatisticClause.TableCount x) {
}
@Override
public boolean visit(OdpsStatisticClause.TableCount x) {
print("TABLE_COUNT");
return false;
}
@Override
public void endVisit(OdpsStatisticClause.ExpressionCondition x) {
}
@Override
public boolean visit(OdpsStatisticClause.ExpressionCondition x) {
print("EXPRESSION_CONDITION ");
x.getExpr().accept(this);
return false;
}
@Override
public void endVisit(OdpsStatisticClause.NullValue x) {
}
@Override
public boolean visit(OdpsStatisticClause.NullValue x) {
print("NULL_VALUE ");
x.getColumn().accept(this);
return false;
}
@Override
public void endVisit(OdpsStatisticClause.ColumnSum x) {
}
@Override
public boolean visit(OdpsStatisticClause.ColumnSum x) {
print("COLUMN_SUM ");
x.getColumn().accept(this);
return false;
}
@Override
public void endVisit(OdpsStatisticClause.ColumnMax x) {
}
@Override
public boolean visit(OdpsStatisticClause.ColumnMax x) {
print("COLUMN_MAX ");
x.getColumn().accept(this);
return false;
}
@Override
public void endVisit(OdpsStatisticClause.ColumnMin x) {
}
@Override
public boolean visit(OdpsStatisticClause.ColumnMin x) {
print("COLUMN_MIN ");
x.getColumn().accept(this);
return false;
}
@Override
public void endVisit(OdpsReadStatement x) {
}
@Override
public boolean visit(OdpsReadStatement x) {
print("READ ");
x.getTable().accept(this);
if (x.getColumns().size() > 0) {
print(" (");
printAndAccept(x.getColumns(), ", ");
print(")");
}
if (x.getPartition().size() > 0) {
print(" PARTITION (");
printAndAccept(x.getPartition(), ", ");
print(")");
}
if (x.getRowCount() != null) {
print(' ');
x.getRowCount().accept(this);
}
return false;
}
}
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
@@ -205,4 +206,14 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV
public boolean visit(OdpsStatisticClause.ColumnMin x) {
return true;
}
@Override
public void endVisit(OdpsReadStatement x) {
}
@Override
public boolean visit(OdpsReadStatement x) {
return true;
}
}
@@ -0,0 +1,37 @@
package com.alibaba.druid.bvt.sql.odps;
import org.junit.Assert;
import com.alibaba.druid.sql.SQLUtils;
import junit.framework.TestCase;
public class OdpsReadTest extends TestCase {
public void test_read() throws Exception {
String sql = "read sale_detail";
Assert.assertEquals("READ sale_detail", SQLUtils.formatOdps(sql));
}
public void test_read_column() throws Exception {
String sql = "read sale_detail(f0, f1, f2) 10";
Assert.assertEquals("READ sale_detail (f0, f1, f2) 10", SQLUtils.formatOdps(sql));
}
public void test_read_limit() throws Exception {
String sql = "read sale_detail 10";
Assert.assertEquals("READ sale_detail 10", SQLUtils.formatOdps(sql));
}
public void test_read_partition() throws Exception {
String sql = "read sale_detail partition(ds='20150701')";
Assert.assertEquals("READ sale_detail PARTITION (ds = '20150701')", SQLUtils.formatOdps(sql));
}
public void test_read_partition_limit() throws Exception {
String sql = "read sale_detail partition(ds='20150701') 10";
Assert.assertEquals("READ sale_detail PARTITION (ds = '20150701') 10", SQLUtils.formatOdps(sql));
}
}