improved odps sql parser. support values datasource.

This commit is contained in:
wenshao
2017-02-23 21:01:48 +08:00
parent d84d1b81fe
commit 1ff403500f
10 changed files with 257 additions and 80 deletions
@@ -0,0 +1,42 @@
package com.alibaba.druid.sql.dialect.odps.ast;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSourceImpl;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsObject;
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wenshao on 23/02/2017.
*/
public class OdpsValuesTableSource extends SQLTableSourceImpl implements OdpsObject {
private List<SQLListExpr> values = new ArrayList<SQLListExpr>();
private List<SQLName> columns = new ArrayList<SQLName>();
@Override
protected void accept0(SQLASTVisitor visitor) {
accept0((OdpsASTVisitor) visitor);
}
public List<SQLListExpr> getValues() {
return values;
}
public List<SQLName> getColumns() {
return columns;
}
@Override
public void accept0(OdpsASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, values);
acceptChild(visitor, columns);
}
visitor.endVisit(this);
}
}
@@ -19,12 +19,14 @@ import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
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.dialect.odps.ast.OdpsValuesTableSource;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
@@ -123,6 +125,41 @@ public class OdpsSelectParser extends SQLSelectParser {
return queryRest(queryBlock);
}
public SQLTableSource parseTableSource() {
if (lexer.token() == Token.VALUES) {
lexer.nextToken();
OdpsValuesTableSource tableSource = new OdpsValuesTableSource();
for (;;) {
accept(Token.LPAREN);
SQLListExpr listExpr = new SQLListExpr();
this.exprParser.exprList(listExpr.getItems(), listExpr);
accept(Token.RPAREN);
listExpr.setParent(tableSource);
tableSource.getValues().add(listExpr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
String alias = this.as();
tableSource.setAlias(alias);
accept(Token.LPAREN);
this.exprParser.names(tableSource.getColumns(), tableSource);
accept(Token.RPAREN);
return tableSource;
}
return super.parseTableSource();
}
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
tableSource = super.parseTableSourceRest(tableSource);
@@ -15,24 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.odps.visitor;
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.OdpsCreateTableStatement;
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;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.dialect.odps.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public interface OdpsASTVisitor extends SQLASTVisitor {
@@ -128,4 +111,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor {
void endVisit(OdpsLateralViewTableSource x);
boolean visit(OdpsLateralViewTableSource x);
void endVisit(OdpsValuesTableSource x);
boolean visit(OdpsValuesTableSource x);
}
@@ -15,24 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.odps.visitor;
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.OdpsCreateTableStatement;
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;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.dialect.odps.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
@@ -268,4 +251,13 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA
return true;
}
@Override
public void endVisit(OdpsValuesTableSource x) {
}
@Override
public boolean visit(OdpsValuesTableSource x) {
return true;
}
}
@@ -29,24 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
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.OdpsCreateTableStatement;
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;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.dialect.odps.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.JdbcConstants;
@@ -911,4 +894,23 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
return false;
}
@Override
public void endVisit(OdpsValuesTableSource x) {
}
@Override
public boolean visit(OdpsValuesTableSource x) {
print0(ucase ? "VALUES " : "values ");
printAndAccept(x.getValues(), ", ");
print(' ');
print0(x.getAlias());
print0(" (");
printAndAccept(x.getColumns(), ", ");
print(')');
return false;
}
}
@@ -18,24 +18,7 @@ package com.alibaba.druid.sql.dialect.odps.visitor;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.*;
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.OdpsCreateTableStatement;
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;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem;
import com.alibaba.druid.sql.dialect.odps.ast.*;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
@@ -300,4 +283,19 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV
public boolean visit(OdpsLateralViewTableSource x) {
return true;
}
@Override
public void endVisit(OdpsValuesTableSource x) {
}
@Override
public boolean visit(OdpsValuesTableSource x) {
Map<String, String> aliasMap = getAliasMap();
if (aliasMap != null && x.getAlias() != null) {
putAliasMap(aliasMap, x.getAlias(), null);
addSubQuery(x.getAlias(), x);
}
return false;
}
}
@@ -54,6 +54,7 @@ import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExpr;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsValuesTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExpr;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter;
import com.alibaba.druid.stat.TableStat;
@@ -859,6 +860,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
List<SQLSelectItem> selectList = null;
if (query instanceof SQLSelectQueryBlock) {
queryBlock = (SQLSelectQueryBlock) query;
if (queryBlock.getGroupBy() != null) {
return null;
}
selectList = queryBlock.getSelectList();
}
@@ -960,7 +966,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
return false;
}
Column column;
Column column = null;
if (currentTable != null) {
column = addColumn(currentTable, ident);
@@ -969,7 +975,22 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
x.putAttribute(ATTR_COLUMN, column);
} else {
column = handleUnkownColumn(ident);
boolean skip = false;
for (SQLObject parent = x.getParent();parent != null;parent = parent.getParent()) {
if (parent instanceof SQLSelectQueryBlock) {
SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom();
if (from instanceof OdpsValuesTableSource) {
skip = true;
break;
}
} else if (parent instanceof SQLSelectQuery) {
break;
}
}
if (!skip) {
column = handleUnkownColumn(ident);
}
if (column != null) {
x.putAttribute(ATTR_COLUMN, column);
}