seawinde commented on code in PR #61345:
URL: https://github.com/apache/doris/pull/61345#discussion_r3208794746
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/Predicates.java:
##########
@@ -254,41 +264,365 @@ private static Set<Expression>
normalizeExpression(Expression expression, Cascad
return ExpressionUtils.extractConjunctionToSet(expression);
}
- /**
- * compensate residual predicates
- */
- public static Map<Expression, ExpressionInfo>
compensateResidualPredicate(StructInfo queryStructInfo,
+ /** Collect all predicate compensation candidates before residual
finalization. */
+ public static PredicateCompensation collectCompensationCandidates(
+ StructInfo queryStructInfo,
StructInfo viewStructInfo,
SlotMapping viewToQuerySlotMapping,
- ComparisonResult comparisonResult) {
- // TODO Residual predicates compensate, simplify implementation
currently.
- SplitPredicate querySplitPredicate =
queryStructInfo.getSplitPredicate();
- SplitPredicate viewSplitPredicate = viewStructInfo.getSplitPredicate();
+ ComparisonResult comparisonResult,
+ CascadesContext cascadesContext) {
+ Map<Expression, ExpressionInfo> equalCandidates =
collectEquivalenceCandidates(
+ queryStructInfo, viewStructInfo, viewToQuerySlotMapping,
comparisonResult);
+ Map<Expression, ExpressionInfo> rangeCandidates =
collectRangeCandidates(
+ queryStructInfo, viewStructInfo, viewToQuerySlotMapping,
comparisonResult, cascadesContext);
+ Map<Expression, ExpressionInfo> residualCandidates =
collectResidualCandidates(queryStructInfo);
+ if (equalCandidates == null || rangeCandidates == null ||
residualCandidates == null) {
+ return null;
+ }
+ return new PredicateCompensation(equalCandidates, rangeCandidates,
residualCandidates);
+ }
- Set<Expression> viewResidualQueryBasedSet = new HashSet<>();
- for (Expression viewExpression :
viewSplitPredicate.getResidualPredicateMap().keySet()) {
- viewResidualQueryBasedSet.add(
- ExpressionUtils.replace(viewExpression,
viewToQuerySlotMapping.toSlotReferenceMap()));
+ /** Compensate predicates in one step. */
+ public static PredicateCompensation compensatePredicates(
+ StructInfo queryStructInfo,
+ StructInfo viewStructInfo,
+ SlotMapping viewToQuerySlotMapping,
+ ComparisonResult comparisonResult,
+ CascadesContext cascadesContext) {
+ PredicateCompensation compensationCandidates =
collectCompensationCandidates(
+ queryStructInfo, viewStructInfo, viewToQuerySlotMapping,
comparisonResult, cascadesContext);
+ if (compensationCandidates == null) {
+ return null;
}
- viewResidualQueryBasedSet.remove(BooleanLiteral.TRUE);
+ Set<Expression> queryBasedViewResidualPredicates =
collectNonInferredQueryBasedExpressions(
+
viewStructInfo.getSplitPredicate().getResidualPredicateMap().keySet(),
viewToQuerySlotMapping);
+ return
compensateCandidatesByViewResidual(queryBasedViewResidualPredicates,
compensationCandidates);
+ }
+
+ private static PredicateCompensation compensateCandidatesByViewResidual(
+ Set<Expression> queryBasedViewResidualPredicates,
+ PredicateCompensation compensationCandidates) {
+ try {
+ Expression combinedCompensationCandidates = buildCombinedPredicate(
+ compensationCandidates.getEquals().keySet(),
+ compensationCandidates.getRanges().keySet(),
+ compensationCandidates.getResiduals().keySet());
+ Expression combinedQueryBasedViewResidual =
buildCombinedPredicate(queryBasedViewResidualPredicates);
+
+ // The compensation must not widen the view result:
+ // compensationCandidates => queryBasedViewResidual.
+ if (!impliesByDnf(combinedCompensationCandidates,
combinedQueryBasedViewResidual)) {
Review Comment:
Could we short-circuit this when `queryBasedViewResidualPredicates` is
empty? In that case `combinedQueryBasedViewResidual` is `TRUE`, so
`compensationCandidates => TRUE` is trivially satisfied. The current code still
expands
`combinedCompensationCandidates` into DNF, and a complex query residual
can hit `MAX_DNF_BRANCHES`, causing us to return `null` even though the
implication should hold. This looks like an unnecessary rewrite regression
rather than a real safety check.
--
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]