diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java index fa0dd73636..fd85d6f431 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGSQLStatementParser.java @@ -519,4 +519,57 @@ public class PGSQLStatementParser extends SQLStatementParser { return stmt; } + public SQLStatement parseCreateIndex(boolean acceptCreate) { + if (acceptCreate) { + accept(Token.CREATE); + } + + SQLCreateIndexStatement stmt = new SQLCreateIndexStatement(getDbType()); + if (lexer.token() == Token.UNIQUE) { + lexer.nextToken(); + if (lexer.identifierEquals("CLUSTERED")) { + lexer.nextToken(); + stmt.setType("UNIQUE CLUSTERED"); + } else { + stmt.setType("UNIQUE"); + } + } else if (lexer.identifierEquals("FULLTEXT")) { + stmt.setType("FULLTEXT"); + lexer.nextToken(); + } else if (lexer.identifierEquals("NONCLUSTERED")) { + stmt.setType("NONCLUSTERED"); + lexer.nextToken(); + } + + accept(Token.INDEX); + + stmt.setName(this.exprParser.name()); + + accept(Token.ON); + + stmt.setTable(this.exprParser.name()); + + if (lexer.token() == Token.USING) { + lexer.nextToken(); + String using = lexer.stringVal(); + accept(Token.IDENTIFIER); + stmt.setUsing(using); + } + + accept(Token.LPAREN); + + for (;;) { + SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem(); + item.setParent(stmt); + stmt.addItem(item); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + + return stmt; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java index e8301717aa..307f2141b0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGOutputVisitor.java @@ -2974,4 +2974,36 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor print0(ucase ? "END IF" : "end if"); return false; } + + @Override + public boolean visit(SQLCreateIndexStatement x) { + print0(ucase ? "CREATE " : "create "); + if (x.getType() != null) { + print0(x.getType()); + print(' '); + } + + print0(ucase ? "INDEX " : "index "); + + if (x.getUsing() != null) { + print0(ucase ? " USING " : " using "); + ; + print0(x.getUsing()); + } + + x.getName().accept(this); + print0(ucase ? " ON " : " on "); + x.getTable().accept(this); + print0(" ("); + printAndAccept(x.getItems(), ", "); + print(')'); + + SQLExpr comment = x.getComment(); + if (comment != null) { + print0(ucase ? " COMMENT " : " comment "); + comment.accept(this); + } + + return false; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateIndexTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateIndexTest_0.java new file mode 100644 index 0000000000..44e31161e6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PGCreateIndexTest_0.java @@ -0,0 +1,55 @@ +/* + * 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.postgresql; + +import com.alibaba.druid.sql.PGTest; +import com.alibaba.druid.sql.SQLUtils; +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; + +import java.util.List; + +public class PGCreateIndexTest_0 extends PGTest { + + public void test_0() throws Exception { + String sql = "CREATE UNIQUE INDEX \"test_idx\" ON \"public\".\"city\" USING btree (\"name\");"; + + PGSQLStatementParser parser = new PGSQLStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + assertEquals("CREATE UNIQUE INDEX USING btree\"test_idx\" ON \"public\".\"city\" (\"name\");", SQLUtils.toPGString(stmt)); + + assertEquals("create UNIQUE index using btree\"test_idx\" on \"public\".\"city\" (\"name\");", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + assertEquals(1, statementList.size()); + + PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("public.city"))); + + assertTrue(visitor.getTables().get(new TableStat.Name("public.city")).getCreateIndexCount() == 1); + + assertEquals(1, visitor.getColumns().size() ); + } + +}