xuzifu666 commented on code in PR #5110:
URL: https://github.com/apache/calcite/pull/5110#discussion_r3618960050
##########
core/src/main/java/org/apache/calcite/rex/RexSimplify.java:
##########
@@ -2367,9 +2364,46 @@ private RexNode simplifyOrs(List<RexNode> terms,
RexUnknownAs unknownAs) {
break;
}
}
+
+ // Absorption law: a OR (a AND b) => a
+ absorb(terms, SqlKind.AND);
+
return RexUtil.composeDisjunction(rexBuilder, terms);
}
+ /**
+ * Applies the absorption law to a list of terms, removing any composite term
+ * that is absorbed by a sibling term.
+ *
+ * <p>When {@code compositeKind} is {@link SqlKind#OR}, removes any
+ * {@code (a OR b)} term whose disjunctions contain a sibling {@code a}, so
+ * {@code a AND (a OR b) => a}. When it is {@link SqlKind#AND}, removes any
+ * {@code (a AND b)} term whose conjunctions contain a sibling {@code a}, so
+ * {@code a OR (a AND b) => a}.
+ *
+ * <p>The absorbing sibling {@code a} must be deterministic; otherwise its
two
+ * occurrences might evaluate differently and the rewrite would not be
+ * equivalence-preserving.
+ */
+ private static void absorb(List<RexNode> terms, SqlKind compositeKind) {
+ for (int i = 0; i < terms.size(); i++) {
+ final RexNode term = terms.get(i);
+ if (term.getKind() == compositeKind) {
+ final List<RexNode> components = compositeKind == SqlKind.OR
+ ? RelOptUtil.disjunctions(term)
Review Comment:
You are right that for each term we may call RelOptUtil.disjunctions /
RelOptUtil.conjunctions, and then scan the sibling terms to check containment.
In the worst case this is O(n²·m) where n is the number of terms and m is the
size of the disjunction/conjunction.
In practice, however, the number of top-level conjuncts/disjuncts in a
WHERE/FILTER predicate is usually small, so the cost should be bounded.
But I agree we should not rely on that assumption, I added a guard to skip
absorption when the term list is large(The threshold is 20,referenced the
threshold value for the IN-to-OR transition), avoid the performance impact
associated with complex situations.
--
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]