seawinde commented on code in PR #62951:
URL: https://github.com/apache/doris/pull/62951#discussion_r3272644763


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/Predicates.java:
##########
@@ -254,6 +269,194 @@ private static Set<Expression> 
normalizeExpression(Expression expression, Cascad
         return ExpressionUtils.extractConjunctionToSet(expression);
     }
 
+    /**
+     * Detect if normalized expressions form a whole-bucket range and 
synthesize date_trunc equality predicates.
+     * Returns null if no whole-bucket pattern detected.
+     */
+    private static Map<Expression, ExpressionInfo> 
detectAndSynthesizeWholeBucketPredicates(
+            Set<Expression> normalizedExpressions,
+            StructInfo viewStructInfo,
+            SlotMapping viewToQuerySlotMapping) {
+        // Group predicates by slot
+        Map<Expression, List<Expression>> slotToPredicates = new HashMap<>();
+        for (Expression expr : normalizedExpressions) {
+            if (!(expr instanceof ComparisonPredicate)) {
+                continue;
+            }
+            ComparisonPredicate pred = (ComparisonPredicate) expr;
+            Expression left = pred.left();
+            if (left instanceof SlotReference) {
+                slotToPredicates.computeIfAbsent(left, k -> new 
ArrayList<>()).add(expr);
+            }
+        }
+
+        // Check if view has date_trunc on any of these slots
+        Map<SlotReference, DateTrunc> viewDateTruncMap = 
extractViewDateTruncExpressions(viewStructInfo);
+        if (viewDateTruncMap.isEmpty()) {
+            return null;
+        }
+
+        // Map view slots to query slots
+        Map<SlotReference, SlotReference> viewToQuerySlotMap = 
viewToQuerySlotMapping.toSlotReferenceMap();
+        Map<SlotReference, DateTrunc> querySlotToViewDateTrunc = new 
HashMap<>();
+        for (Map.Entry<SlotReference, DateTrunc> entry : 
viewDateTruncMap.entrySet()) {
+            SlotReference viewSlot = entry.getKey();
+            SlotReference querySlot = viewToQuerySlotMap.get(viewSlot);
+            if (querySlot != null) {
+                querySlotToViewDateTrunc.put(querySlot, entry.getValue());
+            }
+        }
+
+        // Try to detect whole-bucket ranges
+        for (Map.Entry<Expression, List<Expression>> entry : 
slotToPredicates.entrySet()) {
+            if (!(entry.getKey() instanceof SlotReference)) {
+                continue;
+            }
+            SlotReference slot = (SlotReference) entry.getKey();
+
+            // Only apply to DATE/DATEV2 types, not DATETIME/DATETIMEV2
+            // Reason: Boundary conversion (dt > '2024-12-31' → dt >= 
'2025-01-01') is only
+            // valid for DATE types. For DATETIME, dt <= '2025-01-31 00:00:00' 
does not cover
+            // the full day of Jan 31, so whole-bucket detection would be 
semantically incorrect.
+            if (!slot.getDataType().isDateType() && 
!slot.getDataType().isDateV2Type()) {
+                continue;
+            }
+
+            DateTrunc viewDateTrunc = querySlotToViewDateTrunc.get(slot);
+            if (viewDateTrunc == null) {
+                continue;
+            }
+
+            List<Expression> predicates = entry.getValue();

Review Comment:
     The current detection requires exactly two range predicates for the same 
slot. That is fine for the narrow supported case, but it means multi-bucket 
ranges and more complex predicate forms are not covered. Could we make this
     limitation explicit in the PR description or add negative tests for 
unsupported cases?



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