From 4775d9e4751586ff946a544ae460000a8693f8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Sat, 25 Feb 2012 19:54:09 +0800 Subject: [PATCH] add hive sql parser --- .../sql/dialect/hive/ast/HiveSQLObject.java | 9 ++ .../dialect/hive/ast/HiveSQLObjectImpl.java | 36 +++++++ .../sql/dialect/hive/ast/HiveStatement.java | 7 ++ .../ast/stmt/HiveCreateTableStatement.java | 68 +++++++++++++ .../sql/dialect/hive/parser/HiveLexer.java | 95 ++++++++++++++++++- .../hive/parser/HiveStatementParser.java | 18 ++++ .../dialect/hive/visitor/HiveASTVisitor.java | 11 +++ .../hive/visitor/HiveASTVisitorAdapter.java | 19 ++++ .../hive/visitor/HiveOutputVisitor.java | 24 +++++ .../hive/visitor/HiveSchemaStatVisitor.java | 18 ++++ .../parser/SQLServerStatementParser.java | 83 ---------------- .../druid/sql/visitor/SchemaStatVisitor.java | 48 ++++++++-- .../com/alibaba/druid/stat/TableStat.java | 12 +++ .../bvt/sql/hive/HiveCreateTableTest.java | 40 ++++++++ .../druid/bvt/sql/hive/HiveSelectTest.java | 38 ++++++++ .../druid/bvt/sql/hive/HiveSelectTest2.java | 40 ++++++++ .../bvt/sql/oracle/OracleSelectTest2.java | 2 +- .../com/alibaba/druid/sql/hive/HiveTest.java | 22 +++++ 18 files changed, 496 insertions(+), 94 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObject.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObjectImpl.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/ast/stmt/HiveCreateTableStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/hive/HiveCreateTableTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest2.java create mode 100644 src/test/java/com/alibaba/druid/sql/hive/HiveTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObject.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObject.java new file mode 100644 index 0000000000..5e43e17d3f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObject.java @@ -0,0 +1,9 @@ +package com.alibaba.druid.sql.dialect.hive.ast; + +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; + + +public interface HiveSQLObject extends SQLObject { + void accept0(HiveASTVisitor visitor); +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObjectImpl.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObjectImpl.java new file mode 100644 index 0000000000..9db8034877 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveSQLObjectImpl.java @@ -0,0 +1,36 @@ +/* + * Copyright 1999-2011 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.SQLObjectImpl; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public abstract class HiveSQLObjectImpl extends SQLObjectImpl implements HiveSQLObject { + + private static final long serialVersionUID = 1L; + + @Override + public void accept0(SQLASTVisitor visitor) { + if (visitor instanceof HiveASTVisitor) { + accept0((HiveASTVisitor) visitor); + } else { + throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName()); + } + } + + public abstract void accept0(HiveASTVisitor visitor); +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveStatement.java new file mode 100644 index 0000000000..54329e1a1d --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/HiveStatement.java @@ -0,0 +1,7 @@ +package com.alibaba.druid.sql.dialect.hive.ast; + +import com.alibaba.druid.sql.ast.SQLStatement; + +public interface HiveStatement extends SQLStatement, HiveSQLObject { + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/stmt/HiveCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/stmt/HiveCreateTableStatement.java new file mode 100644 index 0000000000..0e0a2edc71 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/ast/stmt/HiveCreateTableStatement.java @@ -0,0 +1,68 @@ +package com.alibaba.druid.sql.dialect.hive.ast.stmt; + +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.dialect.hive.ast.HiveSQLObjectImpl; +import com.alibaba.druid.sql.dialect.hive.ast.HiveStatement; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class HiveCreateTableStatement extends SQLCreateTableStatement implements HiveStatement { + + private static final long serialVersionUID = 1L; + + private PartitionedBy partitionedBy; + + public PartitionedBy getPartitionedBy() { + return partitionedBy; + } + + public void setPartitionedBy(PartitionedBy partitionedBy) { + this.partitionedBy = partitionedBy; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + this.accept0((HiveASTVisitor) visitor); + } + + @Override + public void accept0(HiveASTVisitor visitor) { + if (visitor.visit(this)) { + this.acceptChild(visitor, name); + this.acceptChild(visitor, tableElementList); + this.acceptChild(visitor, partitionedBy); + } + visitor.endVisit(this); + } + + public static class PartitionedBy extends HiveSQLObjectImpl { + + private static final long serialVersionUID = 1L; + private String name; + private SQLDataType type; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public SQLDataType getType() { + return type; + } + + public void setType(SQLDataType type) { + this.type = type; + } + + @Override + public void accept0(HiveASTVisitor visitor) { + + } + + } + +} 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 7282508490..3b35eaf5d5 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 @@ -1,14 +1,103 @@ package com.alibaba.druid.sql.dialect.hive.parser; +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.druid.sql.parser.Keywords; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.Token; public class HiveLexer extends Lexer { + public final static Keywords DEFAULT_SQL_SERVER_KEYWORDS; - public HiveLexer(char[] input, int inputLength, boolean skipComment) { - super(input, inputLength, skipComment); - } + static { + Map map = new HashMap(); + map.put("EXISTS", Token.EXISTS); + map.put("THEN", Token.THEN); + map.put("AS", Token.AS); + map.put("GROUP", Token.GROUP); + map.put("BY", Token.BY); + map.put("HAVING", Token.HAVING); + map.put("DELETE", Token.DELETE); + map.put("ORDER", Token.ORDER); + map.put("INDEX", Token.INDEX); + map.put("FOR", Token.FOR); + map.put("SCHEMA", Token.SCHEMA); + map.put("FOREIGN", Token.FOREIGN); + map.put("REFERENCE", Token.REFERENCE); + map.put("REFERENCES", Token.REFERENCES); + map.put("CHECK", Token.CHECK); + map.put("PRIMARY", Token.PRIMARY); + map.put("KEY", Token.KEY); + map.put("CONSTRAINT", Token.CONSTRAINT); + map.put("DEFAULT", Token.DEFAULT); + map.put("VIEW", Token.VIEW); + map.put("CREATE", Token.CREATE); + map.put("VALUES", Token.VALUES); + map.put("ALTER", Token.ALTER); + map.put("TABLE", Token.TABLE); + map.put("DROP", Token.DROP); + map.put("SET", Token.SET); + map.put("INTO", Token.INTO); + map.put("UPDATE", Token.UPDATE); + map.put("NULL", Token.NULL); + map.put("IS", Token.IS); + map.put("NOT", Token.NOT); + map.put("SELECT", Token.SELECT); + map.put("INSERT", Token.INSERT); + map.put("FROM", Token.FROM); + map.put("WHERE", Token.WHERE); + map.put("AND", Token.AND); + map.put("OR", Token.OR); + map.put("XOR", Token.XOR); + map.put("DISTINCT", Token.DISTINCT); + map.put("UNIQUE", Token.UNIQUE); + map.put("ALL", Token.ALL); + map.put("UNION", Token.UNION); + map.put("INTERSECT", Token.INTERSECT); + map.put("MINUS", Token.MINUS); + map.put("INNER", Token.INNER); + map.put("LEFT", Token.LEFT); + map.put("RIGHT", Token.RIGHT); + map.put("FULL", Token.FULL); + map.put("ON", Token.ON); + map.put("OUTER", Token.OUTER); + map.put("JOIN", Token.JOIN); + map.put("NEW", Token.NEW); + map.put("CASE", Token.CASE); + map.put("WHEN", Token.WHEN); + map.put("END", Token.END); + map.put("WHEN", Token.WHEN); + map.put("ELSE", Token.ELSE); + map.put("EXISTS", Token.EXISTS); + map.put("CAST", Token.CAST); + map.put("IN", Token.IN); + map.put("ASC", Token.ASC); + map.put("DESC", Token.DESC); + map.put("LIKE", Token.LIKE); + map.put("ESCAPE", Token.ESCAPE); + map.put("BETWEEN", Token.BETWEEN); + map.put("INTERVAL", Token.INTERVAL); + map.put("LOCK", Token.LOCK); + map.put("SOME", Token.SOME); + map.put("ANY", Token.ANY); + map.put("WITH", Token.WITH); + map.put("CURSOR", Token.CURSOR); + map.put("TOP", Token.TOP); + + DEFAULT_SQL_SERVER_KEYWORDS = new Keywords(map); + } + + public HiveLexer(char[] input, int inputLength, boolean skipComment){ + super(input, inputLength, skipComment); + super.keywods = DEFAULT_SQL_SERVER_KEYWORDS; + } + + public HiveLexer(String input) { + super(input); + super.keywods = DEFAULT_SQL_SERVER_KEYWORDS; + } public void scanComment() { if (ch != '/') { 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 new file mode 100644 index 0000000000..15b411cff0 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveStatementParser.java @@ -0,0 +1,18 @@ +package com.alibaba.druid.sql.dialect.hive.parser; + +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.SQLStatementParser; + + +public class HiveStatementParser extends SQLStatementParser { + + public HiveStatementParser(Lexer lexer){ + super(lexer); + } + + public HiveStatementParser(String sql){ + super(new HiveLexer(sql)); + this.lexer.nextToken(); + } + +} 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 new file mode 100644 index 0000000000..c1d391ecb3 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitor.java @@ -0,0 +1,11 @@ +package com.alibaba.druid.sql.dialect.hive.visitor; + +import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveCreateTableStatement; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public interface HiveASTVisitor extends SQLASTVisitor { + + void endVisit(HiveCreateTableStatement x); + + boolean visit(HiveCreateTableStatement 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 new file mode 100644 index 0000000000..1aa4653e89 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveASTVisitorAdapter.java @@ -0,0 +1,19 @@ +package com.alibaba.druid.sql.dialect.hive.visitor; + +import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveCreateTableStatement; +import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; + + +public class HiveASTVisitorAdapter extends SQLASTVisitorAdapter implements HiveASTVisitor { + + @Override + public void endVisit(HiveCreateTableStatement x) { + + } + + @Override + public boolean visit(HiveCreateTableStatement x) { + return true; + } + +} 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 new file mode 100644 index 0000000000..674ed2fe35 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveOutputVisitor.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.sql.dialect.hive.visitor; + +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveCreateTableStatement; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; + +public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVisitor { + + public HiveOutputVisitor(Appendable appender){ + super(appender); + } + + @Override + public void endVisit(HiveCreateTableStatement x) { + + } + + @Override + public boolean visit(HiveCreateTableStatement x) { + visit((SQLCreateTableStatement) x); + return false; + } + +} 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 new file mode 100644 index 0000000000..4ee83e710c --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/hive/visitor/HiveSchemaStatVisitor.java @@ -0,0 +1,18 @@ +package com.alibaba.druid.sql.dialect.hive.visitor; + +import com.alibaba.druid.sql.dialect.hive.ast.stmt.HiveCreateTableStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; + +public class HiveSchemaStatVisitor extends SchemaStatVisitor implements HiveASTVisitor { + + @Override + public void endVisit(HiveCreateTableStatement x) { + + } + + @Override + public boolean visit(HiveCreateTableStatement x) { + return false; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index 523657f617..0b9e5dccf8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -15,17 +15,8 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.parser; -import java.util.List; - -import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OraclePLSQLCommitStatement; -import com.alibaba.druid.sql.dialect.oracle.parser.OracleDeleteParser; -import com.alibaba.druid.sql.dialect.oracle.parser.OracleSelectParser; import com.alibaba.druid.sql.parser.Lexer; -import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLStatementParser; -import com.alibaba.druid.sql.parser.Token; public class SQLServerStatementParser extends SQLStatementParser { @@ -38,78 +29,4 @@ public class SQLServerStatementParser extends SQLStatementParser { super(lexer); } - @Override - public void parseStatementList(List statementList) throws ParserException { - for (;;) { - if (lexer.token() == Token.EOF) { - return; - } - - if (lexer.token() == (Token.SEMI)) { - lexer.nextToken(); - continue; - } - - if (lexer.token() == (Token.SELECT)) { - statementList.add(new SQLSelectStatement(new SQLServerSelectParser(this.lexer).select())); - continue; - } - - if (lexer.token() == (Token.UPDATE)) { - statementList.add(parseUpdateStatement()); - continue; - } - - if (lexer.token() == (Token.CREATE)) { - lexer.nextToken(); - - // if ((this.tokenList.lookup(1).equals(Token.ViewToken)) || - // (this.tokenList.lookup(3).equals(Token.ViewToken)) - // || (this.tokenList.lookup(4).equals(Token.ViewToken)) || - // (this.tokenList.lookup(5).equals(Token.ViewToken))) { - // statementList.add(parseCreateView()); - // } - // - // if ((this.tokenList.lookup(1).equals(Token.TableToken)) || - // (this.tokenList.lookup(3).equals(Token.TableToken))) { - // statementList.add(parseOracleCreateTable()); - // } - - throw new ParserException("TODO"); - } - - if (lexer.token() == Token.INSERT) { - statementList.add(parseInsert()); - continue; - } - - if (lexer.token() == (Token.DELETE)) { - statementList.add(new OracleDeleteParser(this.lexer).parseDelete()); - continue; - } - - if (lexer.token() == (Token.SLASH)) { - lexer.nextToken(); - statementList.add(new OraclePLSQLCommitStatement()); - continue; - } - - if (lexer.token() == Token.ALTER) { - throw new ParserException("TODO"); - } - - if (lexer.token() == Token.WITH) { - statementList.add(new SQLSelectStatement(new OracleSelectParser(this.lexer).select())); - continue; - } - - if (identifierEquals("CALL")) { - statementList.add(this.parseCall()); - continue; - } - - throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); - } - } - } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 2abe018b34..bf2e016705 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -20,6 +20,8 @@ import com.alibaba.druid.sql.ast.expr.SQLInSubQueryExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -32,6 +34,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.stat.TableStat; @@ -149,7 +152,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { case IsNot: handleCondition(x.getLeft(), x.getOperator().name); handleCondition(x.getRight(), x.getOperator().name); - + handleRelationship(x.getLeft(), x.getOperator().name, x.getRight()); break; default: @@ -163,17 +166,17 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (leftColumn == null) { return; } - + Column rightColumn = getColumn(right); if (rightColumn == null) { return; } - + Relationship relationship = new Relationship(); relationship.setLeft(leftColumn); relationship.setRight(rightColumn); relationship.setOperator(operator); - + this.relationships.add(relationship); } @@ -182,7 +185,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (column == null) { return; } - + Condition condition = new Condition(); condition.setColumn(column); condition.setOperator(operator); @@ -209,7 +212,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (table != null) { return new Column(table, column); } - + return handleSubQueryColumn(tableName, column); } @@ -229,7 +232,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return new Column(table, column); } } - + return null; } @@ -660,4 +663,35 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public void endVisit(SQLUpdateStatement x) { aliasLocal.set(null); } + + public boolean visit(SQLCreateTableStatement x) { + for (SQLTableElement e : x.getTableElementList()) { + e.setParent(x); + } + + String tableName = x.getName().toString(); + TableStat stat = new TableStat(); + stat.incrementCreateCount(); + tableStats.put(new TableStat.Name(tableName), stat); + return true; + } + + public boolean visit(SQLColumnDefinition x) { + String tableName = null; + { + SQLObject parent = x.getParent(); + if (parent instanceof SQLCreateTableStatement) { + tableName = ((SQLCreateTableStatement) parent).getName().toString(); + } + } + + if (tableName == null) { + return true; + } + + String columnName = x.getName().toString(); + columns.add(new Column(tableName, columnName)); + + return true; + } } diff --git a/src/main/java/com/alibaba/druid/stat/TableStat.java b/src/main/java/com/alibaba/druid/stat/TableStat.java index 25c7ade638..74a7f0e815 100644 --- a/src/main/java/com/alibaba/druid/stat/TableStat.java +++ b/src/main/java/com/alibaba/druid/stat/TableStat.java @@ -23,6 +23,15 @@ public class TableStat { int insertCount = 0; int dropCount = 0; int mergeCount = 0; + int createCount = 0; + + public int getCreateCount() { + return createCount; + } + + public void incrementCreateCount() { + this.createCount++; + } public int getMergeCount() { return mergeCount; @@ -112,6 +121,9 @@ public class TableStat { if (dropCount > 0) { buf.append("Drop"); } + if (createCount > 0) { + buf.append("Create"); + } return buf.toString(); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveCreateTableTest.java b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveCreateTableTest.java new file mode 100644 index 0000000000..e6975c453e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveCreateTableTest.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.sql.hive; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.hive.parser.HiveStatementParser; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveSchemaStatVisitor; +import com.alibaba.druid.sql.hive.HiveTest; +import com.alibaba.druid.stat.TableStat; + +public class HiveCreateTableTest extends HiveTest { + + public void test_hive() throws Exception { + String sql = "CREATE TABLE pokes (foo INT, bar STRING);"; + + HiveStatementParser parser = new HiveStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + HiveSchemaStatVisitor visitor = new HiveSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("pokes"))); + + Assert.assertEquals(2, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pokes", "foo"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("pokes", "bar"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest.java b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest.java new file mode 100644 index 0000000000..7511ee8393 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest.java @@ -0,0 +1,38 @@ +package com.alibaba.druid.bvt.sql.hive; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.hive.parser.HiveStatementParser; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveSchemaStatVisitor; +import com.alibaba.druid.sql.hive.HiveTest; +import com.alibaba.druid.stat.TableStat; + +public class HiveSelectTest extends HiveTest { + + public void test_hive() throws Exception { + String sql = "SELECT COUNT(*) FROM u_data;"; + + HiveStatementParser parser = new HiveStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + HiveSchemaStatVisitor visitor = new HiveSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("u_data"))); + + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("u_data", "*"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest2.java new file mode 100644 index 0000000000..f17225f4e7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/hive/HiveSelectTest2.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.sql.hive; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.hive.parser.HiveStatementParser; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveSchemaStatVisitor; +import com.alibaba.druid.sql.hive.HiveTest; +import com.alibaba.druid.stat.TableStat; + +public class HiveSelectTest2 extends HiveTest { + + public void test_hive() throws Exception { + String sql = "SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';"; + + HiveStatementParser parser = new HiveStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + System.out.println(output(statementList)); + + Assert.assertEquals(1, statementList.size()); + + HiveSchemaStatVisitor visitor = new HiveSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("invites"))); + + Assert.assertEquals(2, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("invites", "foo"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("invites", "ds"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java index 22a763cb3f..6eef316472 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest2.java @@ -49,7 +49,7 @@ public class OracleSelectTest2 extends OracleTest { Assert.assertEquals(4, visitor.getColumns().size()); - // Assert.assertTrue(visitor.getFields().contains(new TableStat.Column("films", "producer_id"))); + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("films", "producer_id"))); } } diff --git a/src/test/java/com/alibaba/druid/sql/hive/HiveTest.java b/src/test/java/com/alibaba/druid/sql/hive/HiveTest.java new file mode 100644 index 0000000000..9e7cc8fe99 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/hive/HiveTest.java @@ -0,0 +1,22 @@ +package com.alibaba.druid.sql.hive; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.hive.visitor.HiveOutputVisitor; + +public class HiveTest extends TestCase { + + protected String output(List stmtList) { + StringBuilder out = new StringBuilder(); + HiveOutputVisitor visitor = new HiveOutputVisitor(out); + + for (SQLStatement stmt : stmtList) { + stmt.accept(visitor); + } + + return out.toString(); + } +}