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 f467914e67f [fix](schema-change) Fix sync MV loss due to index change 
(#54285)
f467914e67f is described below

commit f467914e67f8885ad372c4471831d86942351f14
Author: Siyang Tang <[email protected]>
AuthorDate: Sun Aug 10 22:41:49 2025 +0800

    [fix](schema-change) Fix sync MV loss due to index change (#54285)
    
    ### What problem does this PR solve?
    
    Problem Summary:
    Creation of shadow index did not take define stmt and where clause of MV
    into account, therefore, after index creation,
    MV info will be lost.
    
    This bug only affect index change on MV related columns. Other types of
    heavy sc are not allowed on MV related columns.
---
 .../org/apache/doris/alter/SchemaChangeJobV2.java  |   8 ++-
 .../test_index_change_after_mv.out                 | Bin 0 -> 326 bytes
 .../test_index_change_after_mv.groovy              |  73 +++++++++++++++++++++
 3 files changed, 79 insertions(+), 2 deletions(-)

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 ef7f5b933ad..3519aaf70e1 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
@@ -30,6 +30,7 @@ import org.apache.doris.catalog.Index;
 import org.apache.doris.catalog.KeysType;
 import org.apache.doris.catalog.MaterializedIndex;
 import org.apache.doris.catalog.MaterializedIndex.IndexState;
+import org.apache.doris.catalog.MaterializedIndexMeta;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.OlapTable.OlapTableState;
 import org.apache.doris.catalog.Partition;
@@ -439,12 +440,15 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
         }
 
         for (long shadowIdxId : indexIdMap.keySet()) {
+            MaterializedIndexMeta originalIndexMeta = 
tbl.getIndexMetaByIndexId(indexIdMap.get(shadowIdxId));
             tbl.setIndexMeta(shadowIdxId, indexIdToName.get(shadowIdxId), 
indexSchemaMap.get(shadowIdxId),
                     
indexSchemaVersionAndHashMap.get(shadowIdxId).schemaVersion,
                     indexSchemaVersionAndHashMap.get(shadowIdxId).schemaHash,
                     indexShortKeyMap.get(shadowIdxId), TStorageType.COLUMN,
-                    tbl.getKeysTypeByIndexId(indexIdMap.get(shadowIdxId)),
-                    indexChange ? indexes : 
tbl.getIndexMetaByIndexId(indexIdMap.get(shadowIdxId)).getIndexes());
+                    tbl.getKeysTypeByIndexId(indexIdMap.get(shadowIdxId)), 
originalIndexMeta.getDefineStmt(),
+                    indexChange ? indexes : originalIndexMeta.getIndexes());
+            MaterializedIndexMeta shadowIndexMeta = 
tbl.getIndexMetaByIndexId(shadowIdxId);
+            shadowIndexMeta.setWhereClause(originalIndexMeta.getWhereClause());
         }
 
         tbl.rebuildFullSchema();
diff --git 
a/regression-test/data/schema_change_p0/test_index_change_after_mv.out 
b/regression-test/data/schema_change_p0/test_index_change_after_mv.out
new file mode 100644
index 00000000000..be9d64912f1
Binary files /dev/null and 
b/regression-test/data/schema_change_p0/test_index_change_after_mv.out differ
diff --git 
a/regression-test/suites/schema_change_p0/test_index_change_after_mv.groovy 
b/regression-test/suites/schema_change_p0/test_index_change_after_mv.groovy
new file mode 100644
index 00000000000..2b06812cb10
--- /dev/null
+++ b/regression-test/suites/schema_change_p0/test_index_change_after_mv.groovy
@@ -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.
+
+import org.awaitility.Awaitility
+
+import static java.util.concurrent.TimeUnit.SECONDS
+
+suite("test_index_change_after_mv") {
+    def tableName = "test_index_change_after_mv"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+        CREATE TABLE IF NOT EXISTS ${tableName} (
+                name varchar(50),
+                age int NOT NULL,
+                grade int NOT NULL,
+                studentInfo char(100),
+                tearchComment string,
+            )
+            DUPLICATE KEY(`name`)
+            DISTRIBUTED BY HASH(`name`) BUCKETS 10
+            properties("replication_num" = "1");
+    """
+
+    def mvName = """${tableName}_1"""
+
+    sql """ INSERT INTO ${tableName} VALUES("steve", 0, 2, "xxx", "xxx") """
+
+    sql """ 
+        CREATE MATERIALIZED VIEW ${mvName} AS SELECT name, age, grade FROM 
${tableName} WHERE name = "steve" AND age = 0
+    """
+
+    def getJobState = { tblName ->
+        def jobStateResult = sql """  SHOW ALTER TABLE MATERIALIZED VIEW WHERE 
TableName='${tblName}' ORDER BY CreateTime DESC LIMIT 1; """
+        return jobStateResult[0][8]
+    }
+
+    def max_try_secs = 60
+    Awaitility.await().atMost(max_try_secs, SECONDS).pollInterval(2, 
SECONDS).until{
+        String res = getJobState(tableName)
+        if (res == "FINISHED" || res == "CANCELLED") {
+            assertEquals("FINISHED", res)
+            sleep(3000)
+            return true
+        }
+        return false
+    }
+
+    sql """
+        CREATE INDEX ${tableName}_idx ON ${tableName}(age) USING INVERTED 
COMMENT 'inverted index age_idx_1'
+    """
+
+    waitForSchemaChangeDone({
+        sql " SHOW ALTER TABLE COLUMN WHERE TableName='${tableName}' ORDER BY 
createtime DESC LIMIT 1 "
+    })
+
+    qt_sql """
+        SHOW CREATE MATERIALIZED VIEW ${mvName} on ${tableName}
+    """
+}


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

Reply via email to