[fix](Nereids) should not put bound expr into unbound group by list (#25938)

we put bound expr into unbound group by list by mistake.
This will lead to bind twice on some exprssion.
Since binding is not idempotent, below exception will be thrown for sql

```sql
select k5 / k5 as nu, sum(k1) from test group by nu order by nu nulls first
```

```
Caused by: org.apache.doris.nereids.exceptions.AnalysisException: Input slot(s) not in child's output: k5#5 in plan: LogicalProject[176] ( distinct=false, projects=[(cast(k5#5 as DECIMALV3(16, 10)) / k5#5) AS `nu`#14, sum(k1)#15], excepts=[] ), child output is: [nu#16, sum(k1)#15]
plan tree:
LogicalProject[176] ( distinct=false, projects=[(cast(k5#5 as DECIMALV3(16, 10)) / k5#5) AS `nu`#14, sum(k1)#15], excepts=[] )
+--LogicalAggregate[168] ( groupByExpr=[nu#16], outputExpr=[nu#16, sum(k1#1) AS `sum(k1)`#15], hasRepeat=false )
   +--LogicalProject[156] ( distinct=false, projects=[k1#1, (cast(k5#5 as DECIMALV3(16, 10)) / k5#5) AS `nu`#16], excepts=[] )
      +--LogicalOlapScan ( qualified=default_cluster:regression_test_nereids_syntax_p0.test, indexName=test, selectedIndexId=503229, preAgg=OFF, Aggregate function sum(k1) contains key column k1. )
    at org.apache.doris.nereids.rules.analysis.CheckAfterRewrite.checkAllSlotReferenceFromChildren(CheckAfterRewrite.java:108) ~[classes/:?]
```
This commit is contained in:
morrySnow
2023-10-26 15:31:20 +08:00
committed by GitHub
parent bc606859c7
commit 2229d82acd
2 changed files with 16 additions and 8 deletions

View File

@ -273,13 +273,17 @@ public class BindExpression implements AnalysisRuleFactory {
group_by_key is bound on t1.a
*/
duplicatedSlotNames.forEach(childOutputsToExpr::remove);
output.stream()
.filter(ne -> ne instanceof Alias)
.map(Alias.class::cast)
// agg function cannot be bound with group_by_key
.filter(alias -> !alias.child()
.anyMatch(expr -> expr instanceof AggregateFunction))
.forEach(alias -> childOutputsToExpr.putIfAbsent(alias.getName(), alias.child()));
for (int i = 0; i < output.size(); i++) {
if (!(output.get(i) instanceof Alias)) {
continue;
}
Alias alias = (Alias) output.get(i);
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));
}
List<Expression> replacedGroupBy = agg.getGroupByExpressions().stream()
.map(groupBy -> {