diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java index 20831723fd..85ccb7d143 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLUnionOperator.java @@ -19,6 +19,7 @@ public enum SQLUnionOperator { UNION("UNION"), UNION_ALL("UNION ALL"), MINUS("MINUS"), + MINUS_DISTINCT("MINUS DISTINCT"), EXCEPT("EXCEPT"), EXCEPT_ALL("EXCEPT ALL"), EXCEPT_DISTINCT("EXCEPT DISTINCT"), diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java index 34560a1662..cbb2a804b7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.odps.parser; import com.alibaba.druid.sql.ast.ClusteringType; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; @@ -280,6 +281,19 @@ public class OdpsCreateTableParser extends SQLCreateTableParser { acceptIdentifier("SHARDS"); } } + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + + if (lexer.token() == Token.LITERAL_INT) { + stmt.setIntoBuckets( + new SQLIntegerExpr(lexer.integerValue().intValue())); + lexer.nextToken(); + acceptIdentifier("BUCKETS"); + } else { + throw new ParserException("into shards must be integer. " + lexer.info()); + } + } if (lexer.identifierEquals(FnvHash.Constants.LIFECYCLE)) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java index 4d5d4a4335..610d6f14df 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java @@ -218,6 +218,10 @@ public class OdpsExprParser extends SQLExprParser { break; } accept(Token.RPAREN); + } else { + SQLColumnDefinition column = new SQLColumnDefinition(); + column.setName(this.name()); + outputColumns.add(column); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index 6c3de2008d..1845ad9a07 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -973,10 +973,17 @@ public class OdpsOutputVisitor extends HiveOutputVisitor implements OdpsASTVisit if (!outputColumns.isEmpty()) { println(); print0(ucase ? "AS (" : "as ("); - printAndAccept(resources, ", "); + printAndAccept(outputColumns, ", "); print(')'); } + SQLExternalRecordFormat inputRowFormat = x.getInputRowFormat(); + if (inputRowFormat != null) { + println(); + print0(ucase ? "ROW FORMAT DELIMITED" : "row format delimited"); + inputRowFormat.accept(this); + } + return false; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 52576f9174..f0eb5eed83 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1094,6 +1094,11 @@ public class SQLExprParser extends SQLParser { case LIKE: case UNION: case CREATE: + case COMMA: + case STAR: + case DIV: + case DISTRIBUTE: + case UNIQUE: if (dbType == DbType.odps || dbType == DbType.hive) { sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); lexer.nextToken(); @@ -1176,10 +1181,17 @@ public class SQLExprParser extends SQLParser { SQLExpr sqlExpr; String str = lexer.stringVal(); lexer.nextToken(); - if (lexer.token == Token.DOT || lexer.token == Token.SLASH) { - return primaryRest(new SQLIdentifierExpr(str)); - } else if (lexer.token == Token.COMMA) { - return new SQLIdentifierExpr(str); + switch (lexer.token) { + case DOT: + case SLASH: + return primaryRest(new SQLIdentifierExpr(str)); + case COMMA: + case PLUS: + case SUB: + case RPAREN: + return new SQLIdentifierExpr(str); + default: + break; } SQLAllExpr allExpr = new SQLAllExpr(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index aa2df62e4b..2121a6e0b2 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -160,7 +160,9 @@ public class SQLParser { return ident; } else if (hash == FnvHash.Constants.DISTRIBUTE || hash == FnvHash.Constants.SORT - || hash == FnvHash.Constants.CLUSTER) { + || hash == FnvHash.Constants.CLUSTER + || hash == FnvHash.Constants.ZORDER + ) { Lexer.SavePoint mark = lexer.mark(); lexer.nextToken(); if (lexer.token == Token.BY) { @@ -217,6 +219,8 @@ public class SQLParser { case FOR: case GRANT: case CHECK: + case LEAVE: + case TRIGGER: if (dbType == DbType.odps || dbType == DbType.hive) { String strVal = lexer.stringVal(); lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index e85db2da1b..b05c122e24 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -58,7 +58,7 @@ public class SQLSelectParser extends SQLParser { select.setWithSubQuery(with); } - SQLSelectQuery query = query(select); + SQLSelectQuery query = query(select, true); select.setQuery(query); SQLOrderBy orderBy = this.parseOrderBy(); @@ -336,6 +336,10 @@ public class SQLSelectParser extends SQLParser { union.setLeft(selectQuery); union.setOperator(SQLUnionOperator.MINUS); + if (lexer.token == Token.DISTINCT) { + union.setOperator(SQLUnionOperator.MINUS_DISTINCT); + lexer.nextToken(); + } SQLSelectQuery right = this.query(union, false); union.setRight(right); @@ -1094,7 +1098,7 @@ public class SQLSelectParser extends SQLParser { this.exprParser.names(tableSource.getColumns(), tableSource); accept(Token.RPAREN); - return tableSource; + return parseTableSourceRest(tableSource); } if (lexer.token == Token.SELECT) { diff --git a/src/main/java/com/alibaba/druid/util/FnvHash.java b/src/main/java/com/alibaba/druid/util/FnvHash.java index 03258b6311..f20df12ecf 100644 --- a/src/main/java/com/alibaba/druid/util/FnvHash.java +++ b/src/main/java/com/alibaba/druid/util/FnvHash.java @@ -812,6 +812,7 @@ public final class FnvHash { long MPP = fnv1a_64_lower("MPP"); long SERDE = fnv1a_64_lower("SERDE"); long SORT = fnv1a_64_lower("SORT"); + long ZORDER = fnv1a_64_lower("ZORDER"); long FIELDS = fnv1a_64_lower("FIELDS"); long COLLECTION = fnv1a_64_lower("COLLECTION"); long SKEWED = fnv1a_64_lower("SKEWED");