From 141aca0cd33ba7d576462b7de3c5afd23ddad660 Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 9 Oct 2017 21:00:00 +0800 Subject: [PATCH] improved db2 parser create table support. --- .../db2/ast/stmt/DB2CreateTableStatement.java | 28 ++++++ .../db2/parser/DB2CreateTableParser.java | 8 +- .../dialect/db2/visitor/DB2OutputVisitor.java | 14 +++ .../java/com/alibaba/druid/util/FnvHash.java | 1 + .../bvt/sql/db2/DB2CreateTableTest_02.java | 88 +++++++++++++++++ .../bvt/sql/db2/DB2CreateTableTest_03.java | 96 +++++++++++++++++++ 6 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_02.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_03.java 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 index 0e23b91830..f5f9fca966 100644 --- 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 @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.dialect.db2.ast.stmt; +import com.alibaba.druid.sql.ast.SQLName; 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; @@ -24,6 +25,9 @@ public class DB2CreateTableStatement extends SQLCreateTableStatement implements private boolean dataCaptureNone; private boolean dataCaptureChanges; + protected SQLName database; + protected SQLName validproc; + public boolean isDataCaptureNone() { return dataCaptureNone; } @@ -40,6 +44,28 @@ public class DB2CreateTableStatement extends SQLCreateTableStatement implements this.dataCaptureChanges = dataCaptureChanges; } + public SQLName getDatabase() { + return database; + } + + public void setDatabase(SQLName database) { + if (database != null) { + database.setParent(this); + } + this.database = database; + } + + public SQLName getValidproc() { + return validproc; + } + + public void setValidproc(SQLName validproc) { + if (validproc != null) { + validproc.setParent(this); + } + this.validproc = validproc; + } + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor instanceof DB2ASTVisitor) { @@ -57,6 +83,8 @@ public class DB2CreateTableStatement extends SQLCreateTableStatement implements this.acceptChild(visitor, tableElementList); this.acceptChild(visitor, inherits); this.acceptChild(visitor, select); + this.acceptChild(visitor, database); + this.acceptChild(visitor, validproc); } 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 index cd935255ef..985831aaa1 100644 --- 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 @@ -143,7 +143,9 @@ public class DB2CreateTableParser extends SQLCreateTableParser { lexer.nextToken(); if (lexer.token() == Token.DATABASE) { - throw new ParserException("TODO " + lexer.info()); + lexer.nextToken(); + SQLName database = this.exprParser.name(); + createTable.setDatabase(database); } else if (lexer.identifierEquals("tablespace")) { throw new ParserException("TODO " + lexer.info()); } else { @@ -164,6 +166,10 @@ public class DB2CreateTableParser extends SQLCreateTableParser { acceptIdentifier("HASHING"); createTable.setPartitioning(partitionBy); continue; + } else if (lexer.identifierEquals(FnvHash.Constants.VALIDPROC)) { + lexer.nextToken(); + SQLName validproc = this.exprParser.name(); + createTable.setValidproc(validproc); } break; } 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 4025975a0e..d3176c7cc8 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 @@ -98,6 +98,20 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit tablespace.accept(this); } + SQLName database = x.getDatabase(); + if (database != null) { + println(); + print("IN DATABASE "); + database.accept(this); + } + + SQLName validproc = x.getValidproc(); + if (validproc != null) { + println(); + print("VALIDPROC "); + validproc.accept(this); + } + SQLPartitionBy partitionBy = x.getPartitioning(); if (partitionBy != null) { println(); diff --git a/src/main/java/com/alibaba/druid/util/FnvHash.java b/src/main/java/com/alibaba/druid/util/FnvHash.java index 4162f56e62..50dd4a6053 100644 --- a/src/main/java/com/alibaba/druid/util/FnvHash.java +++ b/src/main/java/com/alibaba/druid/util/FnvHash.java @@ -512,5 +512,6 @@ public final class FnvHash { long LATERAL = fnv1a_64_lower("LATERAL"); long NONE = fnv1a_64_lower("NONE"); long PARTITIONING = fnv1a_64_lower("PARTITIONING"); + long VALIDPROC = fnv1a_64_lower("VALIDPROC"); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_02.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_02.java new file mode 100644 index 0000000000..a3de541bfe --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_02.java @@ -0,0 +1,88 @@ +/* + * 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_02 extends DB2Test { + + public void test_0() throws Exception { + String sql = " CREATE TABLE DSN8A10.DEPT\n" + + " (DEPTNO CHAR(3) NOT NULL,\n" + + " DEPTNAME VARCHAR(36) NOT NULL,\n" + + " MGRNO CHAR(6) ,\n" + + " ADMRDEPT CHAR(3) NOT NULL,\n" + + " LOCATION CHAR(16) ,\n" + + " PRIMARY KEY(DEPTNO) )\n" + + " IN DSN8D10A.DSN8S10D;"; + + 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.containsTable("DSN8A10.DEPT")); + +// 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 DSN8A10.DEPT (\n" + + "\tDEPTNO CHAR(3) NOT NULL,\n" + + "\tDEPTNAME VARCHAR(36) NOT NULL,\n" + + "\tMGRNO CHAR(6),\n" + + "\tADMRDEPT CHAR(3) NOT NULL,\n" + + "\tLOCATION CHAR(16),\n" + + "\tPRIMARY KEY (DEPTNO)\n" + + ")\n" + + "IN DSN8D10A.DSN8S10D;", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2)); + + Assert.assertEquals("create table DSN8A10.DEPT (\n" + + "\tDEPTNO CHAR(3) not null,\n" + + "\tDEPTNAME VARCHAR(36) not null,\n" + + "\tMGRNO CHAR(6),\n" + + "\tADMRDEPT CHAR(3) not null,\n" + + "\tLOCATION CHAR(16),\n" + + "\tprimary key (DEPTNO)\n" + + ")\n" + + "IN DSN8D10A.DSN8S10D;", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_03.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_03.java new file mode 100644 index 0000000000..831c5a5f54 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2CreateTableTest_03.java @@ -0,0 +1,96 @@ +/* + * 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.util.JdbcConstants; +import org.junit.Assert; + +import java.util.List; + +public class DB2CreateTableTest_03 extends DB2Test { + + public void test_0() throws Exception { + String sql = " CREATE TABLE DSN8A10.PROJ\n" + + " (PROJNO CHAR(6) NOT NULL,\n" + + " PROJNAME VARCHAR(24) NOT NULL,\n" + + " DEPTNO CHAR(3) NOT NULL,\n" + + " RESPEMP CHAR(6) NOT NULL,\n" + + " PRSTAFF DECIMAL(5,2) ,\n" + + " PRSTDATE DATE ,\n" + + " PRENDATE DATE ,\n" + + " MAJPROJ CHAR(6) NOT NULL)\n" + + " IN DATABASE DSN8D10A\n" + + " VALIDPROC DSN8EAPR;"; + + 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(8, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.containsTable("DSN8A10.PROJ")); + +// 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 DSN8A10.PROJ (\n" + + "\tPROJNO CHAR(6) NOT NULL,\n" + + "\tPROJNAME VARCHAR(24) NOT NULL,\n" + + "\tDEPTNO CHAR(3) NOT NULL,\n" + + "\tRESPEMP CHAR(6) NOT NULL,\n" + + "\tPRSTAFF DECIMAL(5, 2),\n" + + "\tPRSTDATE DATE,\n" + + "\tPRENDATE DATE,\n" + + "\tMAJPROJ CHAR(6) NOT NULL\n" + + ")\n" + + "IN DATABASE DSN8D10A\n" + + "VALIDPROC DSN8EAPR;", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2)); + + Assert.assertEquals("create table DSN8A10.PROJ (\n" + + "\tPROJNO CHAR(6) not null,\n" + + "\tPROJNAME VARCHAR(24) not null,\n" + + "\tDEPTNO CHAR(3) not null,\n" + + "\tRESPEMP CHAR(6) not null,\n" + + "\tPRSTAFF DECIMAL(5, 2),\n" + + "\tPRSTDATE DATE,\n" + + "\tPRENDATE DATE,\n" + + "\tMAJPROJ CHAR(6) not null\n" + + ")\n" + + "IN DATABASE DSN8D10A\n" + + "VALIDPROC DSN8EAPR;", // + SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + } +}