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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java:
##########
@@ -800,6 +803,56 @@ public static Set<Slot> inferNotNullSlots(Set<Expression> 
predicates, CascadesCo
         return notNullSlots.build();
     }
 
+    /**
+     * Return whether all predicates are cheap enough for not-null inference.
+     */
+    public static boolean isCheapEnoughToInferNotNull(Collection<? extends 
Expression> predicates) {
+        Set<Slot> inputSlots = new HashSet<>();
+        for (Expression predicate : predicates) {
+            Optional<Set<Slot>> mergedInputSlots = 
mergeInputSlotsIfCheap(predicate, inputSlots);
+            if (!mergedInputSlots.isPresent()) {
+                return false;
+            }
+            inputSlots = mergedInputSlots.get();
+        }
+        return true;
+    }
+
+    /**
+     * Filter predicates that are cheap enough for not-null inference.
+     */
+    public static Set<Expression> filterCheapPredicatesForNotNull(
+            Collection<? extends Expression> predicates) {
+        Set<Slot> inputSlots = new HashSet<>();
+        Set<Expression> cheapPredicates = Sets.newLinkedHashSet();
+        for (Expression predicate : predicates) {
+            Optional<Set<Slot>> mergedInputSlots = 
mergeInputSlotsIfCheap(predicate, inputSlots);
+            if (!mergedInputSlots.isPresent()) {
+                continue;
+            }
+            inputSlots = mergedInputSlots.get();
+            cheapPredicates.add(predicate);
+        }
+        return cheapPredicates;
+    }
+
+    private static Optional<Set<Slot>> mergeInputSlotsIfCheap(Expression 
predicate, Set<Slot> inputSlots) {
+        if (predicate.getWidth() > MAX_INFER_NOT_NULL_EXPR_WIDTH
+                || predicate.getDepth() > MAX_INFER_NOT_NULL_EXPR_DEPTH) {
+            return Optional.empty();
+        }
+        Set<Slot> predicateInputSlots = predicate.getInputSlots();
+        if (predicateInputSlots.size() > MAX_INFER_NOT_NULL_INPUT_SLOTS) {
+            return Optional.empty();
+        }
+        Set<Slot> mergedInputSlots = new HashSet<>(inputSlots);
+        mergedInputSlots.addAll(predicateInputSlots);
+        if (mergedInputSlots.size() > MAX_INFER_NOT_NULL_INPUT_SLOTS) {
+            return Optional.empty();
+        }

Review Comment:
   This global slot budget makes inference depend on the iteration order of the 
predicate collection. If an earlier cheap predicate uses 32 input slots, a 
later simple predicate like `x = 1` reaches this branch and is skipped only 
because `x` would be the 33rd accumulated slot, so `InferFilterNotNull` will 
not infer `x IS NOT NULL` and `EliminateNotNull` will not remove an explicit 
redundant `x IS NOT NULL`. Several callers pass sets, so two equivalent 
predicate sets can get different not-null inference depending on iteration 
order. The budget should be applied per predicate, or the cumulative cap should 
not prevent independently cheap predicates from being considered.



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