diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsert.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsert.java similarity index 72% rename from src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsert.java rename to src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsert.java index a09d0acd01..89f145c756 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsert.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsert.java @@ -13,26 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.druid.sql.dialect.odps.ast; +package com.alibaba.druid.sql.dialect.hive.ast; import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLName; -import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLInsertInto; import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class OdpsInsert extends SQLObjectImpl { +public class HiveInsert extends SQLInsertInto { private boolean overwrite = false; private List partitions = new ArrayList(); - protected SQLExprTableSource tableSource; - private SQLSelect query; + public HiveInsert() { + + } public boolean isOverwrite() { return overwrite; @@ -57,6 +59,21 @@ public class OdpsInsert extends SQLObjectImpl { this.partitions = partitions; } + public void cloneTo(HiveInsert x) { + cloneTo(x); + x.overwrite = overwrite; + for (SQLAssignItem item : partitions) { + x.addPartition(item.clone()); + } + } + + @Override + public SQLInsertInto clone() { + HiveInsert x = new HiveInsert(); + cloneTo(x); + return x; + } + public SQLExprTableSource getTableSource() { return tableSource; } @@ -85,7 +102,11 @@ public class OdpsInsert extends SQLObjectImpl { @Override protected void accept0(SQLASTVisitor visitor) { - accept0((OdpsASTVisitor) visitor); + if (visitor instanceof HiveASTVisitor) { + accept0((HiveASTVisitor) visitor); + } else { + accept0((OdpsASTVisitor) visitor); + } } protected void accept0(OdpsASTVisitor visitor) { @@ -97,4 +118,12 @@ public class OdpsInsert extends SQLObjectImpl { visitor.endVisit(this); } + protected void accept0(HiveASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, tableSource); + acceptChild(visitor, partitions); + acceptChild(visitor, query); + } + visitor.endVisit(this); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsertStatement.java new file mode 100644 index 0000000000..9790993564 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveInsertStatement.java @@ -0,0 +1,97 @@ +/* + * 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.dialect.hive.ast; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLAssignItem; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; +import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.ArrayList; +import java.util.List; + +public class HiveInsertStatement extends SQLInsertStatement implements SQLStatement { + private boolean overwrite = false; + private List partitions = new ArrayList(); + + public HiveInsertStatement() { + dbType = JdbcConstants.HIVE; + } + + @Override + public String getDbType() { + return dbType; + } + + public boolean isOverwrite() { + return overwrite; + } + + public void setOverwrite(boolean overwrite) { + this.overwrite = overwrite; + } + + public List getPartitions() { + return partitions; + } + + public HiveInsertStatement clone() { + HiveInsertStatement x = new HiveInsertStatement(); + super.cloneTo(x); + return x; + } + + public void addPartition(SQLAssignItem partition) { + if (partition != null) { + partition.setParent(this); + } + this.partitions.add(partition); + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof OdpsASTVisitor) { + accept0((OdpsASTVisitor) visitor); + } else if (visitor instanceof HiveASTVisitor) { + accept0((HiveASTVisitor) visitor); + } else { + super.accept0(visitor); + } + } + + protected void accept0(HiveASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, tableSource); + acceptChild(visitor, partitions); + acceptChild(visitor, valuesList); + acceptChild(visitor, query); + } + visitor.endVisit(this); + } + + protected void accept0(OdpsASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, tableSource); + acceptChild(visitor, partitions); + acceptChild(visitor, valuesList); + acceptChild(visitor, query); + } + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveMultiInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveMultiInsertStatement.java new file mode 100644 index 0000000000..e575e9bb8e --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveMultiInsertStatement.java @@ -0,0 +1,73 @@ +/* + * 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.dialect.hive.ast; + +import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.ArrayList; +import java.util.List; + +public class HiveMultiInsertStatement extends SQLStatementImpl { + + private SQLTableSource from; + + private List items = new ArrayList(); + + public HiveMultiInsertStatement() { + dbType = JdbcConstants.HIVE; + } + + public void setFrom(SQLTableSource from) { + this.from = from; + } + + public SQLTableSource getFrom() { + return from; + } + + public List getItems() { + return items; + } + + public void addItem(HiveInsert item) { + if (item != null) { + item.setParent(this); + } + this.items.add(item); + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof HiveASTVisitor) { + accept0((HiveASTVisitor) visitor); + } else { + acceptChild(visitor, from); + acceptChild(visitor, items); + } + } + + public void accept0(HiveASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, from); + acceptChild(visitor, items); + } + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveLexer.java index 5b1a9c0dc0..640b51efd3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveLexer.java @@ -35,13 +35,18 @@ public class HiveLexer extends Lexer { map.put("CONCAT", Token.CONCAT); map.put("CONTINUE", Token.CONTINUE); map.put("MERGE", Token.MERGE); + map.put("MATCHED", Token.MATCHED); map.put("USING", Token.USING); - map.put("TRUE", Token.TRUE); - map.put("FALSE", Token.FALSE); map.put("ROW", Token.ROW); map.put("LIMIT", Token.LIMIT); map.put("PARTITIONED", Token.PARTITIONED); + map.put("PARTITION", Token.PARTITION); + map.put("OVERWRITE", Token.OVERWRITE); + map.put("SORT", Token.SORT); + map.put("IF", Token.IF); + map.put("TRUE", Token.TRUE); + map.put("FALSE", Token.FALSE); DEFAULT_HIVE_KEYWORDS = new Keywords(map); } 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 88b1bc5417..5cc4c3b3ac 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 @@ -18,11 +18,17 @@ package com.alibaba.druid.sql.dialect.hive.parser; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLReplaceStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; import com.alibaba.druid.sql.parser.*; import com.alibaba.druid.util.JdbcConstants; +import java.util.List; + public class HiveStatementParser extends SQLStatementParser { public HiveStatementParser(String sql) { super (new HiveExprParser(sql)); @@ -76,4 +82,60 @@ public class HiveStatementParser extends SQLStatementParser { public SQLCreateTableParser getSQLCreateTableParser() { return new HiveCreateTableParser(this.exprParser); } + + public SQLStatement parseInsert() { + if (lexer.token() == Token.FROM) { + lexer.nextToken(); + + HiveMultiInsertStatement stmt = new HiveMultiInsertStatement(); + + if (lexer.token() == Token.IDENTIFIER) { + SQLName tableName = this.exprParser.name(); + SQLExprTableSource from = new SQLExprTableSource(tableName); + stmt.setFrom(from); + + if (lexer.token() == Token.IDENTIFIER) { + from.setAlias(lexer.stringVal()); + lexer.nextToken(); + } + } else { + accept(Token.LPAREN); + + SQLSelectParser selectParser = createSQLSelectParser(); + SQLSelect select = selectParser.select(); + + accept(Token.RPAREN); + + String alias = lexer.stringVal(); + accept(Token.IDENTIFIER); + + SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias); + + stmt.setFrom(from); + } + + for (;;) { + HiveInsert insert = parseHiveInsert(); + stmt.addItem(insert); + + if (lexer.token() != Token.INSERT) { + break; + } + } + + return stmt; + } + + return parseHiveInsertStmt(); + } + + public boolean parseStatementListDialect(List statementList) { + if (lexer.token() == Token.FROM) { + SQLStatement stmt = this.parseInsert(); + statementList.add(stmt); + return true; + } + + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java index 69df3f61ff..1c17c85812 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java @@ -15,10 +15,22 @@ */ package com.alibaba.druid.sql.dialect.hive.visitor; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface HiveASTVisitor extends SQLASTVisitor { boolean visit(HiveCreateTableStatement x); void endVisit(HiveCreateTableStatement x); + + boolean visit(HiveMultiInsertStatement x); + void endVisit(HiveMultiInsertStatement x); + + boolean visit(HiveInsertStatement x); + void endVisit(HiveInsertStatement x); + + boolean visit(HiveInsert x); + void endVisit(HiveInsert x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java index 3ceb440c12..f4a2923541 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java @@ -15,6 +15,9 @@ */ package com.alibaba.druid.sql.dialect.hive.visitor; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; @@ -28,4 +31,34 @@ public class HiveASTVisitorAdapter extends SQLASTVisitorAdapter implements HiveA public void endVisit(HiveCreateTableStatement x) { } + + @Override + public boolean visit(HiveMultiInsertStatement x) { + return true; + } + + @Override + public void endVisit(HiveMultiInsertStatement x) { + + } + + @Override + public boolean visit(HiveInsertStatement x) { + return true; + } + + @Override + public void endVisit(HiveInsertStatement x) { + + } + + @Override + public boolean visit(HiveInsert x) { + return true; + } + + @Override + public void endVisit(HiveInsert x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java index a9b68ae2c6..150e05b91c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java @@ -19,6 +19,9 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; @@ -188,4 +191,140 @@ public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVis return false; } + + + @Override + public void endVisit(HiveMultiInsertStatement x) { + + } + + @Override + public boolean visit(HiveMultiInsertStatement x) { + SQLTableSource from = x.getFrom(); + if (x.getFrom() != null) { + if (from instanceof SQLSubqueryTableSource) { + SQLSelect select = ((SQLSubqueryTableSource) from).getSelect(); + print0(ucase ? "FROM (" : "from ("); + this.indentCount++; + println(); + select.accept(this); + this.indentCount--; + println(); + print0(") "); + print0(x.getFrom().getAlias()); + } else { + print0(ucase ? "FROM " : "from "); + from.accept(this); + } + println(); + } + + for (int i = 0; i < x.getItems().size(); ++i) { + HiveInsert insert = x.getItems().get(i); + if (i != 0) { + println(); + } + insert.accept(this); + } + return false; + } + + @Override + public void endVisit(HiveInsertStatement x) { + + } + + public boolean visit(HiveInsertStatement x) { + if (x.hasBeforeComment()) { + printlnComments(x.getBeforeCommentsDirect()); + } + if (x.isOverwrite()) { + print0(ucase ? "INSERT OVERWRITE TABLE " : "insert overwrite table "); + } else { + print0(ucase ? "INSERT INTO TABLE " : "insert into table "); + } + x.getTableSource().accept(this); + + int partitions = x.getPartitions().size(); + if (partitions > 0) { + print0(ucase ? " PARTITION (" : " partition ("); + for (int i = 0; i < partitions; ++i) { + if (i != 0) { + print0(", "); + } + + SQLAssignItem assign = x.getPartitions().get(i); + assign.getTarget().accept(this); + + if (assign.getValue() != null) { + print('='); + assign.getValue().accept(this); + } + } + print(')'); + } + println(); + + SQLSelect select = x.getQuery(); + List valuesList = x.getValuesList(); + if (select != null) { + select.accept(this); + } else if (!valuesList.isEmpty()) { + print0(ucase ? "VALUES " : "values "); + printAndAccept(valuesList, ", "); + } + + + return false; + } + + @Override + public boolean visit(HiveInsert x) { + if (x.hasBeforeComment()) { + printlnComments(x.getBeforeCommentsDirect()); + } + if (x.isOverwrite()) { + print0(ucase ? "INSERT OVERWRITE TABLE " : "insert overwrite table "); + } else { + print0(ucase ? "INSERT INTO TABLE " : "insert into table "); + } + x.getTableSource().accept(this); + + int partitions = x.getPartitions().size(); + if (partitions > 0) { + print0(ucase ? " PARTITION (" : " partition ("); + for (int i = 0; i < partitions; ++i) { + if (i != 0) { + print0(", "); + } + + SQLAssignItem assign = x.getPartitions().get(i); + assign.getTarget().accept(this); + + if (assign.getValue() != null) { + print('='); + assign.getValue().accept(this); + } + } + print(')'); + } + println(); + + SQLSelect select = x.getQuery(); + List valuesList = x.getValuesList(); + if (select != null) { + select.accept(this); + } else if (!valuesList.isEmpty()) { + print0(ucase ? "VALUES " : "values "); + printAndAccept(valuesList, ", "); + } + + + return false; + } + + @Override + public void endVisit(HiveInsert x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java index c716f317d8..cd67887dd8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java @@ -15,7 +15,107 @@ */ package com.alibaba.druid.sql.dialect.hive.visitor; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.statement.SQLAssignItem; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; +import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +public class HiveSchemaStatVisitor extends SchemaStatVisitor implements HiveASTVisitor { + + public HiveSchemaStatVisitor() { + super (JdbcConstants.HIVE); + } + + @Override + public boolean visit(HiveCreateTableStatement x) { + return super.visit((SQLCreateTableStatement) x); + } + + @Override + public void endVisit(HiveCreateTableStatement x) { + + } + + @Override + public boolean visit(HiveInsert x) { + setMode(x, TableStat.Mode.Insert); + + SQLExprTableSource tableSource = x.getTableSource(); + SQLExpr tableName = tableSource.getExpr(); + + if (tableName instanceof SQLName) { + TableStat stat = getTableStat((SQLName) tableName); + stat.incrementInsertCount(); + + } + + for (SQLAssignItem partition : x.getPartitions()) { + partition.accept(this); + } + + accept(x.getQuery()); + + return false; + } + + @Override + public void endVisit(HiveInsert x) { + + } + + @Override + public void endVisit(HiveMultiInsertStatement x) { + + } + + @Override + public boolean visit(HiveMultiInsertStatement x) { + if (repository != null + && x.getParent() == null) { + repository.resolve(x); + } + return true; + } + + + @Override + public void endVisit(HiveInsertStatement x) { + + } + + @Override + public boolean visit(HiveInsertStatement x) { + if (repository != null + && x.getParent() == null) { + repository.resolve(x); + } + + setMode(x, TableStat.Mode.Insert); + + SQLExprTableSource tableSource = x.getTableSource(); + SQLExpr tableName = tableSource.getExpr(); + + if (tableName instanceof SQLName) { + TableStat stat = getTableStat((SQLName) tableName); + stat.incrementInsertCount(); + + } + + for (SQLAssignItem partition : x.getPartitions()) { + partition.accept(this); + } + + accept(x.getQuery()); + + return false; + } -public class HiveSchemaStatVisitor extends SchemaStatVisitor { } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 235dd32833..25276c2778 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -4239,8 +4239,6 @@ public class MySqlStatementParser extends SQLStatementParser { } else if (lexer.identifierEquals(FnvHash.Constants.CHARACTER)) { SQLAlterCharacter item = alterTableCharacter(); stmt.setCharacter(item); - } else { - throw new ParserException("TODO " + lexer.info()); } return stmt; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java index 80bc0779c9..10749b2576 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java @@ -18,10 +18,9 @@ package com.alibaba.druid.sql.dialect.odps.ast; import java.util.ArrayList; import java.util.List; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.SQLStatementImpl; -import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.util.JdbcConstants; @@ -30,7 +29,7 @@ public class OdpsInsertStatement extends SQLStatementImpl { private SQLTableSource from; - private List items = new ArrayList(); + private List items = new ArrayList(); public OdpsInsertStatement() { super (JdbcConstants.ODPS); @@ -44,11 +43,11 @@ public class OdpsInsertStatement extends SQLStatementImpl { return from; } - public List getItems() { + public List getItems() { return items; } - public void addItem(OdpsInsert item) { + public void addItem(HiveInsert item) { if (item != null) { item.setParent(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index 5e14051e24..99e0ca74e1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -34,7 +34,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; 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.OdpsGrantStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; @@ -254,7 +254,7 @@ public class OdpsStatementParser extends SQLStatementParser { } for (;;) { - OdpsInsert insert = parseOdpsInsert(); + HiveInsert insert = parseHiveInsert(); stmt.addItem(insert); if (lexer.token() != Token.INSERT) { @@ -269,54 +269,6 @@ public class OdpsStatementParser extends SQLStatementParser { return new OdpsSelectParser(this.exprParser, selectListCache); } - public OdpsInsert parseOdpsInsert() { - OdpsInsert insert = new OdpsInsert(); - - if (lexer.isKeepComments() && lexer.hasComment()) { - insert.addBeforeComment(lexer.readAndResetComments()); - } - - SQLSelectParser selectParser = createSQLSelectParser(); - - accept(Token.INSERT); - - if (lexer.token() == Token.INTO) { - lexer.nextToken(); - } else { - accept(Token.OVERWRITE); - insert.setOverwrite(true); - } - - accept(Token.TABLE); - insert.setTableSource(this.exprParser.name()); - - if (lexer.token() == Token.PARTITION) { - lexer.nextToken(); - accept(Token.LPAREN); - for (;;) { - SQLAssignItem ptExpr = new SQLAssignItem(); - ptExpr.setTarget(this.exprParser.name()); - if (lexer.token() == Token.EQ) { - lexer.nextToken(); - SQLExpr ptValue = this.exprParser.expr(); - ptExpr.setValue(ptValue); - } - insert.addPartition(ptExpr); - if (!(lexer.token() == (Token.COMMA))) { - break; - } else { - lexer.nextToken(); - } - } - accept(Token.RPAREN); - } - - SQLSelect query = selectParser.select(); - insert.setQuery(query); - - return insert; - } - public SQLStatement parseShow() { accept(Token.SHOW); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java index 6505463e92..7a7d95c8d9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java @@ -15,7 +15,7 @@ */ package com.alibaba.druid.sql.dialect.odps.visitor; -import com.alibaba.druid.sql.ast.statement.SQLLateralViewTableSource; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -29,9 +29,9 @@ public interface OdpsASTVisitor extends SQLASTVisitor { boolean visit(OdpsInsertStatement x); - void endVisit(OdpsInsert x); + void endVisit(HiveInsert x); - boolean visit(OdpsInsert x); + boolean visit(HiveInsert x); void endVisit(OdpsUDTFSQLSelectItem x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java index 9cc6d76a6d..0db8aacdc6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java @@ -15,6 +15,10 @@ */ package com.alibaba.druid.sql.dialect.odps.visitor; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement; +import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; @@ -42,12 +46,36 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA } @Override - public void endVisit(OdpsInsert x) { + public void endVisit(HiveInsert x) { } + public boolean visit(HiveCreateTableStatement x) { + return false; + } + + public void endVisit(HiveCreateTableStatement x) { + + } + + public boolean visit(HiveMultiInsertStatement x) { + return false; + } + + public void endVisit(HiveMultiInsertStatement x) { + + } + + public boolean visit(HiveInsertStatement x) { + return false; + } + + public void endVisit(HiveInsertStatement x) { + + } + @Override - public boolean visit(OdpsInsert x) { + public boolean visit(HiveInsert x) { return true; } 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 92a8134764..6d0a51ecf2 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 @@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.util.JdbcConstants; @@ -223,7 +224,7 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis } for (int i = 0; i < x.getItems().size(); ++i) { - OdpsInsert insert = x.getItems().get(i); + HiveInsert insert = x.getItems().get(i); if (i != 0) { println(); } @@ -233,12 +234,12 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis } @Override - public void endVisit(OdpsInsert x) { + public void endVisit(HiveInsert x) { } @Override - public boolean visit(OdpsInsert x) { + public boolean visit(HiveInsert x) { if (x.hasBeforeComment()) { printlnComments(x.getBeforeCommentsDirect()); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index cc7102d4c6..b5ffe863f9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -18,6 +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.hive.ast.HiveInsert; import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.stat.TableStat; @@ -54,12 +55,12 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV } @Override - public void endVisit(OdpsInsert x) { + public void endVisit(HiveInsert x) { } @Override - public boolean visit(OdpsInsert x) { + public boolean visit(HiveInsert x) { setMode(x, TableStat.Mode.Insert); SQLExprTableSource tableSource = x.getTableSource(); 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 35ac7698f2..6bd0c4fa83 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -22,6 +22,8 @@ import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser; import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser; @@ -3300,6 +3302,146 @@ public class SQLStatementParser extends SQLParser { } } + protected HiveInsertStatement parseHiveInsertStmt() { + HiveInsertStatement insert = new HiveInsertStatement(); + + if (lexer.isKeepComments() && lexer.hasComment()) { + insert.addBeforeComment(lexer.readAndResetComments()); + } + + SQLSelectParser selectParser = createSQLSelectParser(); + + accept(Token.INSERT); + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + } else { + accept(Token.OVERWRITE); + insert.setOverwrite(true); + } + + accept(Token.TABLE); + insert.setTableSource(this.exprParser.name()); + + if (lexer.token() == Token.PARTITION) { + lexer.nextToken(); + accept(Token.LPAREN); + for (;;) { + SQLAssignItem ptExpr = new SQLAssignItem(); + ptExpr.setTarget(this.exprParser.name()); + if (lexer.token() == Token.EQ) { + lexer.nextToken(); + SQLExpr ptValue = this.exprParser.expr(); + ptExpr.setValue(ptValue); + } + insert.addPartition(ptExpr); + if (!(lexer.token() == (Token.COMMA))) { + break; + } else { + lexer.nextToken(); + } + } + accept(Token.RPAREN); + } + + if (lexer.token() == Token.VALUES) { + lexer.nextToken(); + + for (;;) { + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); + this.exprParser.exprList(values.getValues(), values); + insert.addValueCause(values); + accept(Token.RPAREN); + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } else { + break; + } + } + } else { + SQLSelect query = selectParser.select(); + insert.setQuery(query); + } + + return insert; + } + + protected HiveInsert parseHiveInsert() { + HiveInsert insert = new HiveInsert(); + + if (lexer.isKeepComments() && lexer.hasComment()) { + insert.addBeforeComment(lexer.readAndResetComments()); + } + + SQLSelectParser selectParser = createSQLSelectParser(); + + accept(Token.INSERT); + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + } else { + accept(Token.OVERWRITE); + insert.setOverwrite(true); + } + + accept(Token.TABLE); + insert.setTableSource(this.exprParser.name()); + + if (lexer.token() == Token.PARTITION) { + lexer.nextToken(); + accept(Token.LPAREN); + for (;;) { + SQLAssignItem ptExpr = new SQLAssignItem(); + ptExpr.setTarget(this.exprParser.name()); + if (lexer.token() == Token.EQ) { + lexer.nextToken(); + SQLExpr ptValue = this.exprParser.expr(); + ptExpr.setValue(ptValue); + } + insert.addPartition(ptExpr); + if (!(lexer.token() == (Token.COMMA))) { + break; + } else { + lexer.nextToken(); + } + } + accept(Token.RPAREN); + } + + if (lexer.token() == Token.VALUES) { + lexer.nextToken(); + + for (;;) { + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); + this.exprParser.exprList(values.getValues(), values); + insert.addValueCause(values); + accept(Token.RPAREN); + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } else { + break; + } + } + } else { + SQLSelect query = selectParser.select(); + insert.setQuery(query); + } + + return insert; + } + public SQLSelectListCache getSelectListCache() { return selectListCache; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index ee31dd2724..96500be104 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -66,8 +66,8 @@ public enum Token { EXPLAIN("EXPLAIN"), FOR("FOR"), - IF("IF"), - + IF("IF"), + SORT("SORT"), ALL("ALL"), diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java index 6cc22cc0e5..4a80697bcb 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java @@ -263,6 +263,8 @@ public class SchemaRepository { resolveVisitor = new SchemaResolveVisitorFactory.DB2ResolveVisitor(this, optionsValue); } else if (JdbcConstants.ODPS.equals(dbType)) { resolveVisitor = new SchemaResolveVisitorFactory.OdpsResolveVisitor(this, optionsValue); + } else if (JdbcConstants.HIVE.equals(dbType)) { + resolveVisitor = new SchemaResolveVisitorFactory.HiveResolveVisitor(this, optionsValue); } else if (JdbcConstants.POSTGRESQL.equals(dbType)) { resolveVisitor = new SchemaResolveVisitorFactory.PGResolveVisitor(this, optionsValue); } else if (JdbcConstants.SQL_SERVER.equals(dbType)) { diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java index 4504318206..836747c736 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaResolveVisitorFactory.java @@ -22,6 +22,8 @@ import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.db2.ast.DB2Object; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitorAdapter; +import com.alibaba.druid.sql.dialect.hive.ast.HiveInsert; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitorAdapter; import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; @@ -764,7 +766,190 @@ class SchemaResolveVisitorFactory { return false; } - public boolean visit(OdpsInsert x) { + public boolean visit(HiveInsert x) { + Context ctx = createContext(x); + + SQLExprTableSource tableSource = x.getTableSource(); + if (tableSource != null) { + ctx.setTableSource(x.getTableSource()); + visit(tableSource); + } + + for (SQLAssignItem item : x.getPartitions()) { + item.accept(this); + } + + SQLSelect select = x.getQuery(); + if (select != null) { + visit(select); + } + + popContext(); + return false; + } + + public boolean visit(SQLInsertStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLAlterTableStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLMergeStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLCreateProcedureStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLBlockStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLParameter x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLDeclareItem x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLOver x) { + resolve(this, x); + return false; + } + + @Override + public boolean isEnabled(Option option) { + return (options & option.mask) != 0; + } + + @Override + public Context getContext() { + return context; + } + + public Context createContext(SQLObject object) { + return this.context = new Context(object, context); + } + + @Override + public void popContext() { + if (context != null) { + context = context.parent; + } + } + + public SchemaRepository getRepository() { + return repository; + } + } + + static class HiveResolveVisitor extends HiveASTVisitorAdapter implements SchemaResolveVisitor { + private int options; + private SchemaRepository repository; + private Context context; + + public HiveResolveVisitor(SchemaRepository repository, int options) { + this.repository = repository; + this.options = options; + } + + public boolean visit(SQLForeignKeyImpl x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLSelectStatement x) { + resolve(this, x.getSelect()); + return false; + } + + public boolean visit(SQLExprTableSource x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLSelectQueryBlock x) { + resolve(this, x); + return false; + } + + public boolean visit(OdpsSelectQueryBlock x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLSelectItem x) { + SQLExpr expr = x.getExpr(); + if (expr instanceof SQLIdentifierExpr) { + resolve(this, (SQLIdentifierExpr) expr); + return false; + } + + if (expr instanceof SQLPropertyExpr) { + resolve(this, (SQLPropertyExpr) expr); + return false; + } + + return true; + } + + public boolean visit(SQLIdentifierExpr x) { + resolve(this, x); + return true; + } + + public boolean visit(SQLPropertyExpr x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLAllColumnExpr x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLCreateTableStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(OdpsCreateTableStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLUpdateStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLDeleteStatement x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLSelect x) { + resolve(this, x); + return false; + } + + public boolean visit(SQLWithSubqueryClause x) { + resolve(this, x); + return false; + } + + public boolean visit(HiveInsert x) { Context ctx = createContext(x); SQLExprTableSource tableSource = x.getTableSource(); @@ -2046,6 +2231,12 @@ class SchemaResolveVisitorFactory { } } } + + if (from instanceof SQLJoinTableSource) { + SQLJoinTableSource join = (SQLJoinTableSource) from; + extractColumns(visitor, join.getLeft(), columns); + extractColumns(visitor, join.getRight(), columns); + } } static void resolve(SchemaResolveVisitor visitor, SQLAllColumnExpr x) { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_0.java b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_0.java new file mode 100644 index 0000000000..3355b0842e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_0.java @@ -0,0 +1,41 @@ +package com.alibaba.druid.bvt.sql.hive; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class HiveInsert_0 extends TestCase { + public void test_select() throws Exception { + String sql = "INSERT INTO TABLE students\n" + + " VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);";// + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.HIVE); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.HIVE); + stmt.accept(visitor); + + assertEquals("INSERT INTO TABLE students\n" + + "VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);", SQLUtils.formatHive(sql)); + + assertEquals("insert into table students\n" + + "values ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);", SQLUtils.formatHive(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(0, visitor.getColumns().size()); + assertEquals(0, visitor.getConditions().size()); + + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_1.java b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_1.java new file mode 100644 index 0000000000..d7b2227dfa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveInsert_1.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.bvt.sql.hive; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class HiveInsert_1 extends TestCase { + public void test_select() throws Exception { + String sql = "FROM page_view_stg pvs\n" + + "INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country)\n" + + " SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip, pvs.cnt";// + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.HIVE); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.HIVE); + stmt.accept(visitor); + + assertEquals("FROM page_view_stg pvs\n" + + "INSERT OVERWRITE TABLE page_view PARTITION (dt='2008-06-08', country)\n" + + "SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, NULL\n" + + "\t, NULL, pvs.ip, pvs.cnt", SQLUtils.formatHive(sql)); + + assertEquals("from page_view_stg pvs\n" + + "insert overwrite table page_view partition (dt='2008-06-08', country)\n" + + "select pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null\n" + + "\t, null, pvs.ip, pvs.cnt", SQLUtils.formatHive(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(2, visitor.getTables().size()); + assertEquals(8, visitor.getColumns().size()); + assertEquals(0, visitor.getConditions().size()); + + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/AntlrMySqlTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/AntlrMySqlTest.java index 885d128cb5..fb4b311329 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/AntlrMySqlTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/AntlrMySqlTest.java @@ -25,6 +25,7 @@ public class AntlrMySqlTest extends TestCase { for (File file : dir.listFiles()) { System.out.println(file); String sql = FileUtils.readFileToString(file); + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); for (SQLStatement stmt : stmtList) { stmt.toString(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/repository/OracleJoinResolveTest_2_join.java b/src/test/java/com/alibaba/druid/bvt/sql/repository/OracleJoinResolveTest_2_join.java index fa4e1057e8..5631b16b6e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/repository/OracleJoinResolveTest_2_join.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/repository/OracleJoinResolveTest_2_join.java @@ -23,7 +23,7 @@ public class OracleJoinResolveTest_2_join extends TestCase { public void test_for_issue() throws Exception { String sql = "select a.* from t_user a inner join t_group b where a.uid = id"; - assertEquals("SELECT a.uid, a.gid, a.name, b.id, b.name\n" + + assertEquals("SELECT a.uid, a.gid, a.name, b.id, a.name\n" + "FROM t_user a\n" + "\tINNER JOIN t_group b\n" + "WHERE a.uid = b.id"