Skip to content

Commit

Permalink
fix filter regression test
Browse files Browse the repository at this point in the history
  • Loading branch information
seawinde committed Dec 5, 2023
1 parent cdf8817 commit 9c9ba36
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
* AbstractMaterializedViewJoinRule
Expand All @@ -52,21 +53,23 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
queryStructInfo.getExpressions(),
queryStructInfo.getOriginalPlan());
// Rewrite top projects, represent the query projects by view
List<NamedExpression> expressions = rewriteExpression(
List<Expression> expressionsRewritten = rewriteExpression(
queryShuttleExpression,
materializationContext.getViewExpressionIndexMapping(),
queryToViewSlotMappings,
tempRewritedPlan
queryToViewSlotMappings
);
// Can not rewrite, bail out
if (expressions == null) {
if (expressionsRewritten == null
|| expressionsRewritten.stream().anyMatch(expr -> !(expr instanceof NamedExpression))) {
return null;
}
if (queryStructInfo.getOriginalPlan().getGroupExpression().isPresent()) {
materializationContext.addMatchedGroup(
queryStructInfo.getOriginalPlan().getGroupExpression().get().getOwnerGroup().getGroupId());
}
return new LogicalProject<>(expressions, tempRewritedPlan);
return new LogicalProject<>(
expressionsRewritten.stream().map(NamedExpression.class::cast).collect(Collectors.toList()),
tempRewritedPlan);
}

// Check join is whether valid or not. Support join's input can not contain aggregate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.algebra.CatalogRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
Expand Down Expand Up @@ -118,11 +119,10 @@ protected List<Plan> rewrite(Plan queryPlan, CascadesContext cascadesContext) {
rewritedPlan = mvScan;
} else {
// Try to rewrite compensate predicates by using mv scan
List<NamedExpression> rewriteCompensatePredicates = rewriteExpression(
List<Expression> rewriteCompensatePredicates = rewriteExpression(
compensatePredicates.toList(),
materializationContext.getViewExpressionIndexMapping(),
queryToViewSlotMapping,
mvScan);
queryToViewSlotMapping);
if (rewriteCompensatePredicates.isEmpty()) {
continue;
}
Expand Down Expand Up @@ -159,11 +159,10 @@ protected Plan rewriteQueryByView(MatchMode matchMode,
/**
* Use target output expression to represent the source expression
*/
protected List<NamedExpression> rewriteExpression(
protected List<Expression> rewriteExpression(
List<? extends Expression> sourceExpressions,
ExpressionMapping expressionMapping,
SlotMapping sourceToTargetMapping,
Plan targetScanNode) {
SlotMapping sourceToTargetMapping) {
// Firstly, rewrite the target plan output expression using query with inverse mapping
// then try to use the mv expression to represent the query. if any of source expressions
// can not be represented by mv, return null
Expand All @@ -184,22 +183,23 @@ protected List<NamedExpression> rewriteExpression(
// view to view scan expression is 1:1 so get first element
Map<? extends Expression, ? extends Expression> mvSqlToMvScanMappingQueryBased = flattenExpressionMap.get(0);

List<NamedExpression> rewrittenExpressions = new ArrayList<>();
List<Expression> rewrittenExpressions = new ArrayList<>();
for (Expression expressionToRewrite : sourceExpressions) {
if (expressionToRewrite instanceof BooleanLiteral
&& ((BooleanLiteral) expressionToRewrite).getValue()) {
if (expressionToRewrite instanceof Literal) {
rewrittenExpressions.add(expressionToRewrite);
continue;
}
final Set<Object> slotsToRewrite =
expressionToRewrite.collectToSet(expression -> expression instanceof Slot);
boolean wiAlias = expressionToRewrite instanceof NamedExpression;
Expression replacedExpression = ExpressionUtils.replace(expressionToRewrite,
mvSqlToMvScanMappingQueryBased,
true);
wiAlias);
if (replacedExpression.anyMatch(slotsToRewrite::contains)) {
// if contains any slot to rewrite, which means can not be rewritten by target, bail out
return null;
}
rewrittenExpressions.add((NamedExpression) replacedExpression);
rewrittenExpressions.add(replacedExpression);
}
return rewrittenExpressions;
}
Expand All @@ -221,6 +221,9 @@ protected SplitPredicate predicatesCompensate(
Map<SlotReference, SlotReference> viewToQuerySlotMapping = queryToViewSlotMapping.inverse()
.toSlotReferenceMap();
EquivalenceClass viewEquivalenceClassQueryBased = viewEquivalenceClass.permute(viewToQuerySlotMapping);
if (viewEquivalenceClassQueryBased == null) {
return SplitPredicate.empty();
}
final List<Expression> equalCompensateConjunctions = new ArrayList<>();
if (queryEquivalenceClass.isEmpty() && viewEquivalenceClass.isEmpty()) {
equalCompensateConjunctions.add(BooleanLiteral.of(true));
Expand Down Expand Up @@ -278,7 +281,9 @@ protected SplitPredicate predicatesCompensate(
Sets.newHashSet(ExpressionUtils.extractConjunction(queryRangePredicate));
Set<Expression> viewRangeQueryBasedSet =
Sets.newHashSet(ExpressionUtils.extractConjunction(viewRangePredicateQueryBased));
if (!queryRangeSet.containsAll(viewRangeQueryBasedSet)) {
// query range predicate can not contain all view range predicate when view have range predicate, bail out
if (!viewRangePredicateQueryBased.equals(BooleanLiteral.TRUE)
&& !queryRangeSet.containsAll(viewRangeQueryBasedSet)) {
return SplitPredicate.empty();
}
queryRangeSet.removeAll(viewRangeQueryBasedSet);
Expand All @@ -294,7 +299,10 @@ protected SplitPredicate predicatesCompensate(
Sets.newHashSet(ExpressionUtils.extractConjunction(queryResidualPredicate));
Set<Expression> viewResidualQueryBasedSet =
Sets.newHashSet(ExpressionUtils.extractConjunction(viewResidualPredicateQueryBased));
if (!queryResidualSet.containsAll(viewResidualQueryBasedSet)) {
// query residual predicate can not contain all view residual predicate when view have residual predicate,
// bail out
if (!viewResidualPredicateQueryBased.equals(BooleanLiteral.TRUE)
&& !queryResidualSet.containsAll(viewResidualQueryBasedSet)) {
return SplitPredicate.empty();
}
queryResidualSet.removeAll(viewResidualQueryBasedSet);
Expand Down
4 changes: 2 additions & 2 deletions regression-test/suites/nereids_rules_p0/mv/inner_join.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,15 @@ suite("inner_join") {
order_qt_query1_2 "${query1_2}"
sql """ DROP MATERIALIZED VIEW IF EXISTS mv1_2"""

// because hyper graph node contains group plan, should fix it firstly
// select + from + inner join + filter
def mv1_3 = "select lineitem.L_LINENUMBER, orders.O_CUSTKEY " +
"from orders " +
"inner join lineitem on lineitem.L_ORDERKEY = orders.O_ORDERKEY "
def query1_3 = "select lineitem.L_LINENUMBER " +
"from lineitem " +
"inner join orders on lineitem.L_ORDERKEY = orders.O_ORDERKEY " +
"where lineitem.L_LINENUMBER > 10"
// check_rewrite(mv1_3, query1_3, "mv1_3")
check_rewrite(mv1_3, query1_3, "mv1_3")
order_qt_query1_3 "${query1_3}"
sql """ DROP MATERIALIZED VIEW IF EXISTS mv1_3"""
}

0 comments on commit 9c9ba36

Please sign in to comment.