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]