From cadce912f6a690094f8eab748fd3e304afdab5d8 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 30 Nov 2014 01:35:00 +0800 Subject: [PATCH] improved sql parser for postgresql, support create table inherits --- .../statement/SQLCreateTableStatement.java | 35 +++++------- .../ast/stmt/PGCreateTableStatement.java | 14 +++++ .../sql/parser/SQLCreateTableParser.java | 9 +++ .../sql/visitor/SQLASTOutputVisitor.java | 6 ++ .../druid/sql/visitor/SchemaStatVisitor.java | 4 ++ .../sql/postgresql/PGCreateTableTest_5.java | 55 +++++++++++++++++++ 6 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGCreateTableStatement.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateTableTest_5.java 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 87640b7a86..32f606f571 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 @@ -30,12 +30,15 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS protected List tableElementList = new ArrayList(); + // for postgresql + private SQLExprTableSource inherits; + public SQLCreateTableStatement(){ } - + public SQLCreateTableStatement(String dbType){ - super (dbType); + super(dbType); } public SQLName getName() { @@ -76,7 +79,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS public List getTableElementList() { return tableElementList; } - + public boolean isIfNotExiists() { return ifNotExiists; } @@ -85,26 +88,15 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS this.ifNotExiists = ifNotExiists; } - @Override - public void output(StringBuffer buf) { - buf.append("CREATE TABLE "); - if (Type.GLOBAL_TEMPORARY.equals(this.type)) { - buf.append("GLOBAL TEMPORARY "); - } else if (Type.LOCAL_TEMPORARY.equals(this.type)) { - buf.append("LOCAL TEMPORARY "); - } + public SQLExprTableSource getInherits() { + return inherits; + } - this.tableSource.output(buf); - buf.append(" "); - - buf.append("("); - for (int i = 0, size = tableElementList.size(); i < size; ++i) { - if (i != 0) { - buf.append(", "); - } - tableElementList.get(i).output(buf); + public void setInherits(SQLExprTableSource inherits) { + if (inherits != null) { + inherits.setParent(this); } - buf.append(")"); + this.inherits = inherits; } @Override @@ -112,6 +104,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS if (visitor.visit(this)) { this.acceptChild(visitor, tableSource); this.acceptChild(visitor, tableElementList); + this.acceptChild(visitor, inherits); } visitor.endVisit(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGCreateTableStatement.java new file mode 100644 index 0000000000..2d566bc70a --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGCreateTableStatement.java @@ -0,0 +1,14 @@ +package com.alibaba.druid.sql.dialect.postgresql.ast.stmt; + +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.util.JdbcConstants; + +public class PGCreateTableStatement extends SQLCreateTableStatement { + private SQLExprTableSource inherits; + + public PGCreateTableStatement(){ + super(JdbcConstants.POSTGRESQL); + } + +} 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 48bce825c0..3524bc6db3 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLCreateTableParser.java @@ -15,9 +15,11 @@ */ package com.alibaba.druid.sql.parser; +import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLConstraint; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableElement; public class SQLCreateTableParser extends SQLDDLParser { @@ -109,6 +111,13 @@ public class SQLCreateTableParser extends SQLDDLParser { accept(Token.RPAREN); + if (identifierEquals("INHERITS")) { + lexer.nextToken(); + accept(Token.LPAREN); + SQLName inherits = this.exprParser.name(); + createTable.setInherits(new SQLExprTableSource(inherits)); + accept(Token.RPAREN); + } } return createTable; 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 d400b717bd..90b935793c 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1058,6 +1058,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab println(); print(")"); } + + if (x.getInherits() != null) { + print(" INHERITS ("); + x.getInherits().accept(this); + print(")"); + } return false; } 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 a34dd15682..b190912389 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -1107,6 +1107,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { accept(x.getTableElementList()); restoreCurrentTable(x); + + if (x.getInherits() != null) { + x.getInherits().accept(this); + } return false; } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateTableTest_5.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateTableTest_5.java new file mode 100644 index 0000000000..82cfba7248 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateTableTest_5.java @@ -0,0 +1,55 @@ +/* + * 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.bvt.sql.postgresql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PGTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class PGCreateTableTest_5 extends PGTest { + + public void test_0() throws Exception { + String sql = "CREATE TABLE products (" + // + " state char(2)" + // + ") INHERITS (cities);"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("products"))); + + Assert.assertTrue(visitor.getTables().get(new TableStat.Name("products")).getCreateCount() == 1); + + Assert.assertTrue(visitor.getColumns().size() == 1); + } + +}