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

morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 55dc541c90 [Fix](Nereids) aggregate function except COUNT should 
nullable without group by expr  (#15547)
55dc541c90 is described below

commit 55dc541c90db54a1d735e847ad949641526c263c
Author: starocean999 <[email protected]>
AuthorDate: Tue Jan 3 21:28:07 2023 +0800

    [Fix](Nereids) aggregate function except COUNT should nullable without 
group by expr  (#15547)
    
    Co-authored-by: mch_ucchi
---
 .../doris/nereids/analyzer/NereidsAnalyzer.java    |  2 +
 .../AdjustAggregateNullableForEmptySetJob.java     | 34 +++++++++
 .../jobs/batch/NereidsRewriteJobExecutor.java      |  2 +
 .../org/apache/doris/nereids/rules/RuleType.java   |  1 +
 .../AdjustAggregateNullableForEmptySet.java        | 80 ++++++++++++++++++++++
 .../trees/expressions/functions/agg/Avg.java       | 22 ++++--
 .../expressions/functions/agg/GroupBitAnd.java     | 17 +++--
 .../expressions/functions/agg/GroupBitOr.java      | 17 +++--
 .../expressions/functions/agg/GroupBitXor.java     | 17 +++--
 .../expressions/functions/agg/GroupBitmapXor.java  | 19 +++--
 .../trees/expressions/functions/agg/Max.java       | 18 +++--
 .../trees/expressions/functions/agg/Min.java       | 18 +++--
 .../functions/agg/NullableAggregateFunction.java   | 71 +++++++++++++++++++
 .../trees/expressions/functions/agg/Sum.java       | 22 ++++--
 .../trees/expressions/functions/agg/Variance.java  | 21 ++++--
 .../expressions/functions/agg/VarianceSamp.java    | 19 ++---
 .../visitor/AggregateFunctionVisitor.java          | 19 +++--
 .../rules/analysis/AnalyzeWhereSubqueryTest.java   | 19 ++---
 .../data/nereids_syntax_p0/agg_with_empty_set.out  | 20 ++++++
 .../nereids_syntax_p0/agg_with_empty_set.groovy    | 32 +++++++++
 20 files changed, 395 insertions(+), 75 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/NereidsAnalyzer.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/NereidsAnalyzer.java
index 014b3069ed..2924d2cec5 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/NereidsAnalyzer.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/NereidsAnalyzer.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.analyzer;
 
 import org.apache.doris.nereids.CascadesContext;
+import 
org.apache.doris.nereids.jobs.batch.AdjustAggregateNullableForEmptySetJob;
 import org.apache.doris.nereids.jobs.batch.AnalyzeRulesJob;
 import org.apache.doris.nereids.jobs.batch.AnalyzeSubqueryRulesJob;
 import org.apache.doris.nereids.jobs.batch.CheckAnalysisJob;
@@ -50,6 +51,7 @@ public class NereidsAnalyzer {
     public void analyze() {
         new AnalyzeRulesJob(cascadesContext, outerScope).execute();
         new AnalyzeSubqueryRulesJob(cascadesContext).execute();
+        new AdjustAggregateNullableForEmptySetJob(cascadesContext).execute();
         new TypeCoercionJob(cascadesContext).execute();
         // check whether analyze result is meaningful
         new CheckAnalysisJob(cascadesContext).execute();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/AdjustAggregateNullableForEmptySetJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/AdjustAggregateNullableForEmptySetJob.java
new file mode 100644
index 0000000000..403f1b8ff9
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/AdjustAggregateNullableForEmptySetJob.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.jobs.batch;
+
+import org.apache.doris.nereids.CascadesContext;
+import 
org.apache.doris.nereids.rules.analysis.AdjustAggregateNullableForEmptySet;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Analyze subquery.
+ */
+public class AdjustAggregateNullableForEmptySetJob extends BatchRulesJob {
+    public AdjustAggregateNullableForEmptySetJob(CascadesContext 
cascadesContext) {
+        super(cascadesContext);
+        rulesJob.addAll(ImmutableList.of(
+                bottomUpBatch(ImmutableList.of(new 
AdjustAggregateNullableForEmptySet()))));
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
index 0715bfa51b..3ab9f2cd79 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriteJobExecutor.java
@@ -21,6 +21,7 @@ import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.jobs.Job;
 import org.apache.doris.nereids.rules.RuleSet;
 import org.apache.doris.nereids.rules.RuleType;
+import 
org.apache.doris.nereids.rules.analysis.AdjustAggregateNullableForEmptySet;
 import org.apache.doris.nereids.rules.analysis.CheckAfterRewrite;
 import 
org.apache.doris.nereids.rules.analysis.LogicalSubQueryAliasToLogicalProject;
 import 
org.apache.doris.nereids.rules.expression.rewrite.ExpressionNormalization;
@@ -78,6 +79,7 @@ public class NereidsRewriteJobExecutor extends BatchRulesJob {
                  */
                 .addAll(new 
AdjustApplyFromCorrelateToUnCorrelateJob(cascadesContext).rulesJob)
                 .addAll(new ConvertApplyToJoinJob(cascadesContext).rulesJob)
+                .add(bottomUpBatch(ImmutableList.of(new 
AdjustAggregateNullableForEmptySet())))
                 .add(topDownBatch(ImmutableList.of(new 
ExpressionNormalization(cascadesContext.getConnectContext()))))
                 .add(topDownBatch(ImmutableList.of(new 
ExpressionOptimization())))
                 .add(topDownBatch(ImmutableList.of(new 
ExtractSingleTableExpressionFromDisjunction())))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
index 754abd189a..cef0329ee8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
@@ -75,6 +75,7 @@ public enum RuleType {
 
     ADJUST_NULLABLE_FOR_PROJECT_SLOT(RuleTypeClass.REWRITE),
     ADJUST_NULLABLE_FOR_AGGREGATE_SLOT(RuleTypeClass.REWRITE),
+    ADJUST_NULLABLE_FOR_HAVING_SLOT(RuleTypeClass.REWRITE),
     ADJUST_NULLABLE_FOR_REPEAT_SLOT(RuleTypeClass.REWRITE),
 
     CHECK_ROW_POLICY(RuleTypeClass.REWRITE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/AdjustAggregateNullableForEmptySet.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/AdjustAggregateNullableForEmptySet.java
new file mode 100644
index 0000000000..63cdf66572
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/AdjustAggregateNullableForEmptySet.java
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.analysis;
+
+import org.apache.doris.nereids.rules.Rule;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.rules.rewrite.RewriteRuleFactory;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.NamedExpression;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.NullableAggregateFunction;
+import 
org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter;
+import org.apache.doris.nereids.trees.plans.logical.LogicalHaving;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * adjust aggregate nullable when: group expr list is empty and function is 
NullableAggregateFunction,
+ * the function in output should be adjusted to nullable and so as having node.
+ */
+public class AdjustAggregateNullableForEmptySet implements RewriteRuleFactory {
+    @Override
+    public List<Rule> buildRules() {
+        return ImmutableList.of(
+                RuleType.ADJUST_NULLABLE_FOR_AGGREGATE_SLOT.build(
+                        logicalAggregate()
+                                .then(agg -> {
+                                    List<NamedExpression> output = 
agg.getOutputExpressions().stream()
+                                            .map(ne -> ((NamedExpression) 
FunctionReplacer.INSTANCE.replace(ne,
+                                                    
agg.getGroupByExpressions().isEmpty())))
+                                            .collect(Collectors.toList());
+                                    return agg.withAggOutput(output);
+                                })
+                ),
+                RuleType.ADJUST_NULLABLE_FOR_HAVING_SLOT.build(
+                        logicalHaving(logicalAggregate())
+                                .then(having -> {
+                                    Set<Expression> newConjuncts = 
having.getConjuncts().stream()
+                                            .map(ne -> 
FunctionReplacer.INSTANCE.replace(ne,
+                                                    
having.child().getGroupByExpressions().isEmpty()))
+                                            .collect(Collectors.toSet());
+                                    return new LogicalHaving<>(newConjuncts, 
having.child());
+                                })
+                )
+        );
+    }
+
+    private static class FunctionReplacer extends 
DefaultExpressionRewriter<Boolean> {
+        public static final FunctionReplacer INSTANCE = new FunctionReplacer();
+
+        public Expression replace(Expression expression, boolean 
isAlwaysNullable) {
+            return expression.accept(INSTANCE, isAlwaysNullable);
+        }
+
+        @Override
+        public Expression 
visitNullableAggregateFunction(NullableAggregateFunction 
nullableAggregateFunction,
+                Boolean isAlwaysNullable) {
+            return nullableAggregateFunction.isDistinct() ? 
nullableAggregateFunction
+                    : 
nullableAggregateFunction.withAlwaysNullable(isAlwaysNullable);
+        }
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
index 3961d7ff1a..34abff1e31 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -38,14 +37,18 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** avg agg function. */
-public class Avg extends AggregateFunction implements UnaryExpression, 
PropagateNullable, CustomSignature {
+public class Avg extends NullableAggregateFunction implements UnaryExpression, 
CustomSignature {
 
     public Avg(Expression child) {
-        super("avg", child);
+        this(false, false, child);
     }
 
-    public Avg(boolean isDistinct, Expression child) {
-        super("avg", isDistinct, child);
+    public Avg(boolean isDistinct, Expression arg) {
+        this(isDistinct, false, arg);
+    }
+
+    private Avg(boolean isDistinct, boolean isAlwaysNullable, Expression arg) {
+        super("avg", isAlwaysNullable, isDistinct, arg);
     }
 
     @Override
@@ -64,13 +67,18 @@ public class Avg extends AggregateFunction implements 
UnaryExpression, Propagate
     @Override
     public AggregateFunction withDistinctAndChildren(boolean isDistinct, 
List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Avg(isDistinct, children.get(0));
+        return new Avg(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
     public Avg withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Avg(isDistinct, children.get(0));
+        return new Avg(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new Avg(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitAnd.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitAnd.java
index 43dd0f1d47..bd514b606a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitAnd.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitAnd.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -36,8 +35,7 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** min agg function. */
-public class GroupBitAnd extends AggregateFunction
-        implements UnaryExpression, PropagateNullable, 
ExplicitlyCastableSignature {
+public class GroupBitAnd extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(TinyIntType.INSTANCE).args(TinyIntType.INSTANCE),
             
FunctionSignature.ret(SmallIntType.INSTANCE).args(SmallIntType.INSTANCE),
@@ -47,7 +45,11 @@ public class GroupBitAnd extends AggregateFunction
     );
 
     public GroupBitAnd(Expression child) {
-        super("group_bit_and", child);
+        this(child, false);
+    }
+
+    private GroupBitAnd(Expression child, boolean isAlwaysNullable) {
+        super("group_bit_and", isAlwaysNullable, child);
     }
 
     @Override
@@ -63,7 +65,7 @@ public class GroupBitAnd extends AggregateFunction
     @Override
     public GroupBitAnd withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new GroupBitAnd(children.get(0));
+        return new GroupBitAnd(children.get(0), isAlwaysNullable);
     }
 
     @Override
@@ -71,6 +73,11 @@ public class GroupBitAnd extends AggregateFunction
         return withChildren(children);
     }
 
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new GroupBitAnd(children.get(0), isAlwaysNullable);
+    }
+
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitGroupBitAnd(this, context);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitOr.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitOr.java
index 4d296078ae..9743ddd858 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitOr.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitOr.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -36,8 +35,7 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** min agg function. */
-public class GroupBitOr extends AggregateFunction
-        implements UnaryExpression, PropagateNullable, 
ExplicitlyCastableSignature {
+public class GroupBitOr extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(TinyIntType.INSTANCE).args(TinyIntType.INSTANCE),
             
FunctionSignature.ret(SmallIntType.INSTANCE).args(SmallIntType.INSTANCE),
@@ -47,7 +45,11 @@ public class GroupBitOr extends AggregateFunction
     );
 
     public GroupBitOr(Expression child) {
-        super("group_bit_or", child);
+        this(child, false);
+    }
+
+    private GroupBitOr(Expression child, boolean isAlwaysNullable) {
+        super("group_bit_or", isAlwaysNullable, child);
     }
 
     @Override
@@ -63,7 +65,7 @@ public class GroupBitOr extends AggregateFunction
     @Override
     public GroupBitOr withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new GroupBitOr(children.get(0));
+        return new GroupBitOr(children.get(0), isAlwaysNullable);
     }
 
     @Override
@@ -71,6 +73,11 @@ public class GroupBitOr extends AggregateFunction
         return withChildren(children);
     }
 
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new GroupBitOr(children.get(0), isAlwaysNullable);
+    }
+
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitGroupBitOr(this, context);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitXor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitXor.java
index 3912dbb962..7d1453155b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitXor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitXor.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -36,8 +35,7 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** min agg function. */
-public class GroupBitXor extends AggregateFunction
-        implements UnaryExpression, PropagateNullable, 
ExplicitlyCastableSignature {
+public class GroupBitXor extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(TinyIntType.INSTANCE).args(TinyIntType.INSTANCE),
@@ -48,7 +46,11 @@ public class GroupBitXor extends AggregateFunction
     );
 
     public GroupBitXor(Expression child) {
-        super("group_bit_xor", child);
+        this(child, false);
+    }
+
+    private GroupBitXor(Expression child, boolean isAlwaysNullable) {
+        super("group_bit_xor", isAlwaysNullable, child);
     }
 
     @Override
@@ -64,7 +66,7 @@ public class GroupBitXor extends AggregateFunction
     @Override
     public GroupBitXor withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new GroupBitXor(children.get(0));
+        return new GroupBitXor(children.get(0), isAlwaysNullable);
     }
 
     @Override
@@ -72,6 +74,11 @@ public class GroupBitXor extends AggregateFunction
         return withChildren(children);
     }
 
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new GroupBitXor(children.get(0), isAlwaysNullable);
+    }
+
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitGroupBitXor(this, context);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitmapXor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitmapXor.java
index 5b48359aea..11ea74365b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitmapXor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupBitmapXor.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.types.BitmapType;
 import org.apache.doris.nereids.types.DataType;
@@ -31,14 +30,17 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** GroupBitmapXor */
-public class GroupBitmapXor extends AggregateFunction
-        implements UnaryExpression, PropagateNullable, 
ExplicitlyCastableSignature {
+public class GroupBitmapXor extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BitmapType.INSTANCE).args(BitmapType.INSTANCE)
     );
 
-    public GroupBitmapXor(Expression arg0) {
-        super("group_bitmap_xor", arg0);
+    public GroupBitmapXor(Expression child) {
+        this(child, false);
+    }
+
+    private GroupBitmapXor(Expression arg0, boolean isAlwaysNullable) {
+        super("group_bitmap_xor", isAlwaysNullable, arg0);
     }
 
     @Override
@@ -54,7 +56,12 @@ public class GroupBitmapXor extends AggregateFunction
     @Override
     public GroupBitmapXor withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new GroupBitmapXor(children.get(0));
+        return new GroupBitmapXor(children.get(0), isAlwaysNullable);
+    }
+
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new GroupBitmapXor(children.get(0), isAlwaysNullable);
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Max.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Max.java
index a374313453..1c273da418 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Max.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Max.java
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
 import 
org.apache.doris.nereids.trees.expressions.functions.ForbiddenMetricTypeArguments;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DataType;
@@ -32,14 +31,18 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** max agg function. */
-public class Max extends AggregateFunction implements UnaryExpression, 
PropagateNullable, CustomSignature,
+public class Max extends NullableAggregateFunction implements UnaryExpression, 
CustomSignature,
         ForbiddenMetricTypeArguments {
     public Max(Expression child) {
-        super("max", child);
+        this(false, false, child);
     }
 
     public Max(boolean isDistinct, Expression arg) {
-        super("max", false, arg);
+        this(isDistinct, false, arg);
+    }
+
+    private Max(boolean isDistinct, boolean isAlwaysNullable, Expression arg) {
+        super("max", isAlwaysNullable, isDistinct, arg);
     }
 
     @Override
@@ -56,7 +59,7 @@ public class Max extends AggregateFunction implements 
UnaryExpression, Propagate
     @Override
     public Max withDistinctAndChildren(boolean isDistinct, List<Expression> 
children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Max(isDistinct, children.get(0));
+        return new Max(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
@@ -65,6 +68,11 @@ public class Max extends AggregateFunction implements 
UnaryExpression, Propagate
         return new Max(children.get(0));
     }
 
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new Max(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitMax(this, context);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Min.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Min.java
index aadb48471c..829e9c89f9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Min.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Min.java
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
 import 
org.apache.doris.nereids.trees.expressions.functions.ForbiddenMetricTypeArguments;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.DataType;
@@ -32,15 +31,19 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** min agg function. */
-public class Min extends AggregateFunction implements UnaryExpression, 
PropagateNullable, CustomSignature,
+public class Min extends NullableAggregateFunction implements UnaryExpression, 
CustomSignature,
         ForbiddenMetricTypeArguments {
 
     public Min(Expression child) {
-        super("min", child);
+        this(false, false, child);
     }
 
     public Min(boolean isDistinct, Expression arg) {
-        super("min", false, arg);
+        this(isDistinct, false, arg);
+    }
+
+    private Min(boolean isDistinct, boolean isAlwaysNullable, Expression arg) {
+        super("min", isAlwaysNullable, isDistinct, arg);
     }
 
     @Override
@@ -57,7 +60,7 @@ public class Min extends AggregateFunction implements 
UnaryExpression, Propagate
     @Override
     public Min withDistinctAndChildren(boolean isDistinct, List<Expression> 
children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Min(isDistinct, children.get(0));
+        return new Min(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
@@ -66,6 +69,11 @@ public class Min extends AggregateFunction implements 
UnaryExpression, Propagate
         return new Min(children.get(0));
     }
 
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new Min(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
     @Override
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitMin(this, context);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullableAggregateFunction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullableAggregateFunction.java
new file mode 100644
index 0000000000..cd6c58b749
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullableAggregateFunction.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.agg;
+
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+
+import java.util.Objects;
+
+/**
+ * nullable aggregate function
+ */
+public abstract class NullableAggregateFunction extends AggregateFunction 
implements
+        PropagateNullable, AlwaysNullable {
+    protected final boolean isAlwaysNullable;
+
+    protected NullableAggregateFunction(String name, boolean isAlwaysNullable,
+            Expression ...expressions) {
+        super(name, false, expressions);
+        this.isAlwaysNullable = isAlwaysNullable;
+    }
+
+    protected NullableAggregateFunction(String name, boolean isAlwaysNullable, 
boolean isDistinct,
+            Expression ...expressions) {
+        super(name, isDistinct, expressions);
+        this.isAlwaysNullable = isAlwaysNullable;
+    }
+
+    @Override
+    public boolean nullable() {
+        return isAlwaysNullable ? AlwaysNullable.super.nullable() : 
PropagateNullable.super.nullable();
+    }
+
+    public abstract NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable);
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        NullableAggregateFunction that = (NullableAggregateFunction) o;
+        return isAlwaysNullable == that.isAlwaysNullable;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), isAlwaysNullable);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum.java
index 853f73f469..1166ce418c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum.java
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -38,13 +37,17 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** sum agg function. */
-public class Sum extends AggregateFunction implements UnaryExpression, 
PropagateNullable, CustomSignature {
+public class Sum extends NullableAggregateFunction implements UnaryExpression, 
CustomSignature {
     public Sum(Expression child) {
-        super("sum", child);
+        this(false, false, child);
     }
 
-    public Sum(boolean isDistinct, Expression child) {
-        super("sum", isDistinct, child);
+    public Sum(boolean isDistinct, Expression arg) {
+        this(isDistinct, false, arg);
+    }
+
+    private Sum(boolean isDistinct, boolean isAlwaysNullable, Expression arg) {
+        super("sum", isAlwaysNullable, isDistinct, arg);
     }
 
     @Override
@@ -62,13 +65,18 @@ public class Sum extends AggregateFunction implements 
UnaryExpression, Propagate
     @Override
     public Sum withDistinctAndChildren(boolean isDistinct, List<Expression> 
children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Sum(isDistinct, children.get(0));
+        return new Sum(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
     public Sum withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Sum(isDistinct, children.get(0));
+        return new Sum(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new Sum(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Variance.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Variance.java
index 85f08279d1..8a53af11df 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Variance.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Variance.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -40,8 +39,7 @@ import java.util.List;
 /**
  * Variance function
  */
-public class Variance extends AggregateFunction implements UnaryExpression, 
PropagateNullable,
-        ExplicitlyCastableSignature {
+public class Variance extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
@@ -55,11 +53,15 @@ public class Variance extends AggregateFunction implements 
UnaryExpression, Prop
     );
 
     public Variance(Expression child) {
-        super("variance", child);
+        this(false, child);
     }
 
     public Variance(boolean isDistinct, Expression child) {
-        super("variance", isDistinct, child);
+        this(isDistinct, false, child);
+    }
+
+    private Variance(boolean isDistinct, boolean isAlwaysNullable, Expression 
child) {
+        super("variance", isAlwaysNullable, isDistinct, child);
     }
 
     @Override
@@ -70,13 +72,18 @@ public class Variance extends AggregateFunction implements 
UnaryExpression, Prop
     @Override
     public AggregateFunction withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Variance(isDistinct, children.get(0));
+        return new Variance(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
     public AggregateFunction withDistinctAndChildren(boolean isDistinct, 
List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new Variance(isDistinct, children.get(0));
+        return new Variance(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new Variance(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/VarianceSamp.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/VarianceSamp.java
index 8d212f3ae3..33ad68c269 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/VarianceSamp.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/VarianceSamp.java
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -40,8 +39,7 @@ import java.util.List;
 /**
  * VarianceSamp function
  */
-public class VarianceSamp extends AggregateFunction implements 
UnaryExpression, PropagateNullable,
-        ExplicitlyCastableSignature {
+public class VarianceSamp extends NullableAggregateFunction implements 
UnaryExpression, ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
@@ -55,11 +53,11 @@ public class VarianceSamp extends AggregateFunction 
implements UnaryExpression,
     );
 
     public VarianceSamp(Expression child) {
-        super("variance_samp", child);
+        this(false, false, child);
     }
 
-    public VarianceSamp(boolean isDistinct, Expression child) {
-        super("variance_samp", isDistinct, child);
+    private VarianceSamp(boolean isDistinct, boolean isAlwaysNullable, 
Expression child) {
+        super("variance_samp", isAlwaysNullable, isDistinct, child);
     }
 
     @Override
@@ -70,13 +68,18 @@ public class VarianceSamp extends AggregateFunction 
implements UnaryExpression,
     @Override
     public AggregateFunction withChildren(List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new VarianceSamp(isDistinct, children.get(0));
+        return new VarianceSamp(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
     public AggregateFunction withDistinctAndChildren(boolean isDistinct, 
List<Expression> children) {
         Preconditions.checkArgument(children.size() == 1);
-        return new VarianceSamp(isDistinct, children.get(0));
+        return new VarianceSamp(isDistinct, isAlwaysNullable, children.get(0));
+    }
+
+    @Override
+    public NullableAggregateFunction withAlwaysNullable(boolean 
isAlwaysNullable) {
+        return new VarianceSamp(isDistinct, isAlwaysNullable, children.get(0));
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/AggregateFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/AggregateFunctionVisitor.java
index ee2403e9e2..c6f17995d4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/AggregateFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/AggregateFunctionVisitor.java
@@ -33,6 +33,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.agg.Min;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctCount;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Ndv;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.NullableAggregateFunction;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Variance;
 import org.apache.doris.nereids.trees.expressions.functions.agg.VarianceSamp;
@@ -43,8 +44,12 @@ import 
org.apache.doris.nereids.trees.expressions.functions.agg.VarianceSamp;
 public interface AggregateFunctionVisitor<R, C> {
     R visitAggregateFunction(AggregateFunction aggregateFunction, C context);
 
+    default R visitNullableAggregateFunction(NullableAggregateFunction 
nullableAggregateFunction, C context) {
+        return visitAggregateFunction(nullableAggregateFunction, context);
+    }
+
     default R visitAvg(Avg avg, C context) {
-        return visitAggregateFunction(avg, context);
+        return visitNullableAggregateFunction(avg, context);
     }
 
     default R visitCount(Count count, C context) {
@@ -52,11 +57,11 @@ public interface AggregateFunctionVisitor<R, C> {
     }
 
     default R visitMax(Max max, C context) {
-        return visitAggregateFunction(max, context);
+        return visitNullableAggregateFunction(max, context);
     }
 
     default R visitMin(Min min, C context) {
-        return visitAggregateFunction(min, context);
+        return visitNullableAggregateFunction(min, context);
     }
 
     default R visitMultiDistinctCount(MultiDistinctCount multiDistinctCount, C 
context) {
@@ -68,19 +73,19 @@ public interface AggregateFunctionVisitor<R, C> {
     }
 
     default R visitGroupBitAnd(GroupBitAnd groupBitAnd, C context) {
-        return visitAggregateFunction(groupBitAnd, context);
+        return visitNullableAggregateFunction(groupBitAnd, context);
     }
 
     default R visitGroupBitOr(GroupBitOr groupBitOr, C context) {
-        return visitAggregateFunction(groupBitOr, context);
+        return visitNullableAggregateFunction(groupBitOr, context);
     }
 
     default R visitGroupBitXor(GroupBitXor groupBitXor, C context) {
-        return visitAggregateFunction(groupBitXor, context);
+        return visitNullableAggregateFunction(groupBitXor, context);
     }
 
     default R visitSum(Sum sum, C context) {
-        return visitAggregateFunction(sum, context);
+        return visitNullableAggregateFunction(sum, context);
     }
 
     default R visitBitmapUnionCount(BitmapUnionCount bitmapUnionCount, C 
context) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/AnalyzeWhereSubqueryTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/AnalyzeWhereSubqueryTest.java
index 8aa1e1cc84..d94a8259d8 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/AnalyzeWhereSubqueryTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/AnalyzeWhereSubqueryTest.java
@@ -154,10 +154,13 @@ public class AnalyzeWhereSubqueryTest extends 
TestWithFeService implements Patte
                                         logicalFilter()
                                 ).when(FieldChecker.check("outputExpressions", 
ImmutableList.of(
                                         new Alias(new ExprId(7),
-                                                new Sum(
+                                                (new Sum(
                                                         new SlotReference(new 
ExprId(4), "k3",
                                                                 
BigIntType.INSTANCE, true,
-                                                                
ImmutableList.of("default_cluster:test", "t7"))),
+                                                                
ImmutableList.of(
+                                                                        
"default_cluster:test",
+                                                                        
"t7")))).withAlwaysNullable(
+                                                                               
 true),
                                                 "sum(k3)"))))
                         ).when(FieldChecker.check("correlationSlot", 
ImmutableList.of(
                                 new SlotReference(new ExprId(1), "k2", 
BigIntType.INSTANCE, true,
@@ -176,9 +179,9 @@ public class AnalyzeWhereSubqueryTest extends 
TestWithFeService implements Patte
                         logicalApply(
                                 any(),
                                 
logicalAggregate().when(FieldChecker.check("outputExpressions", 
ImmutableList.of(
-                                                new Alias(new ExprId(7), new 
Sum(
+                                                new Alias(new ExprId(7), (new 
Sum(
                                                         new SlotReference(new 
ExprId(4), "k3", BigIntType.INSTANCE, true,
-                                                                
ImmutableList.of("default_cluster:test", "t7"))),
+                                                                
ImmutableList.of("default_cluster:test", "t7")))).withAlwaysNullable(true),
                                                         "sum(k3)"),
                                                 new SlotReference(new 
ExprId(6), "v2", BigIntType.INSTANCE, true,
                                                         
ImmutableList.of("default_cluster:test", "t7"))
@@ -393,9 +396,9 @@ public class AnalyzeWhereSubqueryTest extends 
TestWithFeService implements Patte
                                         )))
                                     ).when(agg -> 
agg.getOutputExpressions().equals(ImmutableList.of(
                                         new Alias(new ExprId(8),
-                                                new Max(new SlotReference(new 
ExprId(7), "aa", BigIntType.INSTANCE,
+                                                (new Max(new SlotReference(new 
ExprId(7), "aa", BigIntType.INSTANCE,
                                                         true,
-                                                        
ImmutableList.of("t2"))), "max(aa)")
+                                                        
ImmutableList.of("t2")))).withAlwaysNullable(true), "max(aa)")
                                     )))
                                     .when(agg -> 
agg.getGroupByExpressions().equals(ImmutableList.of()))
                                 )
@@ -454,8 +457,8 @@ public class AnalyzeWhereSubqueryTest extends 
TestWithFeService implements Patte
                                 logicalAggregate(
                                         logicalProject()
                                 ).when(FieldChecker.check("outputExpressions", 
ImmutableList.of(
-                                        new Alias(new ExprId(8), new Max(new 
SlotReference(new ExprId(7), "aa", BigIntType.INSTANCE, true,
-                                                ImmutableList.of("t2"))), 
"max(aa)"),
+                                        new Alias(new ExprId(8), (new Max(new 
SlotReference(new ExprId(7), "aa", BigIntType.INSTANCE, true,
+                                                
ImmutableList.of("t2")))).withAlwaysNullable(true), "max(aa)"),
                                         new SlotReference(new ExprId(6), "v2", 
BigIntType.INSTANCE, true,
                                                 
ImmutableList.of("default_cluster:test", "t7")))))
                                         
.when(FieldChecker.check("groupByExpressions", ImmutableList.of(
diff --git a/regression-test/data/nereids_syntax_p0/agg_with_empty_set.out 
b/regression-test/data/nereids_syntax_p0/agg_with_empty_set.out
new file mode 100644
index 0000000000..1db851c70c
--- /dev/null
+++ b/regression-test/data/nereids_syntax_p0/agg_with_empty_set.out
@@ -0,0 +1,20 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select1 --
+0      \N      \N      \N      \N
+
+-- !select2 --
+3      1312    1303    1308.0  3924
+
+-- !select3 --
+
+-- !select4 --
+1      1303    1303    1303.0  1303
+1      1309    1309    1309.0  1309
+1      1312    1312    1312.0  1312
+
+-- !select5 --
+0      \N      \N      \N      \N
+
+-- !select6 --
+0      \N      \N      \N      \N
+
diff --git a/regression-test/suites/nereids_syntax_p0/agg_with_empty_set.groovy 
b/regression-test/suites/nereids_syntax_p0/agg_with_empty_set.groovy
new file mode 100644
index 0000000000..5fc117445a
--- /dev/null
+++ b/regression-test/suites/nereids_syntax_p0/agg_with_empty_set.groovy
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("agg_with_empty_set") {
+    sql "set enable_nereids_planner=true"
+    sql "set enable_fallback_to_original_planner=false"
+
+    sql "use regression_test_nereids_syntax_p0"
+
+    qt_select1 "select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where 1=2"
+    qt_select2 "select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where 1=1"
+    qt_select3 "select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where 1=2 group by c_custkey"
+    qt_select4 "select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where 1=1 group by c_custkey order 
by c_custkey"
+    qt_select5 """select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where c_custkey < 
+        (select min(c_custkey) from customer)"""
+    qt_select6 """select count(c_custkey), max(c_custkey), min(c_custkey), 
avg(c_custkey), sum(c_custkey) from customer where c_custkey < 
+        (select min(c_custkey) from customer) having min(c_custkey) is null"""
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to