yujun777 commented on code in PR #63639:
URL: https://github.com/apache/doris/pull/63639#discussion_r4140246940


##########
fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVCache.java:
##########
@@ -142,6 +160,19 @@ public static MTMVCache from(String defSql,
                     .orElse(rewritePlan);
             Pair<Plan, StructInfo> finalPlanStructInfoPair = 
constructPlanAndStructInfo(
                     addGuardRewritePlan, cascadesContext);
+            // Analysis records nondeterministic functions before constant 
folding erases their origin.
+            // Replanning current_date(), for example, cannot establish a 
guarantee about rows stored
+            // by an earlier refresh. Do not export output guarantees from 
such a definition.
+            // Alias UDF definitions can also change between refresh and cache 
reconstruction,
+            // even when the expanded function body is deterministic.
+            // A lower MV may have refreshed since this MV's rows were stored. 
Derive guarantees
+            // from this definition alone, without importing the lower MV's 
current output facts.
+            Set<Expression> outputPredicates = 
(cascadesContext.getStatementContext().hasNondeterministic()

Review Comment:
   [P1] Preserve refresh-time expression bindings before exporting output 
facts. These predicates are derived from the expression as currently analyzed, 
while only nondeterministic expressions and alias UDFs are excluded. A 
replaceable IMMUTABLE Java/Python UDF, or a folded mutable global/session 
variable, can change its binding without refreshing the lower MV. After cache 
rebuild, the lower cache may incorrectly claim `id > 10` although its stored 
rows were built with `id > 1`; an upper MV refreshed with the new bound can 
have its real filter removed by `withoutRedundantMvFilters()`, allowing `SELECT 
id FROM lower` to lose rows 2..10. Persist and validate the refresh-time 
binding/signature, or withhold dependent output guarantees when the binding is 
not stable.



##########
fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java:
##########
@@ -1683,6 +1687,16 @@ public void writeMvUnlock() {
         this.mvRwLock.writeLock().unlock();
     }
 
+    private MTMVCache cacheWithValidOutputPredicates(MTMVCache cache) {
+        // A cache built from the current definition can prove facts about 
stored rows only after
+        // every partition has been refreshed. Callers hold the MV lock while 
publishing it.
+        if (status.getState() == MTMVState.SCHEMA_CHANGE

Review Comment:
   [P1] Suppress output guarantees after direct MTMV writes. This gate only 
checks SCHEMA_CHANGE and partition snapshot coverage, but 
`allow_modify_materialized_view_data` permits direct writes that do not 
invalidate this guarantee. For example, after a lower MV defined with `WHERE id 
> 10` is refreshed, inserting `id = 5` directly into it leaves the lower cache 
claiming `id > 10`. Refreshing an upper MV defined as `SELECT id FROM lower 
WHERE id > 10` omits that row; `withoutRedundantMvFilters()` can then remove 
the upper filter and rewrite `SELECT id FROM lower` to the upper MV, losing `id 
= 5`. Track direct writes as a persistent loss of output guarantees until a 
qualifying refresh; transient cache invalidation alone is insufficient because 
rebuilding the same definition repeats the false proof.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to