diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java index 57190c0ade..05acb5a611 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsCreateTableStatement.java @@ -35,6 +35,11 @@ public class OdpsCreateTableStatement extends SQLCreateTableStatement { protected List partitionColumns = new ArrayList(2); + protected final List clusteredBy = new ArrayList(); + protected final List sortedBy = new ArrayList(); + + protected int buckets; + protected SQLExpr lifecycle; public OdpsCreateTableStatement(){ @@ -90,10 +95,27 @@ public class OdpsCreateTableStatement extends SQLCreateTableStatement { this.acceptChild(visitor, tableSource); this.acceptChild(visitor, tableElementList); this.acceptChild(visitor, partitionColumns); + this.acceptChild(visitor, clusteredBy); + this.acceptChild(visitor, sortedBy); this.acceptChild(visitor, lifecycle); this.acceptChild(visitor, select); } visitor.endVisit(this); } + public List getClusteredBy() { + return clusteredBy; + } + + public List getSortedBy() { + return sortedBy; + } + + public int getBuckets() { + return buckets; + } + + public void setBuckets(int buckets) { + this.buckets = buckets; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java index 41e98cb1cd..73a2211a0f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsCreateTableParser.java @@ -136,6 +136,33 @@ public class OdpsCreateTableParser extends SQLCreateTableParser { accept(Token.RPAREN); } + + if (identifierEquals("CLUSTERED")) { + lexer.nextToken(); + accept(Token.BY); + accept(Token.LPAREN); + this.exprParser.names(stmt.getClusteredBy()); + accept(Token.RPAREN); + } + + if (identifierEquals("SORTED")) { + lexer.nextToken(); + accept(Token.BY); + accept(Token.LPAREN); + this.exprParser.names(stmt.getSortedBy()); + accept(Token.RPAREN); + } + + if (stmt.getClusteredBy().size() > 0 || stmt.getSortedBy().size() > 0) { + accept(Token.INTO); + if (lexer.token() == Token.LITERAL_INT) { + stmt.setBuckets(lexer.integerValue().intValue()); + lexer.nextToken(); + } else { + throw new ParserException("into buckets must be integer."); + } + acceptIdentifier("BUCKETS"); + } if (identifierEquals("LIFECYCLE")) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index eaec1e3df9..6c226253bd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -131,6 +131,30 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis print(')'); } + List clusteredBy = x.getClusteredBy(); + if (clusteredBy.size() > 0) { + println(); + print0(ucase ? "CLUSTERED BY (" : "clustered by ("); + printAndAccept(clusteredBy, ","); + print(')'); + } + + List sortedBy = x.getSortedBy(); + if (sortedBy.size() > 0) { + println(); + print0(ucase ? "SORTED BY (" : "sorted by ("); + printAndAccept(sortedBy, ","); + print(')'); + } + + int buckets = x.getBuckets(); + if (buckets > 0) { + println(); + print0(ucase ? "INTO " : "into "); + print(buckets); + print0(ucase ? " BUCKETS" : " buckets"); + } + if (x.getLifecycle() != null) { println(); print0(ucase ? "LIFECYCLE " : "lifecycle "); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest_1.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest3.java similarity index 93% rename from src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest_1.java rename to src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest3.java index 9d64a06d51..5f1831c738 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest_1.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest3.java @@ -9,7 +9,7 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser; import com.alibaba.druid.sql.parser.Token; -public class OdpsCreateTableTest_1 extends TestCase { +public class OdpsCreateTableTest3 extends TestCase { public void test_0() throws Exception { String sql = "CREATE TABLE sale_detail_like LIKE sale_detail;"; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest4.java new file mode 100644 index 0000000000..0f4d8a9025 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest4.java @@ -0,0 +1,72 @@ +/* + * 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.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class OdpsCreateTableTest4 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "CREATE TABLE T1 (a string, b string, c bigint) CLUSTERED BY (c) SORTED by (c) INTO 1024 BUCKETS;";// + assertEquals("CREATE TABLE T1 (\n" + + "\ta STRING,\n" + + "\tb STRING,\n" + + "\tc BIGINT\n" + + ")\n" + + "CLUSTERED BY (c)\n" + + "SORTED BY (c)\n" + + "INTO 1024 BUCKETS;", SQLUtils.formatOdps(sql)); + + assertEquals("create table T1 (\n" + + "\ta string,\n" + + "\tb string,\n" + + "\tc bigint\n" + + ")\n" + + "clustered by (c)\n" + + "sorted by (c)\n" + + "into 1024 buckets;", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + 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()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(3, visitor.getColumns().size()); + assertEquals(0, visitor.getConditions().size()); + +// System.out.println(SQLUtils.formatOdps(sql)); + +// assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +}