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]

Reply via email to