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