github-actions[bot] commented on code in PR #63639:
URL: https://github.com/apache/doris/pull/63639#discussion_r4131025029


##########
fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java:
##########
@@ -875,6 +880,13 @@ private MTMVCache getCache(boolean sessionVarsMatch) {
     }
 
     private void setCache(boolean sessionVarsMatch, MTMVCache cache) {
+        // A null cache clears a failed/replayed rebuild. Otherwise output 
guarantees are valid
+        // only when the current definition has refreshed every stored 
partition. State changes
+        // clear these snapshots; restoring NORMAL after one partition refresh 
is not sufficient.
+        if (cache != null && (status.getState() == MTMVState.SCHEMA_CHANGE

Review Comment:
   [P1] Suppress output guarantees after direct MTMV writes. For `Query: 
Project(id) -> Scan(lower)` and `upper: Project(id) -> Filter(id > 10) -> 
Scan(lower)`, this state/snapshot check stays satisfied when 
`allow_modify_materialized_view_data=true` inserts id=5 into a refreshed lower 
MV defined with `WHERE id > 10`. Refreshing upper then omits id=5, but 
`withoutRedundantMvFilters` drops its real filter using the lower's false 
guarantee, so the query can rewrite to upper and lose that row. Track direct 
writes as a persistent loss of guarantees until a qualifying refresh; 
rebuilding the unchanged definition cache repeats the false proof.



##########
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()
+                    || cascadesContext.getStatementContext().hasAliasUdf())

Review Comment:
   [P1] Preserve refresh-time bindings before exporting output facts. `Upper: 
Project(id) -> Filter(id > bound) -> Scan(lower)` becomes a bare lower scan 
when this cache claims that filter is redundant. The bound can change without 
refreshing lower: an IMMUTABLE Java/Python UDF can be dropped and recreated, or 
`@@global.analyze_timeout` can change and be folded again after FE restarts. If 
lower stores ids >1 under the old bound and a newly refreshed upper stores only 
ids >10, this normalization removes upper's real filter; `SELECT id FROM lower` 
can then use upper and lose ids 2..10. The alias-UDF/nondeterministic flags do 
not cover these cases. Persist and validate the refresh-time binding, or 
withhold the dependent output facts.



-- 
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