diff --git a/core/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java b/core/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java index ab945fa704..d9ad7e2feb 100644 --- a/core/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java +++ b/core/src/main/java/com/alibaba/druid/sql/ast/SQLPartitionByList.java @@ -18,6 +18,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLPartitionByList extends SQLPartitionBy { + protected PartitionByListType type; @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { @@ -29,6 +30,14 @@ protected void accept0(SQLASTVisitor visitor) { visitor.endVisit(this); } + public PartitionByListType getType() { + return type; + } + + public void setType(PartitionByListType type) { + this.type = type; + } + public SQLPartitionByList clone() { SQLPartitionByList x = new SQLPartitionByList(); @@ -46,4 +55,8 @@ public SQLPartitionByList clone() { public void cloneTo(SQLPartitionByList x) { super.cloneTo(x); } + public enum PartitionByListType { + LIST_EXPRESSION, + LIST_COLUMNS, + } } diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/clickhouse/parser/CKCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/clickhouse/parser/CKCreateTableParser.java index ac289a6670..d948b8b0d2 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/clickhouse/parser/CKCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/clickhouse/parser/CKCreateTableParser.java @@ -27,7 +27,8 @@ protected SQLCreateTableStatement newCreateStatement() { public SQLPartitionBy parsePartitionBy() { lexer.nextToken(); accept(Token.BY); - SQLPartitionBy sqlPartitionBy = new SQLPartitionByList(); + SQLPartitionByList sqlPartitionBy = new SQLPartitionByList(); + sqlPartitionBy.setType(SQLPartitionByList.PartitionByListType.LIST_EXPRESSION); boolean hasParen = false; if (lexer.nextIf(Token.LPAREN)) { hasParen = true; diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index 6fdfaa3089..83f4892a08 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -1071,7 +1071,7 @@ public SQLPartitionBy parsePartitionBy() { partitionClause = clause; partitionClauseRest(clause); - } else if (lexer.identifierEquals("HASH") || lexer.identifierEquals("UNI_HASH")) { + } else if (lexer.identifierEquals(FnvHash.Constants.HASH) || lexer.identifierEquals("UNI_HASH")) { SQLPartitionByHash clause = new SQLPartitionByHash(); if (lexer.identifierEquals("UNI_HASH")) { @@ -1096,28 +1096,30 @@ public SQLPartitionBy parsePartitionBy() { partitionClauseRest(clause); - } else if (lexer.identifierEquals("RANGE")) { + } else if (lexer.identifierEquals(FnvHash.Constants.RANGE)) { SQLPartitionByRange clause = partitionByRange(); partitionClause = clause; partitionClauseRest(clause); - } else if (lexer.identifierEquals("VALUE")) { + } else if (lexer.identifierEquals(FnvHash.Constants.VALUE)) { SQLPartitionByValue clause = partitionByValue(); partitionClause = clause; partitionClauseRest(clause); - } else if (lexer.identifierEquals("LIST")) { + } else if (lexer.identifierEquals(FnvHash.Constants.LIST)) { lexer.nextToken(); SQLPartitionByList clause = new SQLPartitionByList(); if (lexer.token() == Token.LPAREN) { + clause.setType(SQLPartitionByList.PartitionByListType.LIST_EXPRESSION); lexer.nextToken(); clause.addColumn(this.exprParser.expr()); accept(Token.RPAREN); } else { - acceptIdentifier("COLUMNS"); + acceptIdentifier(FnvHash.Constants.COLUMNS); + clause.setType(SQLPartitionByList.PartitionByListType.LIST_COLUMNS); accept(Token.LPAREN); for (; ; ) { clause.addColumn(this.exprParser.name()); diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oscar/parser/OscarCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oscar/parser/OscarCreateTableParser.java index dc6eb8fe8e..1cfeee730e 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oscar/parser/OscarCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oscar/parser/OscarCreateTableParser.java @@ -27,11 +27,13 @@ public SQLPartitionBy parsePartitionBy() { SQLPartitionByList list = new SQLPartitionByList(); if (lexer.token() == Token.LPAREN) { + list.setType(SQLPartitionByList.PartitionByListType.LIST_EXPRESSION); lexer.nextToken(); list.addColumn(this.exprParser.expr()); accept(Token.RPAREN); } else { acceptIdentifier("COLUMNS"); + list.setType(SQLPartitionByList.PartitionByListType.LIST_COLUMNS); accept(Token.LPAREN); for (; ; ) { list.addColumn(this.exprParser.name()); diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGCreateTableParser.java index 0c88ad8439..7ed59844e4 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGCreateTableParser.java @@ -70,11 +70,13 @@ public SQLPartitionBy parsePartitionBy() { SQLPartitionByList list = new SQLPartitionByList(); if (lexer.token() == Token.LPAREN) { + list.setType(SQLPartitionByList.PartitionByListType.LIST_EXPRESSION); lexer.nextToken(); list.addColumn(this.exprParser.expr()); accept(Token.RPAREN); } else { acceptIdentifier("COLUMNS"); + list.setType(SQLPartitionByList.PartitionByListType.LIST_COLUMNS); accept(Token.LPAREN); for (; ; ) { list.addColumn(this.exprParser.name()); diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/starrocks/parser/StarRocksCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/starrocks/parser/StarRocksCreateTableParser.java index 4b55f454c6..21cec19644 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/starrocks/parser/StarRocksCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/starrocks/parser/StarRocksCreateTableParser.java @@ -162,6 +162,7 @@ public SQLPartitionBy parsePartitionBy() { hasLparen = true; } else if (lexer.nextIfIdentifier(FnvHash.Constants.LIST)) { partitionClause = new SQLPartitionByList(); + ((SQLPartitionByList) partitionClause).setType(SQLPartitionByList.PartitionByListType.LIST_EXPRESSION); accept(Token.LPAREN); hasLparen = true; } else if (lexer.nextIf(Token.LPAREN)) { diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index ee80c7d322..7f8ddcdb72 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -8011,12 +8011,12 @@ public boolean visit(SQLPartitionByRange x) { @Override public boolean visit(SQLPartitionByList x) { print0(ucase ? "LIST " : "list "); - if (x.getColumns().size() == 1) { - print('('); - x.getColumns().get(0).accept(this); + if (SQLPartitionByList.PartitionByListType.LIST_COLUMNS.equals(x.getType())) { + print0(ucase ? "COLUMNS (" : "columns ("); + printAndAccept(x.getColumns(), ", "); print0(")"); } else { - print0(ucase ? "COLUMNS (" : "columns ("); + print('('); printAndAccept(x.getColumns(), ", "); print0(")"); } diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oceanbase/OceanBaseResourceTest.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oceanbase/OceanBaseResourceTest.java new file mode 100644 index 0000000000..f17fbd036f --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oceanbase/OceanBaseResourceTest.java @@ -0,0 +1,16 @@ +package com.alibaba.druid.bvt.sql.oceanbase; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.bvt.sql.SQLResourceTest; +import org.junit.Test; + +public class OceanBaseResourceTest extends SQLResourceTest { + public OceanBaseResourceTest() { + super(DbType.oceanbase); + } + + @Test + public void oceanbase_parse() throws Exception { + fileTest(0, 999, i -> "bvt/parser/oceanbase/" + i + ".txt"); + } +} diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/presto/TrinoResourceTest.java b/core/src/test/java/com/alibaba/druid/bvt/sql/presto/TrinoResourceTest.java index 97deb6d9e2..696e436108 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/presto/TrinoResourceTest.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/presto/TrinoResourceTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals; -public class TrinoResourceTest extends SQLResourceTest{ +public class TrinoResourceTest extends SQLResourceTest { public TrinoResourceTest() { super(DbType.trino); @@ -159,7 +159,7 @@ public void test_92() throws Exception { @Test public void trino_parse() throws Exception { - fileTest(1, 999, i -> "bvt/parser/trino/" + i + ".txt"); + fileTest(0, 999, i -> "bvt/parser/trino/" + i + ".txt"); } public void exec_test(String resource) throws Exception { diff --git a/core/src/test/resources/bvt/parser/oceanbase/0.txt b/core/src/test/resources/bvt/parser/oceanbase/0.txt new file mode 100644 index 0000000000..cb54e3523c --- /dev/null +++ b/core/src/test/resources/bvt/parser/oceanbase/0.txt @@ -0,0 +1,38 @@ +CREATE TABLE t2_m_lch(col1 INT,col2 INT) +PARTITION BY LIST COLUMNS(col1) +SUBPARTITION BY HASH(col2) SUBPARTITIONS 5 +(PARTITION p0 VALUES IN(100), +PARTITION p1 VALUES IN(200), +PARTITION p2 VALUES IN(300) +); +-------------------- +CREATE TABLE t2_m_lch ( + col1 INT, + col2 INT +) +PARTITION BY LIST COLUMNS (col1) +SUBPARTITION BY HASH (col2) SUBPARTITIONS 5 ( + PARTITION p0 VALUES IN (100), + PARTITION p1 VALUES IN (200), + PARTITION p2 VALUES IN (300) +); +------------------------------------------------------------------------------------------------------------------------ +CREATE TABLE t2_m_lh (col1 INT NOT NULL,col2 varchar(50),col3 INT NOT NULL) +PARTITION BY LIST (col1) +SUBPARTITION BY HASH(col3) SUBPARTITIONS 3 +(PARTITION p0 VALUES IN(100), +PARTITION p1 VALUES IN(200), +PARTITION p2 VALUES IN(300) +); +-------------------- +CREATE TABLE t2_m_lh ( + col1 INT NOT NULL, + col2 varchar(50), + col3 INT NOT NULL +) +PARTITION BY LIST (col1) +SUBPARTITION BY HASH (col3) SUBPARTITIONS 3 ( + PARTITION p0 VALUES IN (100), + PARTITION p1 VALUES IN (200), + PARTITION p2 VALUES IN (300) +); \ No newline at end of file diff --git a/core/src/test/resources/bvt/parser/trino/0.txt b/core/src/test/resources/bvt/parser/trino/0.txt index 25db6229d1..14de6c35ad 100644 --- a/core/src/test/resources/bvt/parser/trino/0.txt +++ b/core/src/test/resources/bvt/parser/trino/0.txt @@ -70,7 +70,13 @@ CREATE TABLE kudu.dwd_market.dynamic_qrcode_hquid_relate_unionid ( del_flag integer WITH(nullable = true), uname varchar WITH(nullable = true) ) -WITH (number_of_replicas = 3, partition_by_hash_buckets = 2, partition_by_hash_columns = ARRAY['unionid'], partition_by_range_columns = ARRAY['unionid', 'hq_uid'], range_partitions = '[{lower:null,upper:null}]') +WITH ( + number_of_replicas = 3, + partition_by_hash_buckets = 2, + partition_by_hash_columns = ARRAY['unionid'], + partition_by_range_columns = ARRAY['unionid', 'hq_uid'], + range_partitions = '[{lower:null,upper:null}]' +) ------------------------------------------------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS orders ( orderkey bigint,