diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableSetLocation.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableSetLocation.java new file mode 100644 index 0000000000..8c97a538ad --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableSetLocation.java @@ -0,0 +1,45 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObjectImpl; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLAlterTableSetLocation extends SQLObjectImpl implements SQLAlterTableItem { + + private SQLExpr location; + + public SQLExpr getLocation() { + return location; + } + + public void setLocation(SQLExpr x) { + if (x != null) { + x.setParent(this); + } + this.location = x; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, location); + } + visitor.endVisit(this); + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java index 2c75412783..f175150da7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java @@ -78,7 +78,18 @@ public class HiveStatementParser extends SQLStatementParser { String alias = lexer.stringVal(); accept(Token.IDENTIFIER); - SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias); + SQLTableSource from = new SQLSubqueryTableSource(select, alias); + + switch (lexer.token()) { + case LEFT: + case RIGHT: + case FULL: + case JOIN: + from = selectParser.parseTableSourceRest(from); + break; + default: + break; + } stmt.setFrom(from); } 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 2e89932a20..ad06b024ce 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -970,13 +970,17 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); break; case BANG: + lexer.nextToken(); + sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Not + , primary()); + break; case BANGBANG: { if (dbType == DbType.hive) { throw new ParserException(lexer.info()); } lexer.nextToken(); - SQLExpr bangExpr = primary(); - sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Not, bangExpr); + sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Not + , primary()); break; } case BANG_TILDE: { @@ -4606,6 +4610,17 @@ public class SQLExprParser extends SQLParser { } else { SQLExpr expr = expr(); + if (lexer.token == Token.COLON) { + if (dbType == DbType.hive || dbType == DbType.odps) { + Lexer.SavePoint mark = lexer.mark(); + lexer.nextToken(); + String str = expr.toString() + ':'; + str += lexer.numberString(); + lexer.nextToken(); + expr = new SQLIdentifierExpr(str); + } + } + if (lexer.token == Token.COMMA && DbType.postgresql == dbType) { SQLListExpr listExpr = new SQLListExpr(); listExpr.addItem(expr); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 1c45f572d6..f0d78258cd 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -2051,6 +2051,11 @@ public class SQLStatementParser extends SQLParser { SQLAlterTableSetLifecycle setLifecycle = new SQLAlterTableSetLifecycle(); setLifecycle.setLifecycle(this.exprParser.primary()); stmt.addItem(setLifecycle); + } else if (lexer.identifierEquals(Constants.LOCATION)) { + lexer.nextToken(); + SQLAlterTableSetLocation setLocation = new SQLAlterTableSetLocation(); + setLocation.setLocation(this.exprParser.primary()); + stmt.addItem(setLocation); } else if (lexer.identifierEquals(FnvHash.Constants.TBLPROPERTIES)) { lexer.nextToken(); SQLAlterTableSetOption setOption = new SQLAlterTableSetOption(); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index f5166a114f..24d7a59935 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -6579,6 +6579,13 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } + @Override + public boolean visit(SQLAlterTableSetLocation x) { + print0(ucase ? "SET LOCATION " : "set location "); + x.getLocation().accept(this); + return false; + } + @Override public boolean visit(SQLAlterTableEnableLifecycle x) { if (x.getPartition().size() != 0) { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index f3aca2e885..85b8c0cc1a 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -1077,6 +1077,14 @@ public interface SQLASTVisitor { } + default boolean visit(SQLAlterTableSetLocation x) { + return true; + } + + default void endVisit(SQLAlterTableSetLocation x) { + + } + default boolean visit(SQLAlterTableEnableLifecycle x) { return true; } diff --git a/src/test/resources/bvt/parser/hive-11.txt b/src/test/resources/bvt/parser/hive-11.txt new file mode 100644 index 0000000000..554c01d89b --- /dev/null +++ b/src/test/resources/bvt/parser/hive-11.txt @@ -0,0 +1,5 @@ +select * from bi.aaa where !array_contains(list, cc_id) +--------------------------- +SELECT * +FROM bi.aaa +WHERE !array_contains(list, cc_id) \ No newline at end of file diff --git a/src/test/resources/bvt/parser/hive-12.txt b/src/test/resources/bvt/parser/hive-12.txt new file mode 100644 index 0000000000..ce5ea8b297 --- /dev/null +++ b/src/test/resources/bvt/parser/hive-12.txt @@ -0,0 +1,17 @@ +from (select name,address from test1) t1 left join (select name,school from test2) t2 on t2.name = t1.name +insert overwrite table tt1 +select name,address,school insert overwrite table tt2 select name,address +--------------------------- +FROM ( + SELECT name, address + FROM test1 +) t1 + LEFT JOIN ( + SELECT name, school + FROM test2 + ) t2 + ON t2.name = t1.name +INSERT OVERWRITE TABLE tt1 +SELECT name, address, school +INSERT OVERWRITE TABLE tt2 +SELECT name, address \ No newline at end of file diff --git a/src/test/resources/bvt/parser/hive-13.txt b/src/test/resources/bvt/parser/hive-13.txt new file mode 100644 index 0000000000..76ca8efd15 --- /dev/null +++ b/src/test/resources/bvt/parser/hive-13.txt @@ -0,0 +1,3 @@ +set test.url=xx.test.com:8808; +--------------------------- +SET test.url = xx.test.com:8808; \ No newline at end of file diff --git a/src/test/resources/bvt/parser/hive-14.txt b/src/test/resources/bvt/parser/hive-14.txt new file mode 100644 index 0000000000..438e96fba6 --- /dev/null +++ b/src/test/resources/bvt/parser/hive-14.txt @@ -0,0 +1,4 @@ +ALTER TABLE bi.bi_xxx_external SET LOCATION 'hdfs://nameservice1/user/hive/warehouse/bi.db/bi_xxx/pt=aaa'; +--------------------------- +ALTER TABLE bi.bi_xxx_external + SET LOCATION 'hdfs://nameservice1/user/hive/warehouse/bi.db/bi_xxx/pt=aaa'; \ No newline at end of file