924060929 commented on code in PR #10241: URL: https://github.com/apache/doris/pull/10241#discussion_r901287014
########## fe/fe-core/src/main/java/org/apache/doris/nereids/pattern/GroupExpressionMatching.java: ########## @@ -60,58 +59,101 @@ public GroupExpressionIterator<Plan> iterator() { * @param pattern pattern to match * @param groupExpression group expression to be matched */ - public GroupExpressionIterator(Pattern<? extends NODE_TYPE, NODE_TYPE> pattern, - GroupExpression groupExpression) { - results = Lists.newArrayList(); - + public GroupExpressionIterator(Pattern<Plan, Plan> pattern, GroupExpression groupExpression) { if (!pattern.matchOperator(groupExpression.getOperator())) { return; } - if (pattern.arity() > groupExpression.arity()) { + + // (logicalFilter(), multi()) match (logicalFilter()), + // but (logicalFilter(), logicalFilter(), multi()) not match (logicalFilter()) + boolean extraMulti = pattern.arity() == groupExpression.arity() + 1 + && (pattern.hasMultiChild() || pattern.hasMultiGroupChild()); + if (pattern.arity() > groupExpression.arity() && !extraMulti) { return; } - if (pattern.arity() < groupExpression.arity() - && (!pattern.children().contains(Pattern.MULTI) - || !pattern.children().contains(Pattern.MULTI_FIXED))) { + + // (multi()) match (logicalFilter(), logicalFilter()), + // but (logicalFilter()) not match (logicalFilter(), logicalFilter()) + if (!pattern.isAny() && pattern.arity() < groupExpression.arity() + && !pattern.hasMultiChild() && !pattern.hasMultiGroupChild()) { return; } - NODE_TYPE root = groupExpression.getOperator().toTreeNode(groupExpression); - - List<List<NODE_TYPE>> childrenResults = Lists.newArrayListWithCapacity(groupExpression.arity()); - for (int i = 0; i < groupExpression.arity(); ++i) { - childrenResults.add(Lists.newArrayList()); - int patternChildIndex = i >= pattern.arity() ? pattern.arity() - 1 : i; - for (NODE_TYPE child : new GroupMatching<NODE_TYPE>( - pattern.child(patternChildIndex), groupExpression.child(i))) { - childrenResults.get(i).add(child); - } + // Pattern.GROUP / Pattern.MULTI / Pattern.MULTI_GROUP can not match GroupExpression + if (pattern.isGroup() || pattern.isMulti() || pattern.isMultiGroup()) { Review Comment: this condition is prevent the top level pattern is multi/group/multiGroup, because of performance. so we must wrap a top concrete pattern, e.g. union(multi()). multi/multiGroup will translate to any/group in the matchingChildGroup ```java // translate MULTI and MULTI_GROUP to ANY and GROUP if (isLastPattern) { if (childPattern.isMulti()) { childPattern = Pattern.ANY; } else if (childPattern.isMultiGroup()) { childPattern = Pattern.GROUP; } } ``` this is the example for multi and multiGroup: the pattern: `union(logicalRelation(), multi())` means union with first child is logicalRelation and has empty or multi other children. so this plan trees can be matched and returned: 1. Union(LogicalRelation()) 2. Union(LogicalRelation(), LogicalProject()), 3. Union(LogicalProject(), LogicalProject(), LogicalProject()). and rule can see the real child plan type is logicalRelation and logicalProject. if the pattern is `union(logicalRelation(), multiGroup())`, the returned corresponding plan trees is 1. Union(LogicalRelation()) 2. Union(LogicalRelation(), GroupPlan()), 3. Union(LogicalRelation(), GroupPlan(), GroupPlan()) -- 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