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 8e53a731ec8 [fix](schema_change) fix incorrect cache usage of schema 
change expr leading to schema errors (#56602)
8e53a731ec8 is described below

commit 8e53a731ec82cd546cd436820f0da55ccfd074d5
Author: Luwei <[email protected]>
AuthorDate: Tue Sep 30 19:26:38 2025 +0800

    [fix](schema_change) fix incorrect cache usage of schema change expr 
leading to schema errors (#56602)
---
 .../java/org/apache/doris/alter/RollupJobV2.java   |  11 +-
 .../org/apache/doris/alter/SchemaChangeJobV2.java  |  10 +-
 .../test_alter_rollup_table.groovy                 | 136 +++++++++++++++++++++
 3 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
index c60d7ab2363..7701d04753d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
@@ -397,11 +397,12 @@ public class RollupJobV2 extends AlterJobV2 implements 
GsonPostProcessable {
         }
 
         tbl.readLock();
-        Map<Object, Object> objectPool = new ConcurrentHashMap<Object, 
Object>();
         String vaultId = tbl.getStorageVaultId();
         try {
             long expiration = (createTimeMs + timeoutMs) / 1000;
             Preconditions.checkState(tbl.getState() == OlapTableState.ROLLUP);
+            // Create object pool per MaterializedIndex
+            Map<Long, Map<Object, Object>> indexObjectPoolMap = 
Maps.newHashMap();
             for (Map.Entry<Long, MaterializedIndex> entry : 
this.partitionIdToRollupIndex.entrySet()) {
                 long partitionId = entry.getKey();
                 Partition partition = tbl.getPartition(partitionId);
@@ -413,6 +414,14 @@ public class RollupJobV2 extends AlterJobV2 implements 
GsonPostProcessable {
                 Map<String, Expr> defineExprs = Maps.newHashMap();
                 MaterializedIndex rollupIndex = entry.getValue();
                 Map<Long, Long> tabletIdMap = 
this.partitionIdToBaseRollupTabletIdMap.get(partitionId);
+
+                // Get or create object pool for this MaterializedIndex
+                Map<Object, Object> objectPool = 
indexObjectPoolMap.get(rollupIndex.getId());
+                if (objectPool == null) {
+                    objectPool = new ConcurrentHashMap<Object, Object>();
+                    indexObjectPoolMap.put(rollupIndex.getId(), objectPool);
+                }
+
                 for (Tablet rollupTablet : rollupIndex.getTablets()) {
                     long rollupTabletId = rollupTablet.getId();
                     long baseTabletId = tabletIdMap.get(rollupTabletId);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
index e238f310973..526f821c825 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
@@ -485,7 +485,6 @@ public class SchemaChangeJobV2 extends AlterJobV2 
implements GsonPostProcessable
         }
 
         tbl.readLock();
-        Map<Object, Object> objectPool = new ConcurrentHashMap<Object, 
Object>();
         String vaultId = tbl.getStorageVaultId();
         try {
             long expiration = (createTimeMs + timeoutMs) / 1000;
@@ -497,6 +496,8 @@ public class SchemaChangeJobV2 extends AlterJobV2 
implements GsonPostProcessable
             }
 
             Preconditions.checkState(tbl.getState() == 
OlapTableState.SCHEMA_CHANGE);
+            // Create object pool per MaterializedIndex
+            Map<Long, Map<Object, Object>> indexObjectPoolMap = 
Maps.newHashMap();
             for (long partitionId : partitionIndexMap.rowKeySet()) {
                 Partition partition = tbl.getPartition(partitionId);
                 Preconditions.checkNotNull(partition, partitionId);
@@ -509,6 +510,13 @@ public class SchemaChangeJobV2 extends AlterJobV2 
implements GsonPostProcessable
                 for (Map.Entry<Long, MaterializedIndex> entry : 
shadowIndexMap.entrySet()) {
                     long shadowIdxId = entry.getKey();
                     MaterializedIndex shadowIdx = entry.getValue();
+
+                    // Get or create object pool for this MaterializedIndex
+                    Map<Object, Object> objectPool = 
indexObjectPoolMap.get(shadowIdxId);
+                    if (objectPool == null) {
+                        objectPool = new ConcurrentHashMap<Object, Object>();
+                        indexObjectPoolMap.put(shadowIdxId, objectPool);
+                    }
                     long originIdxId = indexIdMap.get(shadowIdxId);
                     Map<String, Expr> defineExprs = Maps.newHashMap();
                     List<Column> fullSchema = 
tbl.getSchemaByIndexId(originIdxId, true);
diff --git 
a/regression-test/suites/schema_change_p0/test_alter_rollup_table.groovy 
b/regression-test/suites/schema_change_p0/test_alter_rollup_table.groovy
new file mode 100644
index 00000000000..fb492c63fe7
--- /dev/null
+++ b/regression-test/suites/schema_change_p0/test_alter_rollup_table.groovy
@@ -0,0 +1,136 @@
+// 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_rollup_table") {
+    def tbName = "test_alter_rollup_table"
+
+    sql "DROP TABLE IF EXISTS ${tbName} FORCE"
+    sql """
+        CREATE TABLE `${tbName}` (
+          `user_id` bigint NOT NULL COMMENT "用户 ID",
+          `event_time` datetime NOT NULL COMMENT "事件时间",
+          `event_date` date NOT NULL,
+          `country` varchar(128) NULL DEFAULT "UNKNOWN",
+          `city` text NULL COMMENT "城市信息",
+          `age` int NULL DEFAULT "0" COMMENT "用户年龄",
+          `is_active` boolean NULL DEFAULT "TRUE" COMMENT "是否活跃",
+          `balance` decimal(18,2) NULL DEFAULT "0.00" COMMENT "账户余额",
+          `score` double NULL COMMENT "浮点分数",
+          `last_login` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 
"最后登录时间",
+          `last_ip` ipv4 NULL DEFAULT "0.0.0.0" COMMENT "最近一次登录 IP",
+          `ipv6_addr` ipv6 NULL COMMENT "IPv6 地址",
+          `json_data` json NULL COMMENT "扩展 JSON 信息",
+          `user_metadata` variant NULL COMMENT "存储用户自定义半结构化数据",
+          `seq_col` bigint NULL DEFAULT "0" COMMENT "顺序列,测试 sequence",
+          `auto_inc_col` bigint NOT NULL AUTO_INCREMENT(1) COMMENT "自增列,用于测试",
+          `create_time` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP COMMENT 
"创建时间",
+          `update_time` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP COMMENT 
"更新时间",
+          `tags` array<varchar(32)> NULL,
+          `metadata` json NULL,
+          `status` int NULL DEFAULT "1",
+          `created_at` datetime NULL DEFAULT CURRENT_TIMESTAMP,
+          `optional_data` varchar(64) NULL,
+          `required_data` int NOT NULL DEFAULT "0",
+          `total_score` bigint NULL DEFAULT "0",
+          `last_status` int NULL DEFAULT "0",
+          `max_value` int NULL DEFAULT "0",
+          `min_value` int NULL DEFAULT "0",
+          
+          `col1` int NULL DEFAULT "0",
+          `col2` varchar(32) NULL,
+          `a_very_long_column_name_that_is_just_under_the_limit` int NULL,
+          `long_default` varchar(255) NULL DEFAULT 
"a_very_long_default_value_that_is_just_under_the_limit_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz",
+          `max_int` int NULL DEFAULT "2147483647",
+          `min_int` int NULL DEFAULT "-2147483648",
+          `high_precision` decimal(38,10) NULL DEFAULT 
"1234567890123456789012345678.1234567890",
+          `test_col` int NULL DEFAULT "0",
+          `consistency_check` int NULL DEFAULT "42",
+          INDEX idx_json_data_inverted (`user_metadata`) USING INVERTED
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`user_id`, `event_time`, `event_date`)
+        DISTRIBUTED BY HASH(`user_id`) BUCKETS 3
+        PROPERTIES (
+        "file_cache_ttl_seconds" = "0",
+        "bloom_filter_columns" = "country, city",
+        "is_being_synced" = "false",
+        "storage_medium" = "hdd",
+        "storage_format" = "V2",
+        "inverted_index_storage_format" = "V2",
+        "light_schema_change" = "true",
+        "disable_auto_compaction" = "false",
+        "enable_single_replica_compaction" = "false",
+        "group_commit_interval_ms" = "10000",
+        "group_commit_data_bytes" = "134217728"
+        );
+
+    """
+
+    sql """
+        insert into ${tbName}
+        (user_id, event_date, event_time, country, city, age, is_active, 
balance, score, last_ip, json_data, seq_col)
+        values
+        (1001, '2025-09-19', '2025-09-19 10:00:00', 'japan', 'tokyo', 30, 1, 
1000.50, 88.8, '192.168.0.1', '{"device":"iphone"}', 1),
+        (1002, '2025-09-19', '2025-09-19 11:30:00', 'usa', null, null, 0, 
500.00, null, '10.0.0.2', '{"device":"android"}', 2);
+    """
+
+
+    sql """
+        ALTER TABLE ${tbName}
+        ADD ROLLUP r_event_user
+        (
+            event_date,
+            event_time,
+            user_id,
+            country,
+            city,
+            age,
+            balance
+        );
+    """
+    
+    sleep(10000)
+
+    sql """
+        ALTER TABLE ${tbName}
+        ADD ROLLUP r_complex
+        (
+            event_date,
+            event_time,
+            user_id,
+            ipv6_addr,
+            last_ip,
+            json_data,
+            create_time,
+            update_time
+        );
+    """
+
+    sleep(10000)
+
+    sql """
+        ALTER TABLE ${tbName} MODIFY COLUMN event_date DATETIME
+    """
+
+    sql """
+        insert into ${tbName}
+        (user_id, event_date, event_time, country, city, age, is_active, 
balance, score, last_ip, json_data, seq_col)
+        values
+        (1003, '2025-09-19', '2025-09-19 10:00:00', 'japan', 'tokyo', 30, 1, 
1000.50, 88.8, '192.168.0.1', '{"device":"iphone"}', 1),
+        (1004, '2025-09-19', '2025-09-19 11:30:00', 'usa', null, null, 0, 
500.00, null, '10.0.0.2', '{"device":"android"}', 2);
+    """
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to