This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new fb2ad0c43f5 branch-4.2: [fix](aggregate) Ignore lambda-local slots in
aggregate validation #67742 (#70065)
fb2ad0c43f5 is described below
commit fb2ad0c43f5b76142e7c23b1a6c0f76a34d20f9b
Author: morrySnow <[email protected]>
AuthorDate: Wed Nov 4 14:10:47 2026 +0800
branch-4.2: [fix](aggregate) Ignore lambda-local slots in aggregate
validation #67742 (#70065)
picked from master #67742
---
.../nereids/rules/analysis/FillUpMissingSlots.java | 6 ++++++
.../rules/analysis/FillUpMissingSlotsTest.java | 21 ++++++++++++++++++++
.../test_having_with_aggregate_function.out | 4 ++++
.../test_having_with_aggregate_function.groovy | 23 ++++++++++++++++++++++
4 files changed, 54 insertions(+)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java
index de14524712c..6f7dc1de191 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java
@@ -24,6 +24,7 @@ import org.apache.doris.nereids.properties.OrderKey;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.trees.expressions.Alias;
+import
org.apache.doris.nereids.trees.expressions.ArrayItemReference.ArrayItemSlot;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
@@ -207,6 +208,11 @@ public class FillUpMissingSlots implements
AnalysisRuleFactory {
}
public void resolve(Expression expression, ResolvePlanType planType) {
+ // ArrayItemSlot represents a lambda-local variable, not an input
from the aggregate's child.
+ // It is bound by its ArrayItemReference and should not
participate in GROUP BY validation.
+ if (expression instanceof ArrayItemSlot) {
+ return;
+ }
Pair<Optional<Expression>, Boolean> result = lookUp(expression);
Optional<Expression> found = result.first;
boolean isFoundInOutputExpressions = result.second;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlotsTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlotsTest.java
index a1c64226868..46044a2416f 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlotsTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlotsTest.java
@@ -352,6 +352,27 @@ public class FillUpMissingSlotsTest extends
AnalyzeCheckTestBase implements Memo
).when(FieldChecker.check("projects",
Lists.newArrayList(a1.toSlot(), sumA2.toSlot()))));
}
+ @Test
+ void testHavingLambdaLocalSlots() {
+ String multiArgumentSql = "SELECT a1, COUNT(*) AS n FROM t1 GROUP BY
a1 "
+ + "HAVING array_match_any(array_map((k, v) -> v > k, array(1),
array(COUNT(*))))";
+
Assertions.assertNotNull(PlanChecker.from(connectContext).analyze(multiArgumentSql).getPlan());
+
+ String arraySql = "SELECT a1, COUNT(*) AS n FROM t1 GROUP BY a1 "
+ + "HAVING array_match_any(array_map(x -> x > 1,
array(COUNT(*))))";
+
Assertions.assertNotNull(PlanChecker.from(connectContext).analyze(arraySql).getPlan());
+
+ ExceptionChecker.expectThrowsWithMsg(
+ AnalysisException.class,
+ "HAVING expression 'a2' must appear in the GROUP BY clause"
+ + " or be used in an aggregate function.",
+ () -> PlanChecker.from(connectContext).analyze(
+ "SELECT a1, COUNT(*) AS n FROM t1 GROUP BY a1 "
+ + "HAVING array_match_any(array_map(x -> x >
1, "
+ + "array(COUNT(*) + a2)))"
+ ));
+ }
+
@Test
void testInvalidHaving() {
ExceptionChecker.expectThrowsWithMsg(
diff --git
a/regression-test/data/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.out
b/regression-test/data/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.out
index 2892b7e4a40..49d66843e95 100644
---
a/regression-test/data/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.out
+++
b/regression-test/data/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.out
@@ -8,3 +8,7 @@
1
-- !scalar_subquery_having_false --
+
+-- !having_array_lambda_local_slots --
+1 2
+
diff --git
a/regression-test/suites/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.groovy
b/regression-test/suites/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.groovy
index eb507b98f03..9adb02b0137 100644
---
a/regression-test/suites/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.groovy
+++
b/regression-test/suites/nereids_rules_p0/fill_up_missing_slots/test_having_with_aggregate_function.groovy
@@ -34,6 +34,20 @@ suite("test_having_project") {
SELECT 1 AS c1 FROM t HAVING count(1) > 0
"""
+ test {
+ sql """
+ SELECT id, COUNT(*) AS n
+ FROM (
+ SELECT 1 id, 1 AS ungrouped_col
+ UNION ALL
+ SELECT 1 id, 2 AS ungrouped_col
+ ) input
+ GROUP BY id
+ HAVING array_match_any(array_map(x -> x > 1, array(COUNT(*) +
ungrouped_col)))
+ """
+ exception "HAVING expression 'ungrouped_col' must appear in the GROUP
BY clause or be used in an aggregate function"
+ }
+
test {
sql "SELECT 1 AS c1 FROM t HAVING count(1) > 0 OR c1 IS NOT NULL"
exception "HAVING expression 'c1' must appear in the GROUP BY clause
or be used in an aggregate function"
@@ -53,4 +67,13 @@ suite("test_having_project") {
sql "SELECT (SELECT 1, 2 FROM t HAVING SUM(id) > 0)"
exception "Multiple columns returned by subquery are not yet
supported. Found 2"
}
+
+ qt_having_array_lambda_local_slots """
+ SELECT id, COUNT(*) AS n
+ FROM (SELECT 1 id UNION ALL SELECT 1 id) input
+ GROUP BY id
+ HAVING array_match_any(array_map(x -> x > 1, array(COUNT(*))))
+ ORDER BY id
+ """
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]