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

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


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 95f10aa8a15 branch-2.1:[fix](mtmv) fix when compatible fail, will 
throw NPE (#49875) (#52273)
95f10aa8a15 is described below

commit 95f10aa8a15625ac0e01ff2925c83597f3ab114c
Author: zhangdong <[email protected]>
AuthorDate: Sat Jun 28 10:54:44 2025 +0800

    branch-2.1:[fix](mtmv) fix when compatible fail, will throw NPE (#49875) 
(#52273)
    
    pick: https://github.com/apache/doris/pull/49875
---
 .../main/java/org/apache/doris/alter/Alter.java    |  5 ++
 .../main/java/org/apache/doris/catalog/MTMV.java   | 17 ++++++
 .../java/org/apache/doris/mtmv/BaseTableInfo.java  | 16 +++++-
 .../org/apache/doris/mtmv/MTMVPartitionInfo.java   |  2 +-
 .../doris/mtmv/MTMVRefreshPartitionSnapshot.java   | 61 +++++++++++-----------
 .../org/apache/doris/mtmv/MTMVRefreshSnapshot.java |  2 +-
 .../java/org/apache/doris/mtmv/MTMVRelation.java   |  4 +-
 .../org/apache/doris/mtmv/MTMVRelationManager.java | 43 +++++++--------
 .../org/apache/doris/mtmv/MTMVRewriteUtil.java     |  5 +-
 .../java/org/apache/doris/mtmv/MTMVStatus.java     |  6 +++
 .../org/apache/doris/nereids/StatementContext.java |  6 +++
 .../nereids/rules/analysis/CollectRelation.java    |  8 ++-
 .../InitConsistentMaterializationContextHook.java  |  8 +--
 .../mv/InitMaterializationContextHook.java         |  7 +--
 .../java/org/apache/doris/mtmv/AlterMTMVTest.java  |  2 +-
 .../org/apache/doris/mtmv/MTMVRewriteUtilTest.java | 12 +++--
 .../doris/nereids/memo/StructInfoMapTest.java      | 18 +++++++
 .../doris/nereids/mv/IdStatisticsMapTest.java      |  6 +++
 .../doris/nereids/mv/MvTableIdIsLongTest.java      |  6 +++
 .../nereids/mv/OptimizeGetAvailableMvsTest.java    | 20 +++++++
 .../org/apache/doris/nereids/util/PlanChecker.java | 11 ++++
 .../mv/dml/insert/dml_insert_and_overwrite.groovy  |  9 ++--
 .../mv/dml/outfile/dml_into_outfile.groovy         |  5 +-
 23 files changed, 191 insertions(+), 88 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 3b5c64b7ff2..95e9d92aa4a 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
@@ -1009,6 +1009,11 @@ public class Alter {
                 case ADD_TASK:
                     mtmv.addTaskResult(alterMTMV.getTask(), 
alterMTMV.getRelation(), alterMTMV.getPartitionSnapshots(),
                             isReplay);
+                    // If it is not a replay thread, it means that the current 
service is already a new version
+                    // and does not require compatibility
+                    if (isReplay) {
+                        mtmv.compatible(Env.getCurrentEnv().getCatalogMgr());
+                    }
                     break;
                 default:
                     throw new RuntimeException("Unknown type value: " + 
alterMTMV.getOpType());
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java
index ea4e94d5c97..c82c749120b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java
@@ -480,6 +480,10 @@ public class MTMV extends OlapTable {
         this.refreshSnapshot = refreshSnapshot;
     }
 
+    public boolean canBeCandidate() {
+        return getStatus().canBeCandidate();
+    }
+
     public void readMvLock() {
         this.mvRwLock.readLock().lock();
     }
@@ -556,6 +560,19 @@ public class MTMV extends OlapTable {
      * The logic here is to be compatible with older versions by converting ID 
to name
      */
     public void compatible(CatalogMgr catalogMgr) {
+        try {
+            compatibleInternal(catalogMgr);
+            Env.getCurrentEnv().getMtmvService().unregisterMTMV(this);
+            Env.getCurrentEnv().getMtmvService().registerMTMV(this, 
this.getDatabase().getId());
+        } catch (Throwable e) {
+            LOG.warn("MTMV compatible failed, dbName: {}, mvName: {}, errMsg: 
{}", getQualifiedDbName(), name,
+                    e.getMessage());
+            status.setState(MTMVState.SCHEMA_CHANGE);
+            status.setSchemaChangeDetail("compatible failed, please refresh or 
recreate it, reason: " + e.getMessage());
+        }
+    }
+
+    private void compatibleInternal(CatalogMgr catalogMgr) throws Exception {
         if (mvPartitionInfo != null) {
             mvPartitionInfo.compatible(catalogMgr);
         }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/BaseTableInfo.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/BaseTableInfo.java
index 2f0810c7a72..49f0d4f948b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/BaseTableInfo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/BaseTableInfo.java
@@ -159,10 +159,18 @@ public class BaseTableInfo {
                 + '}';
     }
 
-    public void compatible(CatalogMgr catalogMgr) {
+    public void compatible(CatalogMgr catalogMgr) throws Exception {
         if (!StringUtils.isEmpty(ctlName)) {
             return;
         }
+        // should not get meta from external catalog when replay, because the 
timeout period may be very long
+        if (ctlId != InternalCatalog.INTERNAL_CATALOG_ID) {
+            String msg = String.format(
+                    "Can not compatibility external table, ctlId: %s, dbId: 
%s, tableId: %s",
+                    ctlId, dbId, tableId);
+            LOG.warn(msg);
+            throw new Exception(msg);
+        }
         try {
             CatalogIf catalog = 
catalogMgr.getCatalogOrAnalysisException(ctlId);
             DatabaseIf db = catalog.getDbOrAnalysisException(dbId);
@@ -171,7 +179,11 @@ public class BaseTableInfo {
             this.dbName = db.getFullName();
             this.tableName = table.getName();
         } catch (AnalysisException e) {
-            LOG.warn("MTMV compatible failed, ctlId: {}, dbId: {}, tableId: 
{}", ctlId, dbId, tableId, e);
+            String msg = String.format(
+                    "Failed to get name based on id during compatibility 
process, ctlId: %s, dbId: %s, tableId: %s",
+                    ctlId, dbId, tableId);
+            LOG.warn(msg, e);
+            throw new Exception(msg);
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionInfo.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionInfo.java
index 7eae44db0af..682273a93cd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionInfo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionInfo.java
@@ -152,7 +152,7 @@ public class MTMVPartitionInfo {
         }
     }
 
-    public void compatible(CatalogMgr catalogMgr) {
+    public void compatible(CatalogMgr catalogMgr) throws Exception {
         if (relatedTable == null) {
             return;
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshPartitionSnapshot.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshPartitionSnapshot.java
index a8de5b6597b..2601ace5ed6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshPartitionSnapshot.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshPartitionSnapshot.java
@@ -20,8 +20,9 @@ package org.apache.doris.mtmv;
 import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Partition;
-import org.apache.doris.catalog.TableIf;
 import org.apache.doris.common.AnalysisException;
+import org.apache.doris.datasource.InternalCatalog;
+import org.apache.doris.mtmv.MTMVPartitionInfo.MTMVPartitionType;
 
 import com.google.common.collect.Maps;
 import com.google.gson.annotations.SerializedName;
@@ -77,29 +78,28 @@ public class MTMVRefreshPartitionSnapshot {
                 + '}';
     }
 
-    public void compatible(MTMV mtmv) {
-        try {
-            // snapshot add partitionId resolve problem of insert overwrite
-            compatiblePartitions(mtmv);
-        } catch (Throwable e) {
-            LOG.warn("MTMV compatiblePartitions failed, mtmv: {}", 
mtmv.getName(), e);
-        }
-        try {
-            // change table id to BaseTableInfo
-            compatibleTables(mtmv);
-        } catch (Throwable e) {
-            LOG.warn("MTMV compatibleTables failed, mtmv: {}", mtmv.getName(), 
e);
-        }
-
-        try {
-            // snapshot add tableId resolve problem of recreate table
-            compatibleTablesSnapshot();
-        } catch (Throwable e) {
-            LOG.warn("MTMV compatibleTables failed, mtmv: {}", mtmv.getName(), 
e);
-        }
+    public void compatible(MTMV mtmv) throws Exception {
+        // snapshot add partitionId resolve problem of insert overwrite
+        compatiblePartitions(mtmv);
+        // change table id to BaseTableInfo
+        compatibleTables(mtmv);
+        // snapshot add tableId resolve problem of recreate table
+        compatibleTablesSnapshot();
     }
 
     private void compatiblePartitions(MTMV mtmv) throws AnalysisException {
+        if 
(mtmv.getMvPartitionInfo().getPartitionType().equals(MTMVPartitionType.SELF_MANAGE))
 {
+            return;
+        }
+        // Only olapTable has historical data issues that require compatibility
+        if (mtmv.getMvPartitionInfo().getRelatedTableInfo().getCtlId() != 
InternalCatalog.INTERNAL_CATALOG_ID) {
+            return;
+        }
+        MTMVRelatedTableIf relatedTableIf = 
mtmv.getMvPartitionInfo().getRelatedTable();
+        // Only olapTable has historical data issues that require compatibility
+        if (!(relatedTableIf instanceof OlapTable)) {
+            return;
+        }
         if (!checkHasDataWithoutPartitionId()) {
             return;
         }
@@ -108,6 +108,8 @@ public class MTMVRefreshPartitionSnapshot {
             MTMVVersionSnapshot versionSnapshot = (MTMVVersionSnapshot) 
entry.getValue();
             if (versionSnapshot.getId() == 0) {
                 Partition partition = 
relatedTable.getPartition(entry.getKey());
+                // if not find partition, may be partition has been dropped,
+                // the impact is that MTMV will consider this partition to be 
async
                 if (partition != null) {
                     (versionSnapshot).setId(partition.getId());
                 }
@@ -131,12 +133,7 @@ public class MTMVRefreshPartitionSnapshot {
         for (Entry<BaseTableInfo, MTMVSnapshotIf> entry : 
tablesInfo.entrySet()) {
             MTMVVersionSnapshot versionSnapshot = (MTMVVersionSnapshot) 
entry.getValue();
             if (versionSnapshot.getId() == 0) {
-                try {
-                    TableIf table = MTMVUtil.getTable(entry.getKey());
-                    versionSnapshot.setId(table.getId());
-                } catch (AnalysisException e) {
-                    LOG.warn("MTMV compatibleTablesSnapshot failed, can not 
get table by: {}", entry.getKey());
-                }
+                versionSnapshot.setId(entry.getKey().getTableId());
             }
         }
     }
@@ -150,7 +147,7 @@ public class MTMVRefreshPartitionSnapshot {
         return false;
     }
 
-    private void compatibleTables(MTMV mtmv) {
+    private void compatibleTables(MTMV mtmv) throws Exception {
         if (tables.size() == tablesInfo.size()) {
             return;
         }
@@ -164,8 +161,12 @@ public class MTMVRefreshPartitionSnapshot {
             if (tableInfo.isPresent()) {
                 tablesInfo.put(tableInfo.get(), entry.getValue());
             } else {
-                LOG.warn("MTMV compatibleTables failed, tableId: {}, 
relationTables: {}", entry.getKey(),
-                        relation.getBaseTablesOneLevel());
+                String msg = String.format(
+                        "Failed to get table info based on id during 
compatibility process, "
+                                + "tableId: %s, relationTables: %s",
+                        entry.getKey(), relation.getBaseTablesOneLevel());
+                LOG.warn(msg);
+                throw new Exception(msg);
             }
         }
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSnapshot.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSnapshot.java
index 74fc3cc1c5c..0d9665cb446 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSnapshot.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSnapshot.java
@@ -91,7 +91,7 @@ public class MTMVRefreshSnapshot {
                 + '}';
     }
 
-    public void compatible(MTMV mtmv) {
+    public void compatible(MTMV mtmv) throws Exception {
         if (MapUtils.isEmpty(partitionSnapshots)) {
             return;
         }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelation.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelation.java
index 87a0199f128..148d2d00884 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelation.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelation.java
@@ -65,13 +65,13 @@ public class MTMVRelation {
                 + '}';
     }
 
-    public void compatible(CatalogMgr catalogMgr) {
+    public void compatible(CatalogMgr catalogMgr) throws Exception {
         compatible(catalogMgr, baseTables);
         compatible(catalogMgr, baseViews);
         compatible(catalogMgr, baseTablesOneLevel);
     }
 
-    private void compatible(CatalogMgr catalogMgr, Set<BaseTableInfo> infos) {
+    private void compatible(CatalogMgr catalogMgr, Set<BaseTableInfo> infos) 
throws Exception {
         if (CollectionUtils.isEmpty(infos)) {
             return;
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
index c45558ec8cf..ba498636d73 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
@@ -78,48 +78,43 @@ public class MTMVRelationManager implements MTMVHookService 
{
     /**
      * if At least one partition is available, return this mtmv
      *
-     * @param tableInfos
+     * @param candidateMTMVs
      * @param ctx
      * @return
      */
-    public Set<MTMV> getAvailableMTMVs(List<BaseTableInfo> tableInfos, 
ConnectContext ctx,
+    public Set<MTMV> getAvailableMTMVs(Set<MTMV> candidateMTMVs, 
ConnectContext ctx,
             boolean forceConsistent, BiPredicate<ConnectContext, MTMV> 
predicate) {
         Set<MTMV> res = Sets.newLinkedHashSet();
-        Set<BaseTableInfo> mvInfos = getMTMVInfos(tableInfos);
         Map<List<String>, Set<String>> queryUsedPartitions = 
PartitionCompensator.getQueryUsedPartitions(
                 ctx.getStatementContext(), new BitSet());
-
-        for (BaseTableInfo tableInfo : mvInfos) {
-            try {
-                MTMV mtmv = (MTMV) MTMVUtil.getTable(tableInfo);
-                if (predicate.test(ctx, mtmv)) {
-                    continue;
-                }
-                if (!mtmv.isUseForRewrite()) {
-                    continue;
-                }
-                BaseTableInfo relatedTableInfo = 
mtmv.getMvPartitionInfo().getRelatedTableInfo();
-                if (isMVPartitionValid(mtmv, ctx, forceConsistent,
-                        relatedTableInfo == null ? null : 
queryUsedPartitions.get(relatedTableInfo.toList()))) {
-                    res.add(mtmv);
-                }
-            } catch (Exception e) {
-                // not throw exception to client, just ignore it
-                LOG.warn("getTable failed: {}", tableInfo.toString(), e);
+        for (MTMV mtmv : candidateMTMVs) {
+            if (predicate.test(ctx, mtmv)) {
+                continue;
+            }
+            if (!mtmv.isUseForRewrite()) {
+                continue;
+            }
+            BaseTableInfo relatedTableInfo = 
mtmv.getMvPartitionInfo().getRelatedTableInfo();
+            if (isMVPartitionValid(mtmv, ctx, forceConsistent,
+                    relatedTableInfo == null ? null : 
queryUsedPartitions.get(relatedTableInfo.toList()))) {
+                res.add(mtmv);
             }
         }
         return res;
     }
 
     /**
-     * get all mtmv related to tableInfos.
+     * get candidate mtmv related to tableInfos.
      */
-    public Set<MTMV> getAllMTMVs(List<BaseTableInfo> tableInfos) {
+    public Set<MTMV> getCandidateMTMVs(List<BaseTableInfo> tableInfos) {
         Set<MTMV> mtmvs = Sets.newLinkedHashSet();
         Set<BaseTableInfo> mvInfos = getMTMVInfos(tableInfos);
         for (BaseTableInfo tableInfo : mvInfos) {
             try {
-                mtmvs.add((MTMV) MTMVUtil.getTable(tableInfo));
+                MTMV mtmv = (MTMV) MTMVUtil.getTable(tableInfo);
+                if (mtmv.canBeCandidate()) {
+                    mtmvs.add(mtmv);
+                }
             } catch (Exception e) {
                 // not throw exception to client, just ignore it
                 LOG.warn("getTable failed: {}", tableInfo.toString(), e);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRewriteUtil.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRewriteUtil.java
index afaad55a34b..58b2a37d504 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRewriteUtil.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRewriteUtil.java
@@ -20,8 +20,6 @@ package org.apache.doris.mtmv;
 import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.Partition;
 import org.apache.doris.common.AnalysisException;
-import org.apache.doris.mtmv.MTMVRefreshEnum.MTMVRefreshState;
-import org.apache.doris.mtmv.MTMVRefreshEnum.MTMVState;
 import org.apache.doris.qe.ConnectContext;
 
 import com.google.common.collect.Lists;
@@ -56,8 +54,7 @@ public class MTMVRewriteUtil {
             return res;
         }
         // check mv is normal
-        MTMVStatus mtmvStatus = mtmv.getStatus();
-        if (mtmvStatus.getState() != MTMVState.NORMAL || 
mtmvStatus.getRefreshState() == MTMVRefreshState.INIT) {
+        if (!mtmv.canBeCandidate()) {
             return res;
         }
         // if relatedPartitions is empty but not null, which means query no 
partitions
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVStatus.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVStatus.java
index b1761b9e973..aa058e628c6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVStatus.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVStatus.java
@@ -82,6 +82,12 @@ public class MTMVStatus {
         return this;
     }
 
+    public boolean canBeCandidate() {
+        // MTMVRefreshState.FAIL also can be candidate, because may have some 
sync partitions
+        return getState() == MTMVState.NORMAL
+                && getRefreshState() != MTMVRefreshState.INIT;
+    }
+
     @Override
     public String toString() {
         return "MTMVStatus{"
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
index 009c51595b9..cc04721ab80 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
@@ -19,6 +19,7 @@ package org.apache.doris.nereids;
 
 import org.apache.doris.analysis.StatementBase;
 import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.Partition;
 import org.apache.doris.catalog.TableIf;
 import org.apache.doris.catalog.View;
@@ -189,6 +190,7 @@ public class StatementContext implements Closeable {
     // if query is: select * from t2 join t5
     // mtmvRelatedTables is mv1, mv2, mv3, t1, t2, t3, t4, t5
     private final Map<List<String>, TableIf> mtmvRelatedTables = 
Maps.newHashMap();
+    private final Set<MTMV> candidateMTMVs = Sets.newHashSet();
     // insert into target tables
     private final Map<List<String>, TableIf> insertTargetTables = 
Maps.newHashMap();
     // save view's def to avoid them change before lock
@@ -306,6 +308,10 @@ public class StatementContext implements Closeable {
         return mtmvRelatedTables;
     }
 
+    public Set<MTMV> getCandidateMTMVs() {
+        return candidateMTMVs;
+    }
+
     public Map<List<String>, TableIf> getTables() {
         return tables;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CollectRelation.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CollectRelation.java
index 410028ff735..c529cfb580b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CollectRelation.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CollectRelation.java
@@ -207,9 +207,12 @@ public class CollectRelation implements 
AnalysisRuleFactory {
         }
         if (shouldCollect) {
             Set<MTMV> mtmvSet = 
Env.getCurrentEnv().getMtmvService().getRelationManager()
-                    .getAllMTMVs(Lists.newArrayList(new BaseTableInfo(table)));
-            LOG.info("table {} related mv set is {}", new 
BaseTableInfo(table), mtmvSet);
+                    .getCandidateMTMVs(Lists.newArrayList(new 
BaseTableInfo(table)));
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("table {} related mv set is {}", new 
BaseTableInfo(table), mtmvSet);
+            }
             for (MTMV mtmv : mtmvSet) {
+                
cascadesContext.getStatementContext().getCandidateMTMVs().add(mtmv);
                 
cascadesContext.getStatementContext().getMtmvRelatedTables().put(mtmv.getFullQualifiers(),
 mtmv);
                 mtmv.readMvLock();
                 try {
@@ -221,6 +224,7 @@ public class CollectRelation implements AnalysisRuleFactory 
{
                             LOG.debug("mtmv {} related base table include {}", 
new BaseTableInfo(mtmv), baseTableInfo);
                         }
                         try {
+                            // Collect all base tables and lock them before 
querying
                             
cascadesContext.getStatementContext().getAndCacheTable(baseTableInfo.toList(),
                                     TableFrom.MTMV);
                         } catch (AnalysisException exception) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitConsistentMaterializationContextHook.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitConsistentMaterializationContextHook.java
index fbcf4726a10..e86cca263d3 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitConsistentMaterializationContextHook.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitConsistentMaterializationContextHook.java
@@ -20,16 +20,13 @@ package org.apache.doris.nereids.rules.exploration.mv;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.TableIf;
-import org.apache.doris.mtmv.BaseTableInfo;
 import org.apache.doris.mtmv.MTMVUtil;
 import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.PlannerHook;
 
 import com.google.common.annotations.VisibleForTesting;
 
-import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * If enable query rewrite with mv in dml, should init consistent 
materialization context after analyze
@@ -49,10 +46,9 @@ public class InitConsistentMaterializationContextHook 
extends InitMaterializatio
     }
 
     protected Set<MTMV> getAvailableMTMVs(Set<TableIf> usedTables, 
CascadesContext cascadesContext) {
-        List<BaseTableInfo> usedBaseTables =
-                
usedTables.stream().map(BaseTableInfo::new).collect(Collectors.toList());
         return Env.getCurrentEnv().getMtmvService().getRelationManager()
-                .getAvailableMTMVs(usedBaseTables, 
cascadesContext.getConnectContext(),
+                
.getAvailableMTMVs(cascadesContext.getStatementContext().getCandidateMTMVs(),
+                        cascadesContext.getConnectContext(),
                         true, ((connectContext, mtmv) -> {
                             return MTMVUtil.mtmvContainsExternalTable(mtmv) && 
(!connectContext.getSessionVariable()
                                     
.isEnableDmlMaterializedViewRewriteWhenBaseTableUnawareness());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java
index 914ae3a5195..ba3afad0fe6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java
@@ -20,7 +20,6 @@ package org.apache.doris.nereids.rules.exploration.mv;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.TableIf;
-import org.apache.doris.mtmv.BaseTableInfo;
 import org.apache.doris.mtmv.MTMVCache;
 import org.apache.doris.mtmv.MTMVUtil;
 import org.apache.doris.nereids.CascadesContext;
@@ -39,7 +38,6 @@ import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * If enable query rewrite with mv, should init materialization context after 
analyze
@@ -93,10 +91,9 @@ public class InitMaterializationContextHook implements 
PlannerHook {
     }
 
     protected Set<MTMV> getAvailableMTMVs(Set<TableIf> usedTables, 
CascadesContext cascadesContext) {
-        List<BaseTableInfo> usedBaseTables =
-                
usedTables.stream().map(BaseTableInfo::new).collect(Collectors.toList());
         return Env.getCurrentEnv().getMtmvService().getRelationManager()
-                .getAvailableMTMVs(usedBaseTables, 
cascadesContext.getConnectContext(),
+                
.getAvailableMTMVs(cascadesContext.getStatementContext().getCandidateMTMVs(),
+                        cascadesContext.getConnectContext(),
                         false, ((connectContext, mtmv) -> {
                             return MTMVUtil.mtmvContainsExternalTable(mtmv) && 
(!connectContext.getSessionVariable()
                                     
.isEnableMaterializedViewRewriteWhenBaseTableUnawareness());
diff --git a/fe/fe-core/src/test/java/org/apache/doris/mtmv/AlterMTMVTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/mtmv/AlterMTMVTest.java
index 17ec145f583..342f9fd60c8 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/mtmv/AlterMTMVTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/mtmv/AlterMTMVTest.java
@@ -51,7 +51,7 @@ public class AlterMTMVTest extends TestWithFeService {
 
         MTMVRelationManager relationManager = 
Env.getCurrentEnv().getMtmvService().getRelationManager();
         Table table = 
Env.getCurrentInternalCatalog().getDb("test").get().getTableOrMetaException("stu");
-        Set<MTMV> allMTMVs = 
relationManager.getAllMTMVs(Lists.newArrayList(new BaseTableInfo(table)));
+        Set<MTMV> allMTMVs = 
relationManager.getCandidateMTMVs(Lists.newArrayList(new BaseTableInfo(table)));
         boolean hasMvA = false;
         boolean hasMvB = false;
         for (MTMV mtmv : allMTMVs) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVRewriteUtilTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVRewriteUtilTest.java
index 82c7eaac631..e4788c18409 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVRewriteUtilTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVRewriteUtilTest.java
@@ -122,6 +122,10 @@ public class MTMVRewriteUtilTest {
                 MTMVUtil.mtmvContainsExternalTable((MTMV) any);
                 minTimes = 0;
                 result = false;
+
+                mtmv.canBeCandidate();
+                minTimes = 0;
+                result = true;
             }
         };
     }
@@ -279,9 +283,9 @@ public class MTMVRewriteUtilTest {
     public void testGetMTMVCanRewritePartitionsStateAbnormal() {
         new Expectations() {
             {
-                status.getState();
+                mtmv.canBeCandidate();
                 minTimes = 0;
-                result = MTMVState.SCHEMA_CHANGE;
+                result = false;
             }
         };
         Collection<Partition> mtmvCanRewritePartitions = MTMVRewriteUtil
@@ -309,9 +313,9 @@ public class MTMVRewriteUtilTest {
     public void testGetMTMVCanRewritePartitionsRefreshStateInit() {
         new Expectations() {
             {
-                status.getRefreshState();
+                mtmv.canBeCandidate();
                 minTimes = 0;
-                result = MTMVRefreshState.INIT;
+                result = false;
             }
         };
         Collection<Partition> mtmvCanRewritePartitions = MTMVRewriteUtil
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/memo/StructInfoMapTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/memo/StructInfoMapTest.java
index 19d1efdbbd8..0d3181d15e8 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/memo/StructInfoMapTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/memo/StructInfoMapTest.java
@@ -70,6 +70,12 @@ class StructInfoMapTest extends SqlTestBase {
                 return true;
             }
         };
+        new MockUp<MTMV>() {
+            @Mock
+            public boolean canBeCandidate() {
+                return true;
+            }
+        };
         connectContext.getSessionVariable().enableMaterializedViewRewrite = 
true;
         connectContext.getSessionVariable().enableMaterializedViewNestRewrite 
= true;
 
@@ -129,6 +135,12 @@ class StructInfoMapTest extends SqlTestBase {
                 return true;
             }
         };
+        new MockUp<MTMV>() {
+            @Mock
+            public boolean canBeCandidate() {
+                return true;
+            }
+        };
         connectContext.getSessionVariable().enableMaterializedViewRewrite = 
true;
         connectContext.getSessionVariable().enableMaterializedViewNestRewrite 
= true;
         createMvByNereids("create materialized view mv1 BUILD IMMEDIATE 
REFRESH COMPLETE ON MANUAL\n"
@@ -177,6 +189,12 @@ class StructInfoMapTest extends SqlTestBase {
                 return true;
             }
         };
+        new MockUp<MTMV>() {
+            @Mock
+            public boolean canBeCandidate() {
+                return true;
+            }
+        };
         connectContext.getSessionVariable().enableMaterializedViewRewrite = 
true;
         connectContext.getSessionVariable().enableMaterializedViewNestRewrite 
= true;
         createMvByNereids("create materialized view mv1 BUILD IMMEDIATE 
REFRESH COMPLETE ON MANUAL\n"
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
index 1403a9fee5e..3e93919ed22 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
@@ -59,6 +59,12 @@ public class IdStatisticsMapTest extends SqlTestBase {
                 return true;
             }
         };
+        new MockUp<MTMV>() {
+            @Mock
+            public boolean canBeCandidate() {
+                return true;
+            }
+        };
         connectContext.getSessionVariable().enableMaterializedViewRewrite = 
true;
         connectContext.getSessionVariable().enableMaterializedViewNestRewrite 
= true;
         createMvByNereids("create materialized view mv100 BUILD IMMEDIATE 
REFRESH COMPLETE ON MANUAL\n"
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/MvTableIdIsLongTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/MvTableIdIsLongTest.java
index 4fa0a68e77c..5c9fb3c0392 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/MvTableIdIsLongTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/MvTableIdIsLongTest.java
@@ -55,6 +55,12 @@ public class MvTableIdIsLongTest extends SqlTestBase {
                 return true;
             }
         };
+        new MockUp<MTMV>() {
+            @Mock
+            public boolean canBeCandidate() {
+                return true;
+            }
+        };
         connectContext.getSessionVariable().enableMaterializedViewRewrite = 
true;
         connectContext.getSessionVariable().enableMaterializedViewNestRewrite 
= true;
         createMvByNereids("create materialized view mv1 BUILD IMMEDIATE 
REFRESH COMPLETE ON MANUAL\n"
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/OptimizeGetAvailableMvsTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/OptimizeGetAvailableMvsTest.java
index da327b2ba6c..ab70b9dac4a 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/OptimizeGetAvailableMvsTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/OptimizeGetAvailableMvsTest.java
@@ -18,13 +18,16 @@
 package org.apache.doris.nereids.mv;
 
 import org.apache.doris.catalog.DistributionInfo;
+import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.MaterializedIndex;
 import org.apache.doris.catalog.MaterializedIndex.IndexState;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Partition;
 import org.apache.doris.catalog.PartitionItem;
 import org.apache.doris.common.Pair;
+import org.apache.doris.datasource.CatalogIf;
 import org.apache.doris.mtmv.BaseTableInfo;
+import org.apache.doris.mtmv.MTMVRelationManager;
 import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.rules.expression.rules.PartitionPruner;
 import 
org.apache.doris.nereids.rules.expression.rules.PartitionPruner.PartitionTableType;
@@ -48,6 +51,7 @@ import java.util.BitSet;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -127,6 +131,14 @@ public class OptimizeGetAvailableMvsTest extends 
SqlTestBase {
                         + "inner join T3 on T4.id = T3.id",
                 connectContext
         );
+        CatalogIf internal = getCatalog("internal");
+        Optional table = 
internal.getDbOrAnalysisException("test").getTable("mv1");
+        new MockUp<MTMVRelationManager>() {
+            @Mock
+            public Set<MTMV> getCandidateMTMVs(List<BaseTableInfo> 
baseTableInfos) {
+                return Sets.newHashSet((MTMV) table.get());
+            }
+        };
         PlanChecker.from(c1)
                 .analyze()
                 .rewrite()
@@ -238,6 +250,14 @@ public class OptimizeGetAvailableMvsTest extends 
SqlTestBase {
                         + "where T4.id > 0",
                 connectContext
         );
+        CatalogIf internal = getCatalog("internal");
+        Optional table = 
internal.getDbOrAnalysisException("test").getTable("mv2");
+        new MockUp<MTMVRelationManager>() {
+            @Mock
+            public Set<MTMV> getCandidateMTMVs(List<BaseTableInfo> 
baseTableInfos) {
+                return Sets.newHashSet((MTMV) table.get());
+            }
+        };
         PlanChecker.from(c1)
                 .analyze()
                 .rewrite()
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
index e535e3a8ac5..71d0f0101b0 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.util;
 
 import org.apache.doris.analysis.ExplainOptions;
+import org.apache.doris.nereids.CTEContext;
 import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.NereidsPlanner;
 import org.apache.doris.nereids.PlanProcess;
@@ -49,6 +50,7 @@ import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleFactory;
 import org.apache.doris.nereids.rules.RuleSet;
 import org.apache.doris.nereids.rules.RuleType;
+import 
org.apache.doris.nereids.rules.exploration.mv.InitConsistentMaterializationContextHook;
 import 
org.apache.doris.nereids.rules.exploration.mv.InitMaterializationContextHook;
 import org.apache.doris.nereids.rules.exploration.mv.MaterializedViewUtils;
 import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
@@ -120,6 +122,9 @@ public class PlanChecker {
     }
 
     public PlanChecker analyze() {
+        
this.cascadesContext.getStatementContext().addPlannerHook(InitConsistentMaterializationContextHook.INSTANCE);
+        this.cascadesContext.newTableCollector().collect();
+        this.cascadesContext.setCteContext(new CTEContext());
         this.cascadesContext.newAnalyzer().analyze();
         this.cascadesContext.toMemo();
         return this;
@@ -127,6 +132,9 @@ public class PlanChecker {
 
     public PlanChecker analyze(Plan plan) {
         this.cascadesContext = 
MemoTestUtils.createCascadesContext(connectContext, plan);
+        
this.cascadesContext.getStatementContext().addPlannerHook(InitConsistentMaterializationContextHook.INSTANCE);
+        this.cascadesContext.newTableCollector().collect();
+        this.cascadesContext.setCteContext(new CTEContext());
         Set<String> originDisableRules = 
connectContext.getSessionVariable().getDisableNereidsRuleNames();
         Set<String> disableRuleWithAuth = Sets.newHashSet(originDisableRules);
         disableRuleWithAuth.add(RuleType.RELATION_AUTHENTICATION.name());
@@ -140,6 +148,9 @@ public class PlanChecker {
 
     public PlanChecker analyze(String sql) {
         this.cascadesContext = 
MemoTestUtils.createCascadesContext(connectContext, sql);
+        
this.cascadesContext.getStatementContext().addPlannerHook(InitConsistentMaterializationContextHook.INSTANCE);
+        this.cascadesContext.newTableCollector().collect();
+        this.cascadesContext.setCteContext(new CTEContext());
         this.cascadesContext.newAnalyzer().analyze();
         this.cascadesContext.toMemo();
         return this;
diff --git 
a/regression-test/suites/nereids_rules_p0/mv/dml/insert/dml_insert_and_overwrite.groovy
 
b/regression-test/suites/nereids_rules_p0/mv/dml/insert/dml_insert_and_overwrite.groovy
index 54e9b57f7e5..753217f922d 100644
--- 
a/regression-test/suites/nereids_rules_p0/mv/dml/insert/dml_insert_and_overwrite.groovy
+++ 
b/regression-test/suites/nereids_rules_p0/mv/dml/insert/dml_insert_and_overwrite.groovy
@@ -106,7 +106,8 @@ suite("dml_insert_and_overwrite") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    // todo: Temporarily turn off, otherwise usable materialized views will 
not be collected and will need to be changed back in the future
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 
@@ -155,7 +156,7 @@ suite("dml_insert_and_overwrite") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 
@@ -203,7 +204,7 @@ suite("dml_insert_and_overwrite") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 
@@ -249,7 +250,7 @@ suite("dml_insert_and_overwrite") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 
diff --git 
a/regression-test/suites/nereids_rules_p0/mv/dml/outfile/dml_into_outfile.groovy
 
b/regression-test/suites/nereids_rules_p0/mv/dml/outfile/dml_into_outfile.groovy
index 350e49057d0..dc23130b990 100644
--- 
a/regression-test/suites/nereids_rules_p0/mv/dml/outfile/dml_into_outfile.groovy
+++ 
b/regression-test/suites/nereids_rules_p0/mv/dml/outfile/dml_into_outfile.groovy
@@ -122,7 +122,8 @@ suite("dml_into_outfile", "p0") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    // todo: Temporarily turn off, otherwise usable materialized views will 
not be collected and will need to be changed back in the future
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 
@@ -185,7 +186,7 @@ suite("dml_into_outfile", "p0") {
         ps_comment;""")
 
     // disable query rewrite by mv
-    sql "set enable_materialized_view_rewrite=false";
+    sql "set enable_materialized_view_rewrite=true";
     // enable dml rewrite by mv
     sql "set enable_dml_materialized_view_rewrite=true";
 


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


Reply via email to