odps sql parser support lateral view & bug fixed for issue 1049

This commit is contained in:
高铁
2016-01-16 13:44:37 +08:00
parent f44c5ff4a6
commit b1dd5b59af
9 changed files with 228 additions and 3 deletions
@@ -0,0 +1,59 @@
package com.alibaba.druid.sql.dialect.odps.ast;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSourceImpl;
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OdpsLateralViewTableSource extends SQLTableSourceImpl {
private SQLTableSource tableSource;
private SQLMethodInvokeExpr method;
private List<SQLName> columns = new ArrayList<SQLName>(2);
@Override
protected void accept0(SQLASTVisitor visitor) {
accept0((OdpsASTVisitor) visitor);
}
protected void accept0(OdpsASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, tableSource);
acceptChild(visitor, method);
acceptChild(visitor, columns);
}
visitor.endVisit(this);
}
public SQLTableSource getTableSource() {
return tableSource;
}
public void setTableSource(SQLTableSource tableSource) {
this.tableSource = tableSource;
}
public SQLMethodInvokeExpr getMethod() {
return method;
}
public void setMethod(SQLMethodInvokeExpr method) {
this.method = method;
}
public List<SQLName> getColumns() {
return columns;
}
public void setColumns(List<SQLName> columns) {
this.columns = columns;
}
}
@@ -18,8 +18,11 @@ package com.alibaba.druid.sql.dialect.odps.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
@@ -121,5 +124,39 @@ public class OdpsSelectParser extends SQLSelectParser {
return queryRest(queryBlock);
}
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
tableSource = super.parseTableSourceRest(tableSource);
if ("LATERAL".equalsIgnoreCase(tableSource.getAlias()) && lexer.token() == Token.VIEW) {
return parseLateralView(tableSource);
}
if (identifierEquals("LATERAL")) {
lexer.nextToken();
return parseLateralView(tableSource);
}
return tableSource;
}
protected SQLTableSource parseLateralView(SQLTableSource tableSource) {
accept(Token.VIEW);
tableSource.setAlias(null);
OdpsLateralViewTableSource lateralViewTabSrc = new OdpsLateralViewTableSource();
lateralViewTabSrc.setTableSource(tableSource);
SQLMethodInvokeExpr udtf = (SQLMethodInvokeExpr) this.exprParser.expr();
lateralViewTabSrc.setMethod(udtf);
String alias = as();
lateralViewTabSrc.setAlias(alias);
accept(Token.AS);
this.exprParser.names(lateralViewTabSrc.getColumns());
return parseTableSourceRest(lateralViewTabSrc);
}
}
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt;
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.OdpsLateralViewTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
@@ -123,4 +124,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor {
void endVisit(OdpsDescStmt x);
boolean visit(OdpsDescStmt x);
void endVisit(OdpsLateralViewTableSource x);
boolean visit(OdpsLateralViewTableSource x);
}
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt;
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.OdpsLateralViewTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
@@ -256,5 +257,15 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA
public boolean visit(OdpsDescStmt x) {
return true;
}
@Override
public void endVisit(OdpsLateralViewTableSource x) {
}
@Override
public boolean visit(OdpsLateralViewTableSource x) {
return true;
}
}
@@ -41,6 +41,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt;
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.OdpsLateralViewTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
@@ -847,4 +848,24 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
}
return false;
}
@Override
public void endVisit(OdpsLateralViewTableSource x) {
}
@Override
public boolean visit(OdpsLateralViewTableSource x) {
x.getTableSource().accept(this);
incrementIndent();
println();
print0(ucase ? "LATERAL VIEW " : "lateral view ");
x.getMethod().accept(this);
print(' ');
print0(x.getAlias());
print0(ucase ? " AS " : " as ");
printAndAccept(x.getColumns(), ", ");
decrementIndent();
return false;
}
}
@@ -25,6 +25,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt;
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.OdpsLateralViewTableSource;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement;
@@ -261,4 +262,14 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV
public boolean visit(OdpsDescStmt x) {
return true;
}
@Override
public void endVisit(OdpsLateralViewTableSource x) {
}
@Override
public boolean visit(OdpsLateralViewTableSource x) {
return true;
}
}
@@ -389,10 +389,9 @@ public class SQLExprParser extends SQLParser {
SQLExpr notTarget = expr();
accept(Token.RPAREN);
notTarget = exprRest(notTarget);
notTarget = relationalRest(notTarget);
sqlExpr = new SQLNotExpr(notTarget);
return primaryRest(sqlExpr);
} else {
SQLExpr restExpr = relational();