diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/ast/stmt/GaussDbCreateTableStatement.java b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/ast/stmt/GaussDbCreateTableStatement.java index fc8a84cba1..eae43f59b7 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/ast/stmt/GaussDbCreateTableStatement.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/ast/stmt/GaussDbCreateTableStatement.java @@ -14,6 +14,7 @@ public class GaussDbCreateTableStatement extends SQLCreateTableStatement impleme protected SQLExpr toNode; private SQLExpr onCommitExpr; private SQLExpr compressType; + private SQLExpr rowMovementType; public GaussDbCreateTableStatement() { super(DbType.gaussdb); @@ -87,4 +88,12 @@ public SQLExpr getCompressType() { public void setCompressType(SQLExpr compressType) { this.compressType = compressType; } + + public SQLExpr getRowMovementType() { + return rowMovementType; + } + + public void setRowMovementType(SQLExpr rowMovementType) { + this.rowMovementType = rowMovementType; + } } diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/parser/GaussDbCreateTableParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/parser/GaussDbCreateTableParser.java index a0084910e6..3f75670e01 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/parser/GaussDbCreateTableParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/parser/GaussDbCreateTableParser.java @@ -6,6 +6,7 @@ import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbDistributeBy; import com.alibaba.druid.sql.dialect.gaussdb.ast.stmt.GaussDbCreateTableStatement; import com.alibaba.druid.sql.dialect.postgresql.parser.PGCreateTableParser; +import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.Token; import com.alibaba.druid.util.FnvHash; @@ -86,12 +87,105 @@ protected void parseCreateTableRest(SQLCreateTableStatement stmt) { } } + SQLPartitionBy partitionClause = parsePartitionBy(); + if (partitionClause != null) { + gdStmt.setPartitionBy(partitionClause); + } + + parseRowMovement(gdStmt); + if (lexer.nextIf(Token.COMMENT)) { lexer.nextIf(Token.EQ); SQLExpr comment = this.exprParser.expr(); gdStmt.setComment(comment); } } + public void parseRowMovement(GaussDbCreateTableStatement stmt) { + if (lexer.token() == Token.ENABLE || lexer.token() == Token.DISABLE) { + stmt.setRowMovementType(exprParser.name()); + accept(Token.ROW); + acceptIdentifier("MOVEMENT"); + } + } + + public SQLPartitionBy parsePartitionBy() { + if (lexer.nextIf(Token.PARTITION)) { + accept(Token.BY); + if (lexer.nextIfIdentifier(FnvHash.Constants.HASH)) { + SQLPartitionBy hashPartition = new SQLPartitionByHash(); + if (lexer.nextIf(Token.LPAREN)) { + if (lexer.token() != Token.IDENTIFIER) { + throw new ParserException("expect identifier. " + lexer.info()); + } + for (; ; ) { + hashPartition.addColumn(this.exprParser.name()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + return hashPartition; + } + } else if (lexer.nextIfIdentifier(FnvHash.Constants.RANGE)) { + return partitionByRange(); + } else if (lexer.nextIfIdentifier(FnvHash.Constants.LIST)) { + return partitionByList(); + } + } + return null; + } + + protected SQLPartitionByRange partitionByRange() { + SQLPartitionByRange rangePartition = new SQLPartitionByRange(); + accept(Token.LPAREN); + for (; ; ) { + rangePartition.addColumn(this.exprParser.name()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + accept(Token.LPAREN); + for (; ; ) { + rangePartition.addPartition(this.getExprParser().parsePartition()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + return rangePartition; + } + + private SQLPartitionByList partitionByList() { + SQLPartitionByList listPartition = new SQLPartitionByList(); + accept(Token.LPAREN); + for (; ; ) { + listPartition.addColumn(this.exprParser.name()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + accept(Token.LPAREN); + for (; ; ) { + listPartition.addPartition(this.getExprParser().parsePartition()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + accept(Token.RPAREN); + return listPartition; + } protected void createTableBefore(SQLCreateTableStatement createTable) { parseTableType(createTable); diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/visitor/GaussDbOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/visitor/GaussDbOutputVisitor.java index 9364e32e5d..752c7d6c89 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/visitor/GaussDbOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/gaussdb/visitor/GaussDbOutputVisitor.java @@ -53,52 +53,67 @@ public boolean visit(GaussDbCreateTableStatement x) { printTableOptions(x); - if (x.getOnCommitExpr() != null) { - printOnCommit(x); - } + printOnCommit(x); - if (x.getCompressType() != null) { - println(); - x.getCompressType().accept(this); - } + printCompressType(x); - if (x.getDistributeBy() != null) { - printDistributeBy(x.getDistributeBy()); - } + printDistributeBy(x); - if (x.getToGroup() != null) { - printToGroup(x); - } + printToGroup(x); - if (x.getToNode() != null) { - printToNode(x); - } + printToNode(x); + + printPartitionBy(x); + + printRowMovement(x); printComment(x.getComment()); return false; } + public void printRowMovement(GaussDbCreateTableStatement x) { + if (x.getRowMovementType() != null) { + println(); + x.getRowMovementType().accept(this); + print(ucase ? " ROW MOVEMENT" : " row movement"); + } + } + + public void printCompressType(GaussDbCreateTableStatement x) { + if (x.getCompressType() != null) { + println(); + x.getCompressType().accept(this); + } + } public void printOnCommit(GaussDbCreateTableStatement x) { - println(); - print0(ucase ? "ON COMMIT " : "on commit "); - x.getOnCommitExpr().accept(this); - print0(ucase ? " ROWS" : " rows"); + if (x.getOnCommitExpr() != null) { + println(); + print0(ucase ? "ON COMMIT " : "on commit "); + x.getOnCommitExpr().accept(this); + print0(ucase ? " ROWS" : " rows"); + } } - public void printDistributeBy(GaussDbDistributeBy x) { - x.accept(this); + public void printDistributeBy(GaussDbCreateTableStatement x) { + if (x.getDistributeBy() != null) { + x.getDistributeBy().accept(this); + } } public void printToGroup(GaussDbCreateTableStatement x) { - println(); - print0(ucase ? "TO GROUP " : "to group "); - x.getToGroup().accept(this); + if (x.getToGroup() != null) { + println(); + print0(ucase ? "TO GROUP " : "to group "); + x.getToGroup().accept(this); + } } public void printToNode(GaussDbCreateTableStatement x) { - println(); - print0(ucase ? "TO NODE " : "to node "); - x.getToNode().accept(this); + if (x.getToNode() != null) { + println(); + print0(ucase ? "TO NODE " : "to node "); + x.getToNode().accept(this); + } } @Override diff --git a/core/src/test/resources/bvt/parser/gaussdb/5.txt b/core/src/test/resources/bvt/parser/gaussdb/5.txt new file mode 100644 index 0000000000..34d76b6534 --- /dev/null +++ b/core/src/test/resources/bvt/parser/gaussdb/5.txt @@ -0,0 +1,137 @@ +CREATE TABLE customer_address_SE +( + ca_address_sk INTEGER NOT NULL , + ca_address_id CHARACTER(16) NOT NULL , + ca_street_number CHARACTER(10) , + ca_street_name CHARACTER varying(60) , + ca_street_type CHARACTER(15) , + ca_suite_number CHARACTER(10) +) +WITH (ORIENTATION = COLUMN) +DISTRIBUTE BY HASH (ca_address_sk) +PARTITION BY RANGE(ca_address_sk) +( + PARTITION p1 START(1) END(1000) EVERY(200), + PARTITION p2 END(2000), + PARTITION p3 START(2000) END(5000) +) +-------------------- +CREATE TABLE customer_address_SE ( + ca_address_sk INTEGER NOT NULL, + ca_address_id CHARACTER(16) NOT NULL, + ca_street_number CHARACTER(10), + ca_street_name CHARACTER varying(60), + ca_street_type CHARACTER(15), + ca_suite_number CHARACTER(10) +) +WITH ( + ORIENTATION = COLUMN +) +DISTRIBUTE BY HASH (ca_address_sk) +PARTITION BY RANGE (ca_address_sk) ( + PARTITION p1 START (1) END (1000) EVERY (200), + PARTITION p2 END (2000), + PARTITION p3 START (2000) END (5000) +) +------------------------------------------------------------------------------------------------------------------------ +CREATE TABLE customer_address +( + ca_address_sk INTEGER NOT NULL , + ca_address_id CHARACTER(16) NOT NULL , + ca_street_number CHARACTER(10) , + ca_street_name CHARACTER varying(60) , + ca_street_type CHARACTER(15) , + ca_suite_number CHARACTER(10) +) +DISTRIBUTE BY HASH (ca_address_sk) +PARTITION BY RANGE(ca_address_sk) +( + PARTITION P1 VALUES LESS THAN(2450815), + PARTITION P2 VALUES LESS THAN(2451179), + PARTITION P3 VALUES LESS THAN(2451544), + PARTITION P4 VALUES LESS THAN(MAXVALUE) +); +-------------------- +CREATE TABLE customer_address ( + ca_address_sk INTEGER NOT NULL, + ca_address_id CHARACTER(16) NOT NULL, + ca_street_number CHARACTER(10), + ca_street_name CHARACTER varying(60), + ca_street_type CHARACTER(15), + ca_suite_number CHARACTER(10) +) +DISTRIBUTE BY HASH (ca_address_sk) +PARTITION BY RANGE (ca_address_sk) ( + PARTITION P1 VALUES LESS THAN (2450815), + PARTITION P2 VALUES LESS THAN (2451179), + PARTITION P3 VALUES LESS THAN (2451544), + PARTITION P4 VALUES LESS THAN (MAXVALUE) +); +------------------------------------------------------------------------------------------------------------------------ +CREATE TABLE data_list +( + id int, + time int, + sarlay decimal(12,2) +) +PARTITION BY LIST (time) +( + PARTITION P1 VALUES (202209), + PARTITION P2 VALUES (202210,202208), + PARTITION P3 VALUES (202211), + PARTITION P4 VALUES (202212), + PARTITION P5 VALUES (202301) +); +-------------------- +CREATE TABLE data_list ( + id int, + time int, + sarlay decimal(12, 2) +) +PARTITION BY LIST (time) ( + PARTITION P1 VALUES (202209), + PARTITION P2 VALUES ((202210, 202208)), + PARTITION P3 VALUES (202211), + PARTITION P4 VALUES (202212), + PARTITION P5 VALUES (202301) +); +------------------------------------------------------------------------------------------------------------------------ +CREATE TABLE cold_hot_table +( + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_ID CHAR(15) , + W_SUITE_NUMBER CHAR(10) +) +WITH (ORIENTATION = COLUMN, storage_policy = 'LMT:30') +DISTRIBUTE BY HASH (W_WAREHOUSE_ID) +PARTITION BY RANGE(W_STREET_ID) +( + PARTITION P1 VALUES LESS THAN(100000), + PARTITION P2 VALUES LESS THAN(200000), + PARTITION P3 VALUES LESS THAN(300000), + PARTITION P4 VALUES LESS THAN(MAXVALUE) +) DISABLE ROW MOVEMENT; +-------------------- +CREATE TABLE cold_hot_table ( + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20), + W_STREET_NUMBER CHAR(10), + W_STREET_NAME VARCHAR(60), + W_STREET_ID CHAR(15), + W_SUITE_NUMBER CHAR(10) +) +WITH ( + ORIENTATION = COLUMN, + storage_policy = 'LMT:30' +) +DISTRIBUTE BY HASH (W_WAREHOUSE_ID) +PARTITION BY RANGE (W_STREET_ID) ( + PARTITION P1 VALUES LESS THAN (100000), + PARTITION P2 VALUES LESS THAN (200000), + PARTITION P3 VALUES LESS THAN (300000), + PARTITION P4 VALUES LESS THAN (MAXVALUE) +) +DISABLE ROW MOVEMENT; \ No newline at end of file