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

kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 8c340964d5d446025c0b6c1510e232626ea5787c
Author: yujun <yu.jun.re...@gmail.com>
AuthorDate: Sat Sep 2 13:54:25 2023 +0800

    [improvement](colocate table) forbit change colocate table's replica 
allocation (#23064)
---
 .../main/java/org/apache/doris/alter/Alter.java    |   3 +
 .../main/java/org/apache/doris/catalog/Env.java    |   8 +-
 .../java/org/apache/doris/catalog/OlapTable.java   |   6 +
 .../java/org/apache/doris/alter/AlterTest.java     |  61 ++++++++++
 .../doris/clone/TabletRepairAndBalanceTest.java    |   5 +-
 .../test_alter_colocate_table.groovy               | 132 +++++++++++++++++++++
 6 files changed, 212 insertions(+), 3 deletions(-)

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 7803174037..7974663549 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
@@ -798,6 +798,9 @@ public class Alter {
         // get value from properties here
         // 1. replica allocation
         ReplicaAllocation replicaAlloc = 
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
+        if (!replicaAlloc.isNotSet()) {
+            olapTable.checkChangeReplicaAllocation();
+        }
         Env.getCurrentSystemInfo().checkReplicaAllocation(replicaAlloc);
         // 2. in memory
         boolean newInMemory = PropertyAnalyzer.analyzeBooleanProp(properties,
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 81e4c9af80..3f874059fd 100755
--- 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
@@ -4400,6 +4400,9 @@ public class Env {
     public void modifyTableDynamicPartition(Database db, OlapTable table, 
Map<String, String> properties)
             throws UserException {
         convertDynamicPartitionReplicaNumToReplicaAllocation(properties);
+        if 
(properties.containsKey(DynamicPartitionProperty.REPLICATION_ALLOCATION)) {
+            table.checkChangeReplicaAllocation();
+        }
         Map<String, String> logProperties = new HashMap<>(properties);
         TableProperty tableProperty = table.getTableProperty();
         if (tableProperty == null) {
@@ -4459,6 +4462,7 @@ public class Env {
         }
 
         ReplicaAllocation replicaAlloc = 
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
+        table.checkChangeReplicaAllocation();
         Env.getCurrentSystemInfo().checkReplicaAllocation(replicaAlloc);
         Preconditions.checkState(!replicaAlloc.isNotSet());
         boolean isInMemory = partitionInfo.getIsInMemory(partition.getId());
@@ -4488,8 +4492,10 @@ public class Env {
      * @param properties
      */
     // The caller need to hold the table write lock
-    public void modifyTableDefaultReplicaAllocation(Database db, OlapTable 
table, Map<String, String> properties) {
+    public void modifyTableDefaultReplicaAllocation(Database db, OlapTable 
table,
+            Map<String, String> properties) throws UserException {
         Preconditions.checkArgument(table.isWriteLockHeldByCurrentThread());
+        table.checkChangeReplicaAllocation();
         table.setReplicaAllocation(properties);
         ModifyTablePropertyOperationLog info =
                 new ModifyTablePropertyOperationLog(db.getId(), table.getId(), 
table.getName(),
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index 0b6c5ef937..08f03c0ad1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -1697,6 +1697,12 @@ public class OlapTable extends Table {
         }
     }
 
+    public void checkChangeReplicaAllocation() throws DdlException {
+        if (isColocateTable()) {
+            throw new DdlException("Cannot change replication allocation of 
colocate table.");
+        }
+    }
+
     public void setReplicationAllocation(ReplicaAllocation replicaAlloc) {
         getOrCreatTableProperty().setReplicaAlloc(replicaAlloc);
     }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/alter/AlterTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/alter/AlterTest.java
index af70ca249a..a3ddd9991a 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/alter/AlterTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/alter/AlterTest.java
@@ -117,6 +117,37 @@ public class AlterTest {
                 + "    PARTITION p2 values less than('2020-03-01')\n" + ")\n" 
+ "DISTRIBUTED BY HASH(k2) BUCKETS 3\n"
                 + "PROPERTIES('replication_num' = '1');");
 
+        createTable("CREATE TABLE test.colocate_tbl1\n" + "(\n" + "    k1 
date,\n" + "    k2 int,\n" + "    v1 int \n"
+                + ") ENGINE=OLAP\n" + "UNIQUE KEY (k1,k2)\n"
+                + "DISTRIBUTED BY HASH(k2) BUCKETS 3\n"
+                + "PROPERTIES('replication_num' = '1', 'colocate_with' = 
'group_1');");
+
+        createTable("CREATE TABLE test.colocate_tbl2\n" + "(\n" + "    k1 
date,\n" + "    k2 int,\n" + "    v1 int \n"
+                + ") ENGINE=OLAP\n" + "UNIQUE KEY (k1,k2)\n" + "PARTITION BY 
RANGE(k1)\n" + "(\n"
+                + "    PARTITION p1 values less than('2020-02-01'),\n"
+                + "    PARTITION p2 values less than('2020-03-01')\n" + ")\n" 
+ "DISTRIBUTED BY HASH(k2) BUCKETS 3\n"
+                + "PROPERTIES('replication_num' = '1', 'colocate_with' = 
'group_2');");
+
+        createTable("CREATE TABLE test.colocate_tbl3 (\n"
+                + "`uuid` varchar(255) NULL,\n"
+                + "`action_datetime` date NULL\n"
+                + ")\n"
+                + "DUPLICATE KEY(uuid)\n"
+                + "PARTITION BY RANGE(action_datetime)()\n"
+                + "DISTRIBUTED BY HASH(uuid) BUCKETS 3\n"
+                + "PROPERTIES\n"
+                + "(\n"
+                + "\"colocate_with\" = \"group_3\",\n"
+                + "\"dynamic_partition.enable\" = \"true\",\n"
+                + "\"dynamic_partition.time_unit\" = \"DAY\",\n"
+                + "\"dynamic_partition.end\" = \"3\",\n"
+                + "\"dynamic_partition.prefix\" = \"p\",\n"
+                + "\"dynamic_partition.buckets\" = \"32\",\n"
+                + "\"dynamic_partition.replication_num\" = \"1\",\n"
+                + "\"dynamic_partition.create_history_partition\"=\"true\",\n"
+                + "\"dynamic_partition.start\" = \"-3\"\n"
+                + ");\n");
+
         createTable(
                 "CREATE TABLE test.tbl6\n" + "(\n" + "    k1 datetime(3),\n" + 
"    k2 datetime(3),\n"
                         + "    v1 int \n,"
@@ -252,6 +283,36 @@ public class AlterTest {
         alterTable(stmt, true);
     }
 
+    @Test
+    public void alterTableModifyRepliaAlloc() throws Exception {
+        String[] tables = new String[]{"test.colocate_tbl1", 
"test.colocate_tbl2"};
+        final String errChangeReplicaAlloc = "Cannot change replication 
allocation of colocate table";
+        for (int i = 0; i < tables.length; i++) {
+            String sql = "alter table " + tables[i] + " set 
('default.replication_allocation' = 'tag.location.default:1')";
+            AlterTableStmt alterTableStmt2 = (AlterTableStmt) 
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+            ExceptionChecker.expectThrowsWithMsg(DdlException.class, 
errChangeReplicaAlloc,
+                    () -> Env.getCurrentEnv().alterTable(alterTableStmt2));
+
+            sql = "alter table " + tables[i] + " modify partition (*) set (\n"
+                + "'replication_allocation' = 'tag.location.default:1')";
+            AlterTableStmt alterTableStmt3 = (AlterTableStmt) 
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+            ExceptionChecker.expectThrowsWithMsg(DdlException.class, 
errChangeReplicaAlloc,
+                    () -> Env.getCurrentEnv().alterTable(alterTableStmt3));
+        }
+
+        String sql = "alter table test.colocate_tbl1 set 
('replication_allocation' = 'tag.location.default:1')";
+        AlterTableStmt alterTableStmt1 = (AlterTableStmt) 
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+        ExceptionChecker.expectThrowsWithMsg(DdlException.class, 
errChangeReplicaAlloc,
+                () -> Env.getCurrentEnv().alterTable(alterTableStmt1));
+
+        sql = "alter table test.colocate_tbl3 set (\n"
+            + "'dynamic_partition.replication_allocation' = 
'tag.location.default:1'\n"
+            + " );";
+        AlterTableStmt alterTableStmt4 = (AlterTableStmt) 
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+        ExceptionChecker.expectThrowsWithMsg(DdlException.class, 
errChangeReplicaAlloc,
+                () -> Env.getCurrentEnv().alterTable(alterTableStmt4));
+    }
+
     @Test
     public void alterTableModifyComment() throws Exception {
         Database db = 
Env.getCurrentInternalCatalog().getDbOrMetaException("default_cluster:test");
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/clone/TabletRepairAndBalanceTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/clone/TabletRepairAndBalanceTest.java
index 0e9f1446c7..1524ec3a88 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/clone/TabletRepairAndBalanceTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/clone/TabletRepairAndBalanceTest.java
@@ -404,9 +404,10 @@ public class TabletRepairAndBalanceTest {
                 + " set ('replication_allocation' = 'tag.location.zone1:4')";
         ExceptionChecker.expectThrows(AnalysisException.class, () -> 
alterTable(alterStr4));
 
-        // change col_tbl1's default replica allocation to zone2:2, which is 
allowed
+        // change col_tbl1's default replica allocation to zone2:2, which is 
forbidden
         String alterStr5 = "alter table test.col_tbl1 set 
('default.replication_allocation' = 'tag.location.zone2:2')";
-        ExceptionChecker.expectThrowsNoException(() -> alterTable(alterStr5));
+        ExceptionChecker.expectThrowsWithMsg(DdlException.class,
+                "Cannot change replication allocation of colocate table", () 
-> alterTable(alterStr5));
 
         // Drop all tables
         String dropStmt1 = "drop table test.tbl1 force";
diff --git 
a/regression-test/suites/schema_change_p0/test_alter_colocate_table.groovy 
b/regression-test/suites/schema_change_p0/test_alter_colocate_table.groovy
new file mode 100644
index 0000000000..110db9ce75
--- /dev/null
+++ b/regression-test/suites/schema_change_p0/test_alter_colocate_table.groovy
@@ -0,0 +1,132 @@
+// 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_colocate_table") {
+    def tbls = ["col_tbl1", "col_tbl2", "col_tbl3"]
+    for (def tbl : tbls) {
+        sql """
+            DROP TABLE IF EXISTS ${tbl} FORCE
+        """
+    }
+
+    sql """
+        CREATE TABLE IF NOT EXISTS col_tbl1
+        (
+           k1 date,
+           k2 int
+        )
+        ENGINE=OLAP
+        UNIQUE KEY (k1,k2)
+        DISTRIBUTED BY HASH(k2) BUCKETS 3
+        PROPERTIES
+        (
+            "replication_allocation" = "tag.location.default:1",
+            "colocate_with" = 'x_group_1'
+        )
+    """
+
+    sql """
+        CREATE TABLE IF NOT EXISTS col_tbl2
+        (
+           k1 date,
+           k2 int
+        )
+        ENGINE=OLAP
+        UNIQUE KEY (k1,k2)
+        PARTITION BY RANGE(k1)
+        (
+           PARTITION p1 values less than('2020-02-01'),
+           PARTITION p2 values less than('2020-03-01')
+        )
+        DISTRIBUTED BY HASH(k2) BUCKETS 3
+        PROPERTIES
+        (
+            "replication_allocation" = "tag.location.default:1",
+            "colocate_with" = 'x_group_2'
+        )
+    """
+
+    sql """
+        CREATE TABLE col_tbl3
+        (
+         `uuid` varchar(255) NULL,
+         `action_datetime` date NULL
+        )
+        DUPLICATE KEY(uuid)
+        PARTITION BY RANGE(action_datetime)()
+        DISTRIBUTED BY HASH(uuid) BUCKETS 3
+        PROPERTIES
+        (
+            "replication_allocation" = "tag.location.default:1",
+            "colocate_with" = "x_group_3",
+            "dynamic_partition.enable" = "true",
+            "dynamic_partition.time_unit" = "DAY",
+            "dynamic_partition.end" = "3",
+            "dynamic_partition.prefix" = "p",
+            "dynamic_partition.buckets" = "3",
+            "dynamic_partition.replication_num" = "1",
+            "dynamic_partition.create_history_partition"= "true",
+            "dynamic_partition.replication_allocation" = 
"tag.location.default:1",
+            "dynamic_partition.start" = "-3"
+         );
+    """
+
+    def errMsg = "Cannot change replication allocation of colocate table"
+
+    test {
+        sql """
+           ALTER TABLE col_tbl1 set (
+                "replication_allocation" = "tag.location.default:1"
+           )
+        """
+        exception errMsg
+    }
+
+    test {
+        sql """
+           ALTER TABLE col_tbl3 set (
+                "dynamic_partition.replication_allocation" = 
"tag.location.default:1"
+           )
+        """
+        exception errMsg
+    }
+
+    for (def tbl : tbls) {
+        test {
+            sql """
+              ALTER TABLE ${tbl} set (
+                "default.replication_allocation" = "tag.location.default:1"
+              )
+            """
+
+            exception errMsg
+        }
+
+        test {
+            sql """
+              ALTER TABLE ${tbl} MODIFY PARTITION (*) set (
+                "replication_allocation" = "tag.location.default:1"
+              )
+            """
+
+            exception errMsg
+        }
+
+        sql "DROP TABLE ${tbl} FORCE"
+    }
+}
+


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

Reply via email to