This is an automated email from the ASF dual-hosted git repository.

kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 29bdf2cc1d4 [fix](nereids)group by expr may be bound twice in bind agg 
slot #28771 (#28830)
29bdf2cc1d4 is described below

commit 29bdf2cc1d4f38a45b20367829ebcba0c7f6bb87
Author: starocean999 <40539150+starocean...@users.noreply.github.com>
AuthorDate: Mon Dec 25 15:41:30 2023 +0800

    [fix](nereids)group by expr may be bound twice in bind agg slot #28771 
(#28830)
---
 .../nereids/rules/analysis/BindExpression.java     | 38 +++++++++++++++++-----
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
index 445dce033a8..67a82edbf53 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
@@ -286,10 +286,22 @@ public class BindExpression implements 
AnalysisRuleFactory {
                         if (alias.child().anyMatch(expr -> expr instanceof 
AggregateFunction)) {
                             continue;
                         }
-                        // NOTICE: must use unbound expressions, because we 
will bind them in binding group by expr.
-                        childOutputsToExpr.putIfAbsent(alias.getName(), 
agg.getOutputExpressions().get(i).child(0));
+                        /*
+                            Alias(x) has been bound by binding agg's output
+                            we add x to childOutputsToExpr, so when binding 
group by exprs later, we can use x directly
+                            and won't bind it again
+                            select
+                              p_cycle_time / (select max(p_cycle_time) from 
log_event_8)  as 'x',
+                              count(distinct case_id) as 'y'
+                            from
+                              log_event_8
+                            group by
+                              x
+                         */
+                        childOutputsToExpr.putIfAbsent(alias.getName(), 
output.get(i).child(0));
                     }
 
+                    Set<Expression> boundedGroupByExpressions = 
Sets.newHashSet();
                     List<Expression> replacedGroupBy = 
agg.getGroupByExpressions().stream()
                             .map(groupBy -> {
                                 if (groupBy instanceof UnboundSlot) {
@@ -297,7 +309,9 @@ public class BindExpression implements AnalysisRuleFactory {
                                     if (unboundSlot.getNameParts().size() == 
1) {
                                         String name = 
unboundSlot.getNameParts().get(0);
                                         if 
(childOutputsToExpr.containsKey(name)) {
-                                            return 
childOutputsToExpr.get(name);
+                                            Expression expression = 
childOutputsToExpr.get(name);
+                                            
boundedGroupByExpressions.add(expression);
+                                            return expression;
                                         }
                                     }
                                 }
@@ -330,16 +344,24 @@ public class BindExpression implements 
AnalysisRuleFactory {
 
                     List<Expression> groupBy = replacedGroupBy.stream()
                             .map(expression -> {
-                                Expression e = binder.bind(expression);
-                                if (e instanceof UnboundSlot) {
-                                    return childBinder.bind(e);
+                                if 
(boundedGroupByExpressions.contains(expression)) {
+                                    // expr has been bound by binding agg's 
output
+                                    return expression;
+                                } else {
+                                    // bind slot for unbound exprs
+                                    Expression e = binder.bind(expression);
+                                    if (e instanceof UnboundSlot) {
+                                        return childBinder.bind(e);
+                                    }
+                                    return e;
                                 }
-                                return e;
                             })
                             .collect(Collectors.toList());
                     groupBy.forEach(expression -> checkBound(expression, 
ctx.root));
                     groupBy = groupBy.stream()
-                            .map(expr -> bindFunction(expr, ctx.root, 
ctx.cascadesContext))
+                            // bind function for unbound exprs or return old 
expr if it's bound by binding agg's output
+                            .map(expr -> 
boundedGroupByExpressions.contains(expr) ? expr
+                                    : bindFunction(expr, ctx.root, 
ctx.cascadesContext))
                             .collect(ImmutableList.toImmutableList());
                     checkIfOutputAliasNameDuplicatedForGroupBy(groupBy, 
output);
                     return agg.withGroupByAndOutput(groupBy, output);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to