This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 0dca9eff22a [Enhancement](alter) support add partitions in batch 
(#37114)
0dca9eff22a is described below

commit 0dca9eff22ac911e523eceefce6ac94ad9535320
Author: lw112 <131352377+felixw...@users.noreply.github.com>
AuthorDate: Wed Aug 14 23:20:41 2024 +0800

    [Enhancement](alter) support add partitions in batch (#37114)
    
    ## Proposed changes
    
    Issue Number: close #32524
---
 fe/fe-core/src/main/cup/sql_parser.cup             |   8 ++
 .../main/java/org/apache/doris/alter/Alter.java    |  10 +-
 .../doris/analysis/AlterMultiPartitionClause.java  |  73 ++++++++++++++
 .../main/java/org/apache/doris/catalog/Env.java    |   6 ++
 .../apache/doris/datasource/InternalCatalog.java   |  20 ++++
 .../alter_p0/test_alter_add_multi_partition.groovy | 110 +++++++++++++++++++++
 6 files changed, 226 insertions(+), 1 deletion(-)

diff --git a/fe/fe-core/src/main/cup/sql_parser.cup 
b/fe/fe-core/src/main/cup/sql_parser.cup
index 619f13e6278..891a72645cd 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -1746,6 +1746,14 @@ alter_table_clause ::=
     {:
         RESULT = new ModifyEngineClause(engine, properties);
     :}
+    | KW_ADD opt_tmp:isTempPartition KW_PARTITIONS KW_FROM LPAREN 
partition_key_list:lower RPAREN KW_TO LPAREN partition_key_list:upper RPAREN 
KW_INTERVAL INTEGER_LITERAL:time_interval ident:time_unit 
opt_properties:properties
+    {:
+        RESULT = new 
AlterMultiPartitionClause(PartitionKeyDesc.createMultiFixed(lower, upper, 
time_interval, time_unit), properties, isTempPartition);
+    :}
+    | KW_ADD opt_tmp:isTempPartition KW_PARTITIONS KW_FROM LPAREN 
partition_key_list:lower RPAREN KW_TO LPAREN partition_key_list:upper RPAREN 
KW_INTERVAL INTEGER_LITERAL:num_interval opt_properties:properties
+    {:
+        RESULT = new 
AlterMultiPartitionClause(PartitionKeyDesc.createMultiFixed(lower, upper, 
num_interval), properties, isTempPartition);
+    :}
     ;
 
 opt_enable_feature_properties ::=
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
index 1fcb4fe65c3..ced14ad4b8d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
@@ -20,6 +20,7 @@ package org.apache.doris.alter;
 import org.apache.doris.analysis.AddPartitionClause;
 import org.apache.doris.analysis.AddPartitionLikeClause;
 import org.apache.doris.analysis.AlterClause;
+import org.apache.doris.analysis.AlterMultiPartitionClause;
 import org.apache.doris.analysis.AlterSystemStmt;
 import org.apache.doris.analysis.AlterTableStmt;
 import org.apache.doris.analysis.AlterViewStmt;
@@ -252,7 +253,8 @@ public class Alter {
                     } else if (alterClause instanceof 
DropPartitionFromIndexClause) {
                         // do nothing
                     } else if (alterClause instanceof AddPartitionClause
-                            || alterClause instanceof AddPartitionLikeClause) {
+                            || alterClause instanceof AddPartitionLikeClause
+                            || alterClause instanceof 
AlterMultiPartitionClause) {
                         needProcessOutsideTableLock = true;
                     } else {
                         throw new DdlException("Invalid alter operation: " + 
alterClause.getOpType());
@@ -508,6 +510,12 @@ public class Alter {
             } else if (alterClause instanceof ModifyTablePropertiesClause) {
                 Map<String, String> properties = alterClause.getProperties();
                 ((SchemaChangeHandler) 
schemaChangeHandler).updateTableProperties(db, tableName, properties);
+            } else if (alterClause instanceof AlterMultiPartitionClause) {
+                if (!((AlterMultiPartitionClause) 
alterClause).isTempPartition()) {
+                    DynamicPartitionUtil.checkAlterAllowed(
+                             (OlapTable) db.getTableOrMetaException(tableName, 
TableType.OLAP));
+                }
+                Env.getCurrentEnv().addMultiPartitions(db, tableName, 
(AlterMultiPartitionClause) alterClause);
             } else {
                 throw new DdlException("Invalid alter operation: " + 
alterClause.getOpType());
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterMultiPartitionClause.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterMultiPartitionClause.java
new file mode 100644
index 00000000000..f7231e6da3e
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterMultiPartitionClause.java
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 org.apache.doris.analysis;
+
+import org.apache.doris.alter.AlterOpType;
+import org.apache.doris.common.AnalysisException;
+
+import java.util.Map;
+
+public class AlterMultiPartitionClause extends AlterTableClause {
+    private PartitionKeyDesc partitionKeyDesc;
+    private Map<String, String> properties;
+    private boolean isTempPartition;
+
+    public AlterMultiPartitionClause(PartitionKeyDesc partitionKeyDesc, 
Map<String, String> properties,
+                                     boolean isTempPartition) {
+        super(AlterOpType.ADD_PARTITION);
+        this.partitionKeyDesc = partitionKeyDesc;
+        this.properties = properties;
+        this.isTempPartition = isTempPartition;
+    }
+
+    @Override
+    public void analyze(Analyzer analyzer) throws AnalysisException {
+    }
+
+    @Override
+    public String toSql() {
+        return String.format("ADD PARTITIONS %s", partitionKeyDesc.toSql());
+    }
+
+    @Override
+    public String toString() {
+        return toSql();
+    }
+
+    @Override
+    public boolean allowOpMTMV() {
+        return false;
+    }
+
+    @Override
+    public boolean needChangeMTMVState() {
+        return false;
+    }
+
+    public PartitionKeyDesc getPartitionKeyDesc() {
+        return partitionKeyDesc;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public boolean isTempPartition() {
+        return isTempPartition;
+    }
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index 907f2573920..121228f569a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -38,6 +38,7 @@ import org.apache.doris.analysis.AlterDatabasePropertyStmt;
 import org.apache.doris.analysis.AlterDatabaseQuotaStmt;
 import org.apache.doris.analysis.AlterDatabaseQuotaStmt.QuotaType;
 import org.apache.doris.analysis.AlterDatabaseRename;
+import org.apache.doris.analysis.AlterMultiPartitionClause;
 import org.apache.doris.analysis.AlterSystemStmt;
 import org.apache.doris.analysis.AlterTableStmt;
 import org.apache.doris.analysis.AlterViewStmt;
@@ -3278,6 +3279,11 @@ public class Env {
             isCreateTable, generatedPartitionId, writeEditLog);
     }
 
+    public void addMultiPartitions(Database db, String tableName, 
AlterMultiPartitionClause multiPartitionClause)
+            throws DdlException {
+        getInternalCatalog().addMultiPartitions(db, tableName, 
multiPartitionClause);
+    }
+
     public void addPartitionLike(Database db, String tableName, 
AddPartitionLikeClause addPartitionLikeClause)
             throws DdlException {
         getInternalCatalog().addPartitionLike(db, tableName, 
addPartitionLikeClause);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index 12093bb6696..234119b992b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -25,6 +25,7 @@ import org.apache.doris.analysis.AlterDatabasePropertyStmt;
 import org.apache.doris.analysis.AlterDatabaseQuotaStmt;
 import org.apache.doris.analysis.AlterDatabaseQuotaStmt.QuotaType;
 import org.apache.doris.analysis.AlterDatabaseRename;
+import org.apache.doris.analysis.AlterMultiPartitionClause;
 import org.apache.doris.analysis.Analyzer;
 import org.apache.doris.analysis.ColumnDef;
 import org.apache.doris.analysis.ColumnDef.DefaultValue;
@@ -42,6 +43,7 @@ import org.apache.doris.analysis.FunctionCallExpr;
 import org.apache.doris.analysis.HashDistributionDesc;
 import org.apache.doris.analysis.KeysDesc;
 import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.analysis.MultiPartitionDesc;
 import org.apache.doris.analysis.PartitionDesc;
 import org.apache.doris.analysis.PartitionKeyDesc;
 import org.apache.doris.analysis.PartitionNames;
@@ -1867,6 +1869,24 @@ public class InternalCatalog implements 
CatalogIf<Database> {
         }
     }
 
+    public void addMultiPartitions(Database db, String tableName, 
AlterMultiPartitionClause multiPartitionClause)
+            throws DdlException {
+        List<SinglePartitionDesc> singlePartitionDescs;
+        try {
+            MultiPartitionDesc multiPartitionDesc = new 
MultiPartitionDesc(multiPartitionClause.getPartitionKeyDesc(),
+                    multiPartitionClause.getProperties());
+            singlePartitionDescs = 
multiPartitionDesc.getSinglePartitionDescList();
+        } catch (AnalysisException e) {
+            throw new DdlException("Failed to analyze multi partition clause: 
" + e.getMessage());
+        }
+
+        for (SinglePartitionDesc singlePartitionDesc : singlePartitionDescs) {
+            AddPartitionClause addPartitionClause = new 
AddPartitionClause(singlePartitionDesc, null,
+                    multiPartitionClause.getProperties(), false);
+            addPartition(db, tableName, addPartitionClause, false, 0, true);
+        }
+    }
+
     public void replayAddPartition(PartitionPersistInfo info) throws 
MetaNotFoundException {
         Database db = (Database) getDbOrMetaException(info.getDbId());
         OlapTable olapTable = (OlapTable) 
db.getTableOrMetaException(info.getTableId(),
diff --git 
a/regression-test/suites/alter_p0/test_alter_add_multi_partition.groovy 
b/regression-test/suites/alter_p0/test_alter_add_multi_partition.groovy
new file mode 100644
index 00000000000..a5a55d94bea
--- /dev/null
+++ b/regression-test/suites/alter_p0/test_alter_add_multi_partition.groovy
@@ -0,0 +1,110 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+suite("test_alter_add_multi_partition") {
+    sql "DROP TABLE IF EXISTS add_multi_partition FORCE"
+
+    // Check if you can create a partition for a leap month
+    sql """
+        CREATE TABLE IF NOT EXISTS add_multi_partition
+        (
+            `k1` LARGEINT NOT NULL,
+            `date` DATE NOT NULL,
+            `k2` VARCHAR(20)
+        )
+        ENGINE=OLAP
+        UNIQUE KEY(`k1`, `date`)
+        PARTITION BY RANGE(`date`)
+        (
+            PARTITION `p_20000201` VALUES [("2000-02-01"), ("2000-02-05"))
+        )
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 1
+        PROPERTIES
+        (
+            "replication_num" = "1"
+        );
+    """
+    List<List<Object>> result1  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result1.size(), 1)
+    sql "ALTER TABLE add_multi_partition ADD PARTITIONS FROM ('2000-02-05') TO 
('2000-03-01') INTERVAL 4 DAY;"
+    List<List<Object>> result2  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result2.size(), 8)
+    def partitionName = sql "show partitions from add_multi_partition where 
PartitionName = 'p_20000229';"
+    for (pn in partitionName) {
+        assertTrue(pn[1] == "p_20000229")
+    }
+    sql "DROP TABLE IF EXISTS add_multi_partition FORCE"
+
+    
+    sql """
+        CREATE TABLE `add_multi_partition` (
+            `k1` LARGEINT NOT NULL,
+            `date` DATE NOT NULL,
+            `k2` VARCHAR(20) NULL
+        ) ENGINE=OLAP
+        UNIQUE KEY(`k1`, `date`)
+        PARTITION BY RANGE(`date`)
+        (PARTITION p_2024_01 VALUES [('2024-01-01'), ('2024-01-08')),
+        PARTITION p_2024_02 VALUES [('2024-01-08'), ('2024-01-15')),
+        PARTITION p_2024_03 VALUES [('2024-01-15'), ('2024-01-22')),
+        PARTITION p_2024_04 VALUES [('2024-01-22'), ('2024-01-29')),
+        PARTITION p_2024_05 VALUES [('2024-01-29'), ('2024-02-05')),
+        PARTITION p_2024_06 VALUES [('2024-02-05'), ('2024-02-12')),
+        PARTITION p_2024_07 VALUES [('2024-02-12'), ('2024-02-19')),
+        PARTITION p_2024_08 VALUES [('2024-02-19'), ('2024-02-26')),
+        PARTITION p_2024_09 VALUES [('2024-02-26'), ('2024-03-01')))
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 1
+        PROPERTIES
+        (
+            "replication_num" = "1"
+        );
+    """
+    List<List<Object>> result3  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result3.size(), 9)
+    sql "ALTER TABLE add_multi_partition ADD PARTITIONS FROM ('2024-04-01') TO 
('2025-01-01') INTERVAL 1 WEEK;"
+    List<List<Object>> result4  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result4.size(), 49)
+    sql "DROP TABLE IF EXISTS add_multi_partition FORCE"
+
+    
+    sql """
+        CREATE TABLE IF NOT EXISTS add_multi_partition
+        (
+            `k1` LARGEINT NOT NULL,
+            `age` SMALLINT,
+            `k2` VARCHAR(20)
+        )
+        ENGINE=OLAP
+        UNIQUE KEY(`k1`, `age`)
+        PARTITION BY RANGE(`age`)
+        (
+            FROM (1) TO (100) INTERVAL 10
+        )
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 1
+        PROPERTIES
+        (
+            "replication_num" = "1"
+        );
+    """
+    List<List<Object>> result7  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result7.size(), 10)
+    sql "ALTER TABLE add_multi_partition ADD PARTITIONS FROM (100) TO (200) 
INTERVAL 10;"
+    List<List<Object>> result8  = sql "show partitions from 
add_multi_partition;"
+    assertEquals(result8.size(), 20)
+    sql "DROP TABLE IF EXISTS add_multi_partition FORCE"
+
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to