morrySnow commented on code in PR #39450: URL: https://github.com/apache/doris/pull/39450#discussion_r1737798983
########## fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java: ########## @@ -293,6 +292,19 @@ public class Rewriter extends AbstractBatchJobExecutor { topDown(new ConvertInnerOrCrossJoin()), topDown(new ProjectOtherJoinConditionForNestedLoopJoin()) ), + topic("Set operation optimization", Review Comment: add comments to explain why move this rewrite topic here ########## fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpPredicates.java: ########## @@ -60,6 +69,109 @@ public ImmutableSet<Expression> visit(Plan plan, Void context) { return ImmutableSet.of(); } + @Override + public ImmutableSet<Expression> visitLogicalOneRowRelation(LogicalOneRowRelation r, Void context) { + ImmutableSet.Builder<Expression> predicates = ImmutableSet.builder(); + for (NamedExpression expr : r.getProjects()) { + if (expr instanceof Alias && expr.child(0) instanceof Literal) { + predicates.add(new EqualTo(expr.toSlot(), expr.child(0))); + } + } + return predicates.build(); + } + + @Override + public ImmutableSet<Expression> visitLogicalIntersect(LogicalIntersect intersect, Void context) { + return cacheOrElse(intersect, () -> { + ImmutableSet.Builder<Expression> builder = ImmutableSet.builder(); + for (int i = 0; i < intersect.children().size(); ++i) { + Plan child = intersect.child(i); + Set<Expression> childFilters = child.accept(this, context); + if (childFilters.isEmpty()) { + continue; + } + Map<Expression, Expression> replaceMap = new HashMap<>(); + for (int j = 0; j < intersect.getOutput().size(); ++j) { + NamedExpression output = intersect.getOutput().get(j); + replaceMap.put(intersect.getRegularChildOutput(i).get(j), output); + } + builder.addAll(ExpressionUtils.replace(childFilters, replaceMap)); + } + return getAvailableExpressions(builder.build(), intersect); + }); + } + + @Override + public ImmutableSet<Expression> visitLogicalExcept(LogicalExcept except, Void context) { + return cacheOrElse(except, () -> { + if (except.arity() < 1) { + return ImmutableSet.of(); + } + Set<Expression> firstChildFilters = except.child(0).accept(this, context); + if (firstChildFilters.isEmpty()) { + return ImmutableSet.of(); + } + Map<Expression, Expression> replaceMap = new HashMap<>(); + for (int i = 0; i < except.getOutput().size(); ++i) { + NamedExpression output = except.getOutput().get(i); + replaceMap.put(except.getRegularChildOutput(0).get(i), output); + } + return ImmutableSet.copyOf(ExpressionUtils.replace(firstChildFilters, replaceMap)); + }); + } + + @Override + public ImmutableSet<Expression> visitLogicalUnion(LogicalUnion union, Void context) { + return cacheOrElse(union, () -> { + if (!union.getConstantExprsList().isEmpty() && union.arity() == 0) { Review Comment: why could not process union with both constantExprs and normal children? how about ``` union |-- const(1 as a) +-- filter(a = 1) +-- project(a) ``` -- 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: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org