From f4d331073426d8a42940045f44e24728be7a50d9 Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 9 Oct 2017 15:47:16 +0800 Subject: [PATCH] refactor sql parser. improved db2 sql support. bug fixed for issue #2033 --- .../alibaba/druid/sql/ast/SQLPartitionBy.java | 17 +- .../druid/sql/ast/SQLPartitionByHash.java | 24 +-- .../druid/sql/ast/SQLPartitionByList.java | 36 +--- .../druid/sql/ast/SQLPartitionByRange.java | 37 +--- .../statement/SQLCreateTableStatement.java | 47 ++++- .../sql/dialect/db2/ast/DB2Statement.java | 21 +++ .../db2/ast/stmt/DB2CreateTableStatement.java | 63 +++++++ .../db2/parser/DB2CreateTableParser.java | 177 ++++++++++++++++++ .../db2/parser/DB2StatementParser.java | 9 +- .../dialect/db2/visitor/DB2ASTVisitor.java | 4 + .../db2/visitor/DB2ASTVisitorAdapter.java | 11 ++ .../visitor/DB2ExportParameterVisitor.java | 5 + .../dialect/db2/visitor/DB2OutputVisitor.java | 42 ++++- .../db2/visitor/DB2SchemaStatVisitor.java | 13 +- .../statement/MySqlCreateTableStatement.java | 10 - .../ast/statement/MySqlPartitionByKey.java | 18 +- .../mysql/parser/MySqlCreateTableParser.java | 6 +- .../visitor/transform/NameResolveVisitor.java | 3 +- .../ast/stmt/OracleCreateTableStatement.java | 39 +--- .../parser/OracleCreateTableParser.java | 2 +- .../oracle/parser/OracleExprParser.java | 2 +- .../sql/parser/SQLCreateTableParser.java | 9 - .../sql/visitor/SQLASTOutputVisitor.java | 10 +- .../java/com/alibaba/druid/util/FnvHash.java | 2 + .../bvt/sql/SQLSelectQueryBlockTest.java | 64 +++++++ .../bvt/sql/db2/DB2CreateTableTest_01.java | 98 ++++++++++ 26 files changed, 583 insertions(+), 186 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Statement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2CreateTableStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2CreateTableParser.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/SQLSelectQueryBlockTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_01.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionBy.java b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionBy.java index 200933c5bb..8e5a5be44c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionBy.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionBy.java @@ -19,16 +19,12 @@ import java.util.ArrayList; import java.util.List; public abstract class SQLPartitionBy extends SQLObjectImpl { - protected SQLSubPartitionBy subPartitionBy; - protected SQLExpr partitionsCount; - protected boolean linear; - protected List partitions = new ArrayList(); - protected List storeIn = new ArrayList(); + protected List columns = new ArrayList(); public List getPartitions() { return partitions; @@ -75,6 +71,17 @@ public abstract class SQLPartitionBy extends SQLObjectImpl { return storeIn; } + public List getColumns() { + return columns; + } + + public void addColumn(SQLExpr column) { + if (column != null) { + column.setParent(this); + } + this.columns.add(column); + } + public void cloneTo(SQLPartitionBy x) { if (subPartitionBy != null) { x.setSubPartitionBy(subPartitionBy.clone()); diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByHash.java b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByHash.java index 2e72ab5ca3..c0d9a16e16 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByHash.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByHash.java @@ -19,22 +19,9 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLPartitionByHash extends SQLPartitionBy { - protected SQLExpr expr; - // for aliyun ads protected boolean key; - public SQLExpr getExpr() { - return expr; - } - - public void setExpr(SQLExpr expr) { - if (expr != null) { - expr.setParent(this); - } - this.expr = expr; - } - public boolean isKey() { return key; } @@ -46,7 +33,6 @@ public class SQLPartitionByHash extends SQLPartitionBy { @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { - acceptChild(visitor, expr); acceptChild(visitor, partitionsCount); acceptChild(visitor, getPartitions()); acceptChild(visitor, subPartitionBy); @@ -57,12 +43,14 @@ public class SQLPartitionByHash extends SQLPartitionBy { public SQLPartitionByHash clone() { SQLPartitionByHash x = new SQLPartitionByHash(); - if (expr != null) { - x.setExpr(expr.clone()); - } - x.key = key; + for (SQLExpr column : columns) { + SQLExpr c2 = column.clone(); + c2.setParent(x); + x.columns.add(c2); + } + return x; } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java index d71f00d7e5..e62fc8461e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java @@ -21,15 +21,9 @@ import java.util.List; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLPartitionByList extends SQLPartitionBy { - - protected SQLExpr expr; - - protected List columns = new ArrayList(); - @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { - acceptChild(visitor, expr); acceptChild(visitor, columns); acceptChild(visitor, partitionsCount); acceptChild(visitor, getPartitions()); @@ -38,37 +32,11 @@ public class SQLPartitionByList extends SQLPartitionBy { visitor.endVisit(this); } - public SQLExpr getExpr() { - return expr; - } - - public void setExpr(SQLExpr expr) { - if (expr != null) { - expr.setParent(this); - } - this.expr = expr; - } - - public List getColumns() { - return columns; - } - - public void addColumn(SQLName column) { - if (column != null) { - column.setParent(this); - } - this.columns.add(column); - } - public SQLPartitionByList clone() { SQLPartitionByList x = new SQLPartitionByList(); - if (expr != null) { - x.setExpr(expr.clone()); - } - - for (SQLName column : columns) { - SQLName c2 = column.clone(); + for (SQLExpr column : columns) { + SQLExpr c2 = column.clone(); c2.setParent(x); x.columns.add(c2); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByRange.java b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByRange.java index ce5043d8f7..8a5609b836 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByRange.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByRange.java @@ -21,29 +21,12 @@ import java.util.List; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLPartitionByRange extends SQLPartitionBy { - - protected List columns = new ArrayList(); - protected SQLExpr interval; - // mysql - protected SQLExpr expr; - public SQLPartitionByRange() { } - public List getColumns() { - return columns; - } - - public void addColumn(SQLName column) { - if (column != null) { - column.setParent(this); - } - this.columns.add(column); - } - public SQLExpr getInterval() { return interval; } @@ -56,22 +39,10 @@ public class SQLPartitionByRange extends SQLPartitionBy { this.interval = interval; } - public SQLExpr getExpr() { - return expr; - } - - public void setExpr(SQLExpr expr) { - if (expr != null) { - expr.setParent(this); - } - this.expr = expr; - } - @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, columns); - acceptChild(visitor, expr); acceptChild(visitor, interval); acceptChild(visitor, storeIn); acceptChild(visitor, partitions); @@ -82,16 +53,12 @@ public class SQLPartitionByRange extends SQLPartitionBy { public SQLPartitionByRange clone() { SQLPartitionByRange x = new SQLPartitionByRange(); - if (expr != null) { - x.setExpr(expr.clone()); - } - if (interval != null) { x.setInterval(interval.clone()); } - for (SQLName column : columns) { - SQLName c2 = column.clone(); + for (SQLExpr column : columns) { + SQLExpr c2 = column.clone(); c2.setParent(x); x.columns.add(c2); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index 3b80811f6b..3cd055fa74 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -39,15 +39,19 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS protected List tableElementList = new ArrayList(); // for postgresql - private SQLExprTableSource inherits; + protected SQLExprTableSource inherits; protected SQLSelect select; protected SQLExpr comment; - protected SQLExprTableSource like; + protected SQLExprTableSource like; + protected Boolean compress; + protected Boolean logging; + protected SQLName tablespace; + protected SQLPartitionBy partitioning; public SQLCreateTableStatement(){ @@ -176,6 +180,45 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS this.like = like; } + public Boolean getCompress() { + return compress; + } + + public void setCompress(Boolean compress) { + this.compress = compress; + } + + public Boolean getLogging() { + return logging; + } + + public void setLogging(Boolean logging) { + this.logging = logging; + } + + public SQLName getTablespace() { + return tablespace; + } + + public void setTablespace(SQLName tablespace) { + if (tablespace != null) { + tablespace.setParent(this); + } + this.tablespace = tablespace; + } + + public SQLPartitionBy getPartitioning() { + return partitioning; + } + + public void setPartitioning(SQLPartitionBy partitioning) { + if (partitioning != null) { + partitioning.setParent(this); + } + + this.partitioning = partitioning; + } + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Statement.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Statement.java new file mode 100644 index 0000000000..5c18f19a74 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Statement.java @@ -0,0 +1,21 @@ +/* + * 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.db2.ast; + +import com.alibaba.druid.sql.ast.SQLStatement; + +public interface DB2Statement extends SQLStatement, DB2Object { +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2CreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2CreateTableStatement.java new file mode 100644 index 0000000000..0e23b91830 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2CreateTableStatement.java @@ -0,0 +1,63 @@ +/* + * 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.db2.ast.stmt; + +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.dialect.db2.ast.DB2Statement; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class DB2CreateTableStatement extends SQLCreateTableStatement implements DB2Statement { + private boolean dataCaptureNone; + private boolean dataCaptureChanges; + + public boolean isDataCaptureNone() { + return dataCaptureNone; + } + + public void setDataCaptureNone(boolean dataCaptureNone) { + this.dataCaptureNone = dataCaptureNone; + } + + public boolean isDataCaptureChanges() { + return dataCaptureChanges; + } + + public void setDataCaptureChanges(boolean dataCaptureChanges) { + this.dataCaptureChanges = dataCaptureChanges; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof DB2ASTVisitor) { + accept0((DB2ASTVisitor) visitor); + return; + } + + super.accept0(visitor); + } + + @Override + public void accept0(DB2ASTVisitor visitor) { + if (visitor.visit(this)) { + this.acceptChild(visitor, tableSource); + this.acceptChild(visitor, tableElementList); + this.acceptChild(visitor, inherits); + this.acceptChild(visitor, select); + } + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2CreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2CreateTableParser.java new file mode 100644 index 0000000000..cd935255ef --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2CreateTableParser.java @@ -0,0 +1,177 @@ +/* + * 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.db2.parser; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLPartitionBy; +import com.alibaba.druid.sql.ast.SQLPartitionByHash; +import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; +import com.alibaba.druid.sql.parser.ParserException; +import com.alibaba.druid.sql.parser.SQLCreateTableParser; +import com.alibaba.druid.sql.parser.SQLExprParser; +import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.util.FnvHash; +import com.alibaba.druid.util.JdbcConstants; + +public class DB2CreateTableParser extends SQLCreateTableParser { + public DB2CreateTableParser(String sql) { + super(new DB2ExprParser(sql)); + } + + public DB2CreateTableParser(SQLExprParser exprParser) { + super(exprParser); + } + + public SQLCreateTableStatement parseCreateTable(boolean acceptCreate) { + DB2CreateTableStatement createTable = newCreateStatement(); + + if (acceptCreate) { + if (lexer.hasComment() && lexer.isKeepComments()) { + createTable.addBeforeComment(lexer.readAndResetComments()); + } + + accept(Token.CREATE); + } + + if (lexer.identifierEquals("GLOBAL")) { + lexer.nextToken(); + + if (lexer.identifierEquals("TEMPORARY")) { + lexer.nextToken(); + createTable.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY); + } else { + throw new ParserException("syntax error " + lexer.info()); + } + } else if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("LOCAL")) { + lexer.nextToken(); + if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("TEMPORAY")) { + lexer.nextToken(); + createTable.setType(SQLCreateTableStatement.Type.LOCAL_TEMPORARY); + } else { + throw new ParserException("syntax error. " + lexer.info()); + } + } + + accept(Token.TABLE); + + createTable.setName(this.exprParser.name()); + + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + for (; ; ) { + Token token = lexer.token(); + if (token == Token.IDENTIFIER + && lexer.stringVal().equalsIgnoreCase("SUPPLEMENTAL") + && JdbcConstants.ORACLE.equals(dbType)) { + this.parseCreateTableSupplementalLogingProps(createTable); + } else if (token == Token.IDENTIFIER // + || token == Token.LITERAL_ALIAS) { + SQLColumnDefinition column = this.exprParser.parseColumn(); + createTable.getTableElementList().add(column); + } else if (token == Token.PRIMARY // + || token == Token.UNIQUE // + || token == Token.CHECK // + || token == Token.CONSTRAINT + || token == Token.FOREIGN) { + SQLConstraint constraint = this.exprParser.parseConstaint(); + constraint.setParent(createTable); + createTable.getTableElementList().add((SQLTableElement) constraint); + } else if (token == Token.TABLESPACE) { + throw new ParserException("TODO " + lexer.info()); + } else { + SQLColumnDefinition column = this.exprParser.parseColumn(); + createTable.getTableElementList().add(column); + } + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + + if (lexer.token() == Token.RPAREN) { // compatible for sql server + break; + } + continue; + } + + break; + } + + accept(Token.RPAREN); + + if (lexer.identifierEquals("INHERITS")) { + lexer.nextToken(); + accept(Token.LPAREN); + SQLName inherits = this.exprParser.name(); + createTable.setInherits(new SQLExprTableSource(inherits)); + accept(Token.RPAREN); + } + } + + if (lexer.token() == Token.AS) { + lexer.nextToken(); + SQLSelect select = this.createSQLSelectParser().select(); + createTable.setSelect(select); + } + + for (;;) { + if (lexer.identifierEquals(FnvHash.Constants.DATA)) { + lexer.nextToken(); + acceptIdentifier("CAPTURE"); + + if (lexer.identifierEquals(FnvHash.Constants.NONE)) { + lexer.nextToken(); + createTable.setDataCaptureNone(true); + continue; + } + + throw new ParserException("TODO " + lexer.info()); + } else if (lexer.token() == Token.IN) { + lexer.nextToken(); + + if (lexer.token() == Token.DATABASE) { + throw new ParserException("TODO " + lexer.info()); + } else if (lexer.identifierEquals("tablespace")) { + throw new ParserException("TODO " + lexer.info()); + } else { + SQLName tablespace = this.exprParser.name(); + createTable.setTablespace(tablespace); + } + + continue; + } else if (lexer.identifierEquals(FnvHash.Constants.PARTITIONING)) { + SQLPartitionByHash partitionBy = new SQLPartitionByHash(); + + lexer.nextToken(); + accept(Token.KEY); + accept(Token.LPAREN); + this.exprParser.exprList(partitionBy.getColumns(), partitionBy); + accept(Token.RPAREN); + accept(Token.USING); + acceptIdentifier("HASHING"); + createTable.setPartitioning(partitionBy); + continue; + } + break; + } + + return createTable; + } + + protected DB2CreateTableStatement newCreateStatement() { + return new DB2CreateTableStatement(); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java index cd987d37c4..701539d231 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java @@ -19,10 +19,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement; -import com.alibaba.druid.sql.parser.Lexer; -import com.alibaba.druid.sql.parser.SQLParserFeature; -import com.alibaba.druid.sql.parser.SQLStatementParser; -import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.parser.*; public class DB2StatementParser extends SQLStatementParser { @@ -53,4 +50,8 @@ public class DB2StatementParser extends SQLStatementParser { return false; } + + public SQLCreateTableParser getSQLCreateTableParser() { + return new DB2CreateTableParser(this.exprParser); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java index 4f471f9c13..2f4cbd4e38 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -28,4 +29,7 @@ public interface DB2ASTVisitor extends SQLASTVisitor { boolean visit(DB2ValuesStatement x); void endVisit(DB2ValuesStatement x); + + boolean visit(DB2CreateTableStatement x); + void endVisit(DB2CreateTableStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java index 7e1322feed..bb861f401a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; @@ -41,4 +42,14 @@ public class DB2ASTVisitorAdapter extends SQLASTVisitorAdapter implements DB2AST } + @Override + public boolean visit(DB2CreateTableStatement x) { + return false; + } + + @Override + public void endVisit(DB2CreateTableStatement x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java index bb974025fc..514719180c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; @@ -120,4 +121,8 @@ public class DB2ExportParameterVisitor extends DB2OutputVisitor implements Expor return true; } + @Override + public void endVisit(DB2CreateTableStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java index b21cc58c78..4025975a0e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -15,11 +15,12 @@ */ package com.alibaba.druid.sql.dialect.db2.visitor; -import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLPartitionBy; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; @@ -77,7 +78,40 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit public void endVisit(DB2ValuesStatement x) { } - + + @Override + public boolean visit(DB2CreateTableStatement x) { + printCreateTable(x, true); + + if (x.isDataCaptureNone()) { + println(); + print("DATA CAPTURE NONE"); + } else if (x.isDataCaptureChanges()) { + println(); + print("DATA CAPTURE CHANGES"); + } + + SQLName tablespace = x.getTablespace(); + if (tablespace != null) { + println(); + print("IN "); + tablespace.accept(this); + } + + SQLPartitionBy partitionBy = x.getPartitioning(); + if (partitionBy != null) { + println(); + partitionBy.accept(this); + } + + return false; + } + + @Override + public void endVisit(DB2CreateTableStatement x) { + + } + protected void printOperator(SQLBinaryOperator operator) { if (operator == SQLBinaryOperator.Concat) { print0(ucase ? "CONCAT" : "concat"); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java index daecb927c6..12568e1c13 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java @@ -15,12 +15,13 @@ */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.util.JdbcConstants; -import com.alibaba.druid.util.JdbcUtils; public class DB2SchemaStatVisitor extends SchemaStatVisitor implements DB2ASTVisitor { public DB2SchemaStatVisitor() { @@ -46,4 +47,14 @@ public class DB2SchemaStatVisitor extends SchemaStatVisitor implements DB2ASTVis public void endVisit(DB2ValuesStatement x) { } + + @Override + public boolean visit(DB2CreateTableStatement x) { + return visit((SQLCreateTableStatement) x); + } + + @Override + public void endVisit(DB2CreateTableStatement x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java index cc9bba6716..a5d03878a3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlCreateTableStatement.java @@ -42,8 +42,6 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement private Map tableOptions = new LinkedHashMap(); - private SQLPartitionBy partitioning; - private List hints = new ArrayList(); private List optionHints = new ArrayList(); @@ -70,14 +68,6 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement this.tableOptions = tableOptions; } - public SQLPartitionBy getPartitioning() { - return partitioning; - } - - public void setPartitioning(SQLPartitionBy partitioning) { - this.partitioning = partitioning; - } - public Map getTableOptions() { return tableOptions; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlPartitionByKey.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlPartitionByKey.java index 247f0efcb8..04fb42269d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlPartitionByKey.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlPartitionByKey.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.mysql.ast.statement; import java.util.ArrayList; import java.util.List; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLPartitionBy; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject; @@ -26,8 +27,6 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class MySqlPartitionByKey extends SQLPartitionBy implements MySqlObject { - private List columns = new ArrayList(); - @Override protected void accept0(SQLASTVisitor visitor) { if (visitor instanceof MySqlASTVisitor) { @@ -48,21 +47,10 @@ public class MySqlPartitionByKey extends SQLPartitionBy implements MySqlObject { visitor.endVisit(this); } - public List getColumns() { - return columns; - } - - public void addColumn(SQLName column) { - if (column != null) { - column.setParent(this); - } - this.columns.add(column); - } - public void cloneTo(MySqlPartitionByKey x) { super.cloneTo(x); - for (SQLName column : columns) { - SQLName c2 = column.clone(); + for (SQLExpr column : columns) { + SQLExpr c2 = column.clone(); c2.setParent(x); x.columns.add(c2); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index 1203aab0cc..a1550de8cb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -483,7 +483,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { } accept(Token.LPAREN); - clause.setExpr(this.exprParser.expr()); + this.exprParser.exprList(clause.getColumns(), clause); accept(Token.RPAREN); partitionClause = clause; @@ -501,7 +501,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); - clause.setExpr(this.exprParser.expr()); + clause.addColumn(this.exprParser.expr()); accept(Token.RPAREN); } else { acceptIdentifier("COLUMNS"); @@ -576,7 +576,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser { if (lexer.token() == Token.LPAREN) { lexer.nextToken(); - clause.setExpr(this.exprParser.expr()); + clause.addColumn(this.exprParser.expr()); accept(Token.RPAREN); } else { acceptIdentifier("COLUMNS"); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/NameResolveVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/NameResolveVisitor.java index 2b8a2cb2ee..55bbae35f5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/NameResolveVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/transform/NameResolveVisitor.java @@ -51,7 +51,8 @@ public class NameResolveVisitor extends OracleASTVisitorAdapter { SQLTableSource tableSource = null; if (hash == FnvHash.Constants.LEVEL - || hash == FnvHash.Constants.CONNECT_BY_ISCYCLE) { + || hash == FnvHash.Constants.CONNECT_BY_ISCYCLE + || hash == FnvHash.Constants.SYSTIMESTAMP) { return false; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java index 6f66b815c3..6df459deee 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleCreateTableStatement.java @@ -36,8 +36,6 @@ import java.util.List; public class OracleCreateTableStatement extends SQLCreateTableStatement implements OracleDDLStatement, OracleSegmentAttributes { - private SQLName tablespace; - private boolean inMemoryMetadata; private boolean cursorSpecificSegment; @@ -54,8 +52,7 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen private Integer maxtrans; private Integer pctincrease; - private Boolean logging; - private Boolean compress; + private Integer compressLevel; private boolean compressForOltp; @@ -64,8 +61,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen private Boolean cache; - private SQLPartitionBy partitioning; - private DeferredSegmentCreation deferredSegmentCreation; private Boolean enableRowMovement; @@ -122,14 +117,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.deferredSegmentCreation = deferredSegmentCreation; } - public SQLPartitionBy getPartitioning() { - return partitioning; - } - - public void setPartitioning(SQLPartitionBy partitioning) { - this.partitioning = partitioning; - } - public Boolean getCache() { return cache; } @@ -154,22 +141,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.onCommitDeleteRows = onCommitDeleteRows; } - public Boolean getLogging() { - return logging; - } - - public void setLogging(Boolean logging) { - this.logging = logging; - } - - public Boolean getCompress() { - return compress; - } - - public void setCompress(Boolean compress) { - this.compress = compress; - } - public Integer getCompressLevel() { return compressLevel; } @@ -242,14 +213,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen this.inMemoryMetadata = inMemoryMetadata; } - public SQLName getTablespace() { - return tablespace; - } - - public void setTablespace(SQLName tablespace) { - this.tablespace = tablespace; - } - protected void accept0(SQLASTVisitor visitor) { accept0((OracleASTVisitor) visitor); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java index 344d2c57ff..92385a83ed 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleCreateTableParser.java @@ -333,7 +333,7 @@ public class OracleCreateTableParser extends SQLCreateTableParser { SQLPartitionByList partitionByList = new SQLPartitionByList(); accept(Token.LPAREN); - partitionByList.setExpr(this.exprParser.expr()); + partitionByList.addColumn(this.exprParser.expr()); accept(Token.RPAREN); this.getExprParser().parsePartitionByRest(partitionByList); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index b74b9fb2a6..bec1f8e824 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -1731,7 +1731,7 @@ public class OracleExprParser extends SQLExprParser { } accept(Token.LPAREN); - partitionByHash.setExpr(this.expr()); + this.exprList(partitionByHash.getColumns(), partitionByHash); accept(Token.RPAREN); return partitionByHash; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java index 45824c1668..ba962c5af2 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java @@ -119,15 +119,6 @@ public class SQLCreateTableParser extends SQLDDLParser { break; } - // while - // (this.tokenList.current().equals(OracleToken.ConstraintToken)) { - // parseConstaint(table.getConstraints()); - // - // if (this.tokenList.current().equals(OracleToken.CommaToken)) - // ; - // lexer.nextToken(); - // } - accept(Token.RPAREN); if (lexer.identifierEquals("INHERITS")) { 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 c2b7a0161f..8cf9e6b704 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -4530,9 +4530,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet @Override public boolean visit(SQLPartitionByRange x) { print0(ucase ? "PARTITION BY RANGE" : "partition by range"); - if (x.getExpr() != null) { + if (x.getColumns().size() == 1) { print0(" ("); - x.getExpr().accept(this); + x.getColumns().get(0).accept(this); print(')'); } else { if (JdbcConstants.MYSQL.equals(getDbType())) { @@ -4572,9 +4572,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet @Override public boolean visit(SQLPartitionByList x) { print0(ucase ? "PARTITION BY LIST " : "partition by list "); - if (x.getExpr() != null) { + if (x.getColumns().size() == 1) { print('('); - x.getExpr().accept(this); + x.getColumns().get(0).accept(this); print0(")"); } else { print0(ucase ? "COLUMNS (" : "columns ("); @@ -4601,7 +4601,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } print('('); - x.getExpr().accept(this); + printAndAccept(x.getColumns(), ", "); print(')'); printPartitionsCountAndSubPartitions(x); diff --git a/src/main/java/com/alibaba/druid/util/FnvHash.java b/src/main/java/com/alibaba/druid/util/FnvHash.java index 98fc4da657..4162f56e62 100644 --- a/src/main/java/com/alibaba/druid/util/FnvHash.java +++ b/src/main/java/com/alibaba/druid/util/FnvHash.java @@ -510,5 +510,7 @@ public final class FnvHash { long NUMTODSINTERVAL = fnv1a_64_lower("NUMTODSINTERVAL"); long LATERAL = fnv1a_64_lower("LATERAL"); + long NONE = fnv1a_64_lower("NONE"); + long PARTITIONING = fnv1a_64_lower("PARTITIONING"); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectQueryBlockTest.java b/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectQueryBlockTest.java new file mode 100644 index 0000000000..8946ee50e2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/SQLSelectQueryBlockTest.java @@ -0,0 +1,64 @@ +package com.alibaba.druid.bvt.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.repository.SchemaRepository; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class SQLSelectQueryBlockTest extends TestCase { + private final String dbType = JdbcConstants.MYSQL; + private SchemaRepository repository; + + protected void setUp() throws Exception { + repository = new SchemaRepository(dbType); + } + + public void test_findTableSource() throws Exception { + + repository.console("create table t_emp(emp_id bigint, name varchar(20));"); + repository.console("create table t_org(org_id bigint, name varchar(20));"); + + String sql = "SELECT emp_id, a.name AS emp_name, org_id, b.name AS org_name\n" + + "FROM t_emp a\n" + + "\tINNER JOIN t_org b ON a.emp_id = b.org_id"; + + List stmtList = SQLUtils.parseStatements(sql, dbType); + assertEquals(1, stmtList.size()); + + SQLSelectStatement stmt = (SQLSelectStatement) stmtList.get(0); + SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock(); + + // 大小写不敏感 + assertNotNull(queryBlock.findTableSource("A")); + assertSame(queryBlock.findTableSource("a"), queryBlock.findTableSource("A")); + + assertNull(queryBlock.findTableSourceWithColumn("emp_id")); + + // 使用repository做column resolve + repository.resolve(stmt); + + assertNotNull(queryBlock.findTableSourceWithColumn("emp_id")); + + SQLExprTableSource tableSource = (SQLExprTableSource) queryBlock.findTableSourceWithColumn("emp_id"); + assertNotNull(tableSource.getSchemaObject()); + + SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) tableSource.getSchemaObject().getStatement(); + assertNotNull(createTableStmt); + + SQLSelectItem selectItem = queryBlock.findSelectItem("org_name"); + assertNotNull(selectItem); + SQLPropertyExpr selectItemExpr = (SQLPropertyExpr) selectItem.getExpr(); + SQLColumnDefinition column = selectItemExpr.getResolvedColumn(); + assertNotNull(column); + assertEquals("name", column.getName().toString()); + assertEquals("t_org", (((SQLCreateTableStatement)column.getParent()).getName().toString())); + + assertSame(queryBlock.findTableSource("B"), selectItemExpr.getResolvedTableSource()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_01.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_01.java new file mode 100644 index 0000000000..b90a2745ab --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_01.java @@ -0,0 +1,98 @@ +/* + * 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.bvt.sql.db2; + +import com.alibaba.druid.sql.DB2Test; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class DB2CreateTableTest_01 extends DB2Test { + + public void test_0() throws Exception { + String sql = "CREATE TABLE MK.KPI_AREA_SORT_FACT_LATN_ID_MID\n" + + "(\n" + + "LATN_ID INTEGER,\n" + + "BUREAU_KEY INTEGER,\n" + + "ADD_SUM BIGINT,\n" + + "USER_ACCT BIGINT,\n" + + "USER_ACCT_LY BIGINT,\n" + + "TYPE_ID INTEGER\n" + + ")\n" + + "DATA CAPTURE NONE\n" + + "IN WH_APP_TEMP\n" + + "PARTITIONING KEY\n" + + "(LATN_ID,BUREAU_KEY,ADD_SUM\n" + + ") USING HASHING;"; + + DB2StatementParser parser = new DB2StatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + System.out.println(SQLUtils.toDB2String(stmt)); + + Assert.assertEquals(1, statementList.size()); + + DB2SchemaStatVisitor visitor = new DB2SchemaStatVisitor(); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(6, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("MK.KPI_AREA_SORT_FACT_LATN_ID_MID"))); + +// Assert.assertTrue(visitor.getColumns().contains(new Column("DSN8B10.EMP", "WORKDEPT"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name"))); + + Assert.assertEquals("CREATE TABLE MK.KPI_AREA_SORT_FACT_LATN_ID_MID (\n" + + "\tLATN_ID INTEGER,\n" + + "\tBUREAU_KEY INTEGER,\n" + + "\tADD_SUM BIGINT,\n" + + "\tUSER_ACCT BIGINT,\n" + + "\tUSER_ACCT_LY BIGINT,\n" + + "\tTYPE_ID INTEGER\n" + + ")\n" + + "DATA CAPTURE NONE\n" + + "IN WH_APP_TEMP\n" + + "PARTITION BY HASH (LATN_ID, BUREAU_KEY, ADD_SUM);", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2)); + + Assert.assertEquals("create table MK.KPI_AREA_SORT_FACT_LATN_ID_MID (\n" + + "\tLATN_ID INTEGER,\n" + + "\tBUREAU_KEY INTEGER,\n" + + "\tADD_SUM BIGINT,\n" + + "\tUSER_ACCT BIGINT,\n" + + "\tUSER_ACCT_LY BIGINT,\n" + + "\tTYPE_ID INTEGER\n" + + ")\n" + + "DATA CAPTURE NONE\n" + + "IN WH_APP_TEMP\n" + + "partition by hash (LATN_ID, BUREAU_KEY, ADD_SUM);", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + } +}