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 1e09629bde3 branch-4.2: [fix](rbo) Respect aggregate null-row 
semantics in CASE rewrite (#67818) (#69108)
1e09629bde3 is described below

commit 1e09629bde3f93131f2bb3bbcae8dd106b67c8f0
Author: morrySnow <[email protected]>
AuthorDate: Thu Oct 15 19:08:18 2026 +0800

    branch-4.2: [fix](rbo) Respect aggregate null-row semantics in CASE rewrite 
(#67818) (#69108)
    
    ### What problem does this PR solve?
    
    Issue Number: N/A
    Related PR: https://github.com/apache/doris/pull/67818
    
    Problem Summary: Filtering unmatched CASE rows changes results for
    NULL-preserving aggregates. Gate aggregate CASE simplification on an
    explicit null-row contract. Backport the marker prerequisite for Count,
    Avg, Sum, Max and Min; omit aggregate classes absent from this branch
    and preserve the existing InferAggNotNull whitelist. Retain the three
    result cases and NULL-preserving join assertion added by #67818. Omit
    existing upstream suite cases requiring unrelated prerequisite fixes and
    the explain assertion requiring broader inference. Generate the DISTINCT
    collect_list shape on branch-4.2; its result remains unchanged.
    
    ### Release note
    
    Fix incorrect CASE simplification for NULL-preserving aggregate
    functions.
    
    ### Backport validation
    
    - Test: Unit Test: InferAggNotNullTest, SimplifyAggGroupByTest; FE
    Checkstyle (0 violations).
    - Combined eight-backport validation: 283 tests across 13 classes, 0
    failures/errors after correcting identity-cast assertions. This
    standalone backport has not had a separate unit-test run.
    - Regression tests: eliminate_aggregate_casewhen and infer_agg_not_null
    passed on an isolated combined eight-backport ASAN cluster after
    test-only branch adaptation; golden outputs were generated through
    run-regression-test.sh. All result values retained from #67818 match
    upstream.
    - Full build.sh --fe and ASAN build.sh --be succeeded on the combined
    backport tree; smoke validation passed.
    - Behavior changed: Yes (CASE simplification requires the null-row
    contract)
    - Does this need documentation: No
    
    (cherry picked from commit 19a6089e4f95684ca05c3826eeb92d1c5bb1ec25)
    
    ### Scope
    
    This is an independent backport of #67818 onto branch-4.2.
    The branch contains the #67818 backport plus a test-only branch
    adaptation commit, and does not include the other seven picks.
    The 283-test result above was obtained from the combined backport tree;
    this standalone branch has not had a separate unit-test run.
    
    ### Check List (For Author)
    
    - Test:
    - [x] Unit Test: 283 targeted tests passed on the combined backport
    tree.
    - [x] Manual test: standalone patch matches the validated pick; FE
    Checkstyle passed on the combined tree.
    - [x] Regression test: eliminate_aggregate_casewhen and
    infer_agg_not_null passed on the combined eight-backport deployment;
    this standalone branch was not tested separately.
    - Behavior changed: see the backport validation details above.
    - Does this need documentation: No.
---
 .../rules/rewrite/EliminateAggCaseWhen.java        |  4 ++
 .../trees/expressions/functions/agg/AIAgg.java     |  2 +-
 .../trees/expressions/functions/agg/AnyValue.java  |  3 +-
 .../trees/expressions/functions/agg/Avg.java       |  2 +-
 .../expressions/functions/agg/AvgWeighted.java     |  2 +-
 .../trees/expressions/functions/agg/BitmapAgg.java |  2 +-
 .../expressions/functions/agg/BitmapIntersect.java |  3 +-
 .../expressions/functions/agg/BitmapUnion.java     |  3 +-
 .../functions/agg/BitmapUnionCount.java            |  3 +-
 .../expressions/functions/agg/BitmapUnionInt.java  |  2 +-
 .../trees/expressions/functions/agg/BoolAnd.java   |  2 +-
 .../trees/expressions/functions/agg/BoolOr.java    |  2 +-
 .../trees/expressions/functions/agg/BoolXor.java   |  2 +-
 .../expressions/functions/agg/CollectList.java     |  2 +-
 .../expressions/functions/agg/CollectSet.java      |  2 +-
 .../trees/expressions/functions/agg/Corr.java      |  2 +-
 .../expressions/functions/agg/CorrWelford.java     |  2 +-
 .../trees/expressions/functions/agg/Count.java     |  3 +-
 .../trees/expressions/functions/agg/Covar.java     |  2 +-
 .../trees/expressions/functions/agg/CovarSamp.java |  2 +-
 .../functions/agg/DataSketchesHllUnionAgg.java     |  3 +-
 .../functions/agg/ExponentialMovingAverage.java    |  2 +-
 .../functions/agg/GroupArrayIntersect.java         |  2 +-
 .../expressions/functions/agg/GroupArrayUnion.java |  2 +-
 .../expressions/functions/agg/GroupBitAnd.java     |  2 +-
 .../expressions/functions/agg/GroupBitOr.java      |  2 +-
 .../expressions/functions/agg/GroupBitXor.java     |  2 +-
 .../expressions/functions/agg/GroupBitmapXor.java  |  2 +-
 .../trees/expressions/functions/agg/Histogram.java |  2 +-
 .../trees/expressions/functions/agg/HllUnion.java  |  3 +-
 .../expressions/functions/agg/HllUnionAgg.java     |  3 +-
 .../expressions/functions/agg/IntersectCount.java  |  2 +-
 .../trees/expressions/functions/agg/Kurt.java      |  3 +-
 .../expressions/functions/agg/LinearHistogram.java |  3 +-
 .../trees/expressions/functions/agg/Max.java       |  2 +-
 .../trees/expressions/functions/agg/MaxBy.java     |  2 +-
 .../trees/expressions/functions/agg/Median.java    |  2 +-
 .../trees/expressions/functions/agg/Min.java       |  2 +-
 .../trees/expressions/functions/agg/MinBy.java     |  2 +-
 .../functions/agg/MultiDistinctCount.java          |  2 +-
 .../functions/agg/MultiDistinctSum.java            |  3 +-
 .../functions/agg/MultiDistinctSum0.java           |  3 +-
 .../trees/expressions/functions/agg/Ndv.java       |  3 +-
 .../agg/NullIgnoringAggregateFunction.java         | 35 ++++++++++
 .../agg/OrthogonalBitmapExprCalculate.java         |  3 +-
 .../agg/OrthogonalBitmapExprCalculateCount.java    |  3 +-
 .../functions/agg/OrthogonalBitmapIntersect.java   |  2 +-
 .../agg/OrthogonalBitmapIntersectCount.java        |  2 +-
 .../functions/agg/OrthogonalBitmapUnionCount.java  |  2 +-
 .../expressions/functions/agg/Percentile.java      |  2 +-
 .../functions/agg/PercentileApprox.java            |  2 +-
 .../functions/agg/PercentileApproxWeighted.java    |  2 +-
 .../expressions/functions/agg/PercentileArray.java |  2 +-
 .../functions/agg/PercentileReservoir.java         |  2 +-
 .../expressions/functions/agg/QuantileUnion.java   |  2 +-
 .../expressions/functions/agg/RegrIntercept.java   |  3 +-
 .../trees/expressions/functions/agg/RegrSlope.java |  3 +-
 .../trees/expressions/functions/agg/Retention.java |  2 +-
 .../trees/expressions/functions/agg/Sem.java       |  2 +-
 .../expressions/functions/agg/SequenceCount.java   |  2 +-
 .../expressions/functions/agg/SequenceMatch.java   |  2 +-
 .../trees/expressions/functions/agg/Skew.java      |  3 +-
 .../trees/expressions/functions/agg/Stddev.java    |  2 +-
 .../expressions/functions/agg/StddevSamp.java      |  2 +-
 .../trees/expressions/functions/agg/Sum.java       |  2 +-
 .../trees/expressions/functions/agg/Sum0.java      |  3 +-
 .../trees/expressions/functions/agg/TopN.java      |  2 +-
 .../trees/expressions/functions/agg/TopNArray.java |  2 +-
 .../expressions/functions/agg/TopNWeighted.java    |  2 +-
 .../trees/expressions/functions/agg/Variance.java  |  2 +-
 .../expressions/functions/agg/VarianceSamp.java    |  2 +-
 .../expressions/functions/agg/WindowFunnel.java    |  2 +-
 .../expressions/functions/agg/WindowFunnelV2.java  |  2 +-
 .../nereids/rules/rewrite/InferAggNotNullTest.java | 69 ++++++++++++++++++++
 .../eliminate_aggregate_casewhen.out               | 73 +++++++++++++++++++++
 .../infer_agg_not_null/infer_agg_not_null.out      | 10 +++
 .../eliminate_aggregate_casewhen.groovy            | 50 ++++++++++++++
 .../infer_agg_not_null/infer_agg_not_null.groovy   | 76 ++++++++++++++++++++++
 78 files changed, 407 insertions(+), 71 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateAggCaseWhen.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateAggCaseWhen.java
index 33a9bbd9242..bd24c50f87d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateAggCaseWhen.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateAggCaseWhen.java
@@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.NullIgnoringAggregateFunction;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.If;
 import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
 import org.apache.doris.nereids.trees.plans.Plan;
@@ -57,6 +58,9 @@ public final class EliminateAggCaseWhen extends 
OneRewriteRuleFactory {
                 return null;
             }
             for (AggregateFunction aggFun : aggFunctions) {
+                if (!(aggFun instanceof NullIgnoringAggregateFunction)) {
+                    return null;
+                }
                 // check whether we only have on case when/if in aggregate 
function
                 if (aggFun.getArguments().size() != 1) {
                     return null;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AIAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AIAgg.java
index 40238a936ad..e7d3283a2a7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AIAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AIAgg.java
@@ -40,7 +40,7 @@ import java.util.List;
  * AggregateFunction 'AI_AGG'.
  */
 public class AIAgg extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE, 
StringType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AnyValue.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AnyValue.java
index 40f792c9569..016fb817c4a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AnyValue.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AnyValue.java
@@ -34,7 +34,8 @@ import java.util.List;
  * AggregateFunction 'any_value'. This class is generated by GenerateFunction.
  */
 public class AnyValue extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX)
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 4440c1c106e..2090599f2a5 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
@@ -48,7 +48,7 @@ import java.util.List;
  */
 public class Avg extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature, 
ComputePrecision, SupportWindowAnalytic,
-        NeedSessionVarGuard {
+        NeedSessionVarGuard, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AvgWeighted.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AvgWeighted.java
index d57958cd056..adf16b7c493 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AvgWeighted.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AvgWeighted.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'avg_weighted'. This class is generated by 
GenerateFunction.
  */
 public class AvgWeighted extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapAgg.java
index 7083e7f0fe7..2b3eaef9661 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapAgg.java
@@ -37,7 +37,7 @@ import java.util.List;
  * AggregateFunction 'bitmap_agg'.
  */
 public class BitmapAgg extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BitmapType.INSTANCE).args(BigIntType.INSTANCE),
             
FunctionSignature.ret(BitmapType.INSTANCE).args(IntegerType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapIntersect.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapIntersect.java
index 382b242123a..5865e638d4d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapIntersect.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapIntersect.java
@@ -35,7 +35,8 @@ import java.util.List;
  * AggregateFunction 'bitmap_intersect'. This class is generated by 
GenerateFunction.
  */
 public class BitmapIntersect extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BitmapType.INSTANCE).args(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnion.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnion.java
index 01cecaff52b..1370889c32e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnion.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnion.java
@@ -36,7 +36,8 @@ import java.util.List;
  * AggregateFunction 'bitmap_union'. This class is generated by 
GenerateFunction.
  */
 public class BitmapUnion extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BitmapType.INSTANCE).args(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionCount.java
index 185af63fac4..2be34c5f4e7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionCount.java
@@ -37,7 +37,8 @@ import java.util.List;
  * AggregateFunction 'bitmap_union_count'. This class is generated by 
GenerateFunction.
  */
 public class BitmapUnionCount extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).args(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionInt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionInt.java
index 9ce84a0f084..8de87e71bc2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionInt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapUnionInt.java
@@ -41,7 +41,7 @@ import java.util.List;
  * AggregateFunction 'bitmap_union_int'. This class is generated by 
GenerateFunction.
  */
 public class BitmapUnionInt extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).args(SmallIntType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolAnd.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolAnd.java
index 02f8dbec79a..4569144ce28 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolAnd.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolAnd.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'bool_and'.
  */
 public class BoolAnd extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BooleanType.INSTANCE).args(BooleanType.INSTANCE)
     );
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolOr.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolOr.java
index 3eefb907d68..e81d9a460cd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolOr.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolOr.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'bool_or'.
  */
 public class BoolOr extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BooleanType.INSTANCE).args(BooleanType.INSTANCE)
     );
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolXor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolXor.java
index 6e84899ec91..471fe3a33de 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolXor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BoolXor.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'bool_xor'.
  */
 public class BoolXor extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BooleanType.INSTANCE).args(BooleanType.INSTANCE)
     );
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectList.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectList.java
index 6866e23a22e..978ecb13236 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectList.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectList.java
@@ -38,7 +38,7 @@ import java.util.List;
  * AggregateFunction 'collect_list'. This class is generated by 
GenerateFunction.
  */
 public class CollectList extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(ArrayType.of(new 
FollowToAnyDataType(0))).args(new AnyDataType(0)),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectSet.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectSet.java
index 00ebdf253fb..ef1c97d4f02 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectSet.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectSet.java
@@ -39,7 +39,7 @@ import java.util.List;
  * AggregateFunction 'collect_set'. This class is generated by 
GenerateFunction.
  */
 public class CollectSet extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(ArrayType.of(new 
FollowToAnyDataType(0))).args(new AnyDataType(0)),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Corr.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Corr.java
index 5d9f9ac5f23..68b06a35e79 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Corr.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Corr.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'corr'. This class is generated by GenerateFunction.
  */
 public class Corr extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CorrWelford.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CorrWelford.java
index b0d51f1a26b..bd36cc4de08 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CorrWelford.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CorrWelford.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'corr_welford'. This class is generated by 
GenerateFunction.
  */
 public class CorrWelford extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Count.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Count.java
index 0396b13ce98..cc48b91745f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Count.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Count.java
@@ -38,7 +38,8 @@ import java.util.List;
 
 /** count agg function. */
 public class Count extends NotNullableAggregateFunction
-        implements ExplicitlyCastableSignature, SupportWindowAnalytic, 
RollUpTrait, SupportMultiDistinct {
+        implements ExplicitlyCastableSignature, SupportWindowAnalytic, 
RollUpTrait, SupportMultiDistinct,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             // count(*)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Covar.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Covar.java
index 2043ce716d1..6f63538b428 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Covar.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Covar.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'covar'. This class is generated by GenerateFunction.
  */
 public class Covar extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CovarSamp.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CovarSamp.java
index 5f100b6460f..e5adeec8f23 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CovarSamp.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CovarSamp.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'covar_samp'. This class is generated by GenerateFunction.
  */
 public class CovarSamp extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/DataSketchesHllUnionAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/DataSketchesHllUnionAgg.java
index 9fe46d2a77d..5091c45ca19 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/DataSketchesHllUnionAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/DataSketchesHllUnionAgg.java
@@ -39,7 +39,8 @@ import java.util.List;
 
 /** datasketches_hll_union_agg agg function. */
 public class DataSketchesHllUnionAgg extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
FunctionTrait, RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
FunctionTrait, RollUpTrait,
+        NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(StringType.INSTANCE),
             
FunctionSignature.ret(DoubleType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ExponentialMovingAverage.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ExponentialMovingAverage.java
index caeb3b82dc7..ba870c89a0c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ExponentialMovingAverage.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ExponentialMovingAverage.java
@@ -43,7 +43,7 @@ import java.util.List;
  * timestamp columns use {@code intDiv(toUnixTimestamp(ts), interval_seconds)}.
  */
 public class ExponentialMovingAverage extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayIntersect.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayIntersect.java
index ea0ea216fc9..aa0f87ae3e2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayIntersect.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayIntersect.java
@@ -36,7 +36,7 @@ import java.util.List;
  * AggregateFunction 'group_array_intersect'.
  */
 public class GroupArrayIntersect extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.retArgType(0)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayUnion.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayUnion.java
index a760b18ef37..5d4efdd2733 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayUnion.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/GroupArrayUnion.java
@@ -36,7 +36,7 @@ import java.util.List;
  * AggregateFunction 'group_array_union'.
  */
 public class GroupArrayUnion extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.retArgType(0)
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 f85f9cef42c..7f7e119b1d6 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
@@ -37,7 +37,7 @@ import java.util.List;
  * AggregateFunction 'group_bit_and'. This class is generated by 
GenerateFunction.
  */
 public class GroupBitAnd extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(LargeIntType.INSTANCE).args(LargeIntType.INSTANCE),
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 86463f004f9..9e8006d32f3 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
@@ -38,7 +38,7 @@ import java.util.List;
  * AggregateFunction 'group_bit_or'. This class is generated by 
GenerateFunction.
  */
 public class GroupBitOr extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(LargeIntType.INSTANCE).args(LargeIntType.INSTANCE),
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 aca1fca059f..b81c9b6ea4b 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
@@ -38,7 +38,7 @@ import java.util.List;
  * AggregateFunction 'group_bit_xor'. This class is generated by 
GenerateFunction.
  */
 public class GroupBitXor extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(LargeIntType.INSTANCE).args(LargeIntType.INSTANCE),
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 202a469fdd4..9cf9310df8c 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
@@ -34,7 +34,7 @@ import java.util.List;
  * AggregateFunction 'group_bitmap_xor'. This class is generated by 
GenerateFunction.
  */
 public class GroupBitmapXor extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BitmapType.INSTANCE).args(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Histogram.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Histogram.java
index 26e02959243..e3b7722459e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Histogram.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Histogram.java
@@ -37,7 +37,7 @@ import java.util.List;
  * AggregateFunction 'histogram'. This class is generated by GenerateFunction.
  */
 public class Histogram extends NotNullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnion.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnion.java
index 37f1e206a4b..5eb0b3a5227 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnion.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnion.java
@@ -36,7 +36,8 @@ import java.util.List;
  * AggregateFunction 'hll_union'. This class is generated by GenerateFunction.
  */
 public class HllUnion extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(HllType.INSTANCE).args(HllType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnionAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnionAgg.java
index ab37fa27927..ce516da455e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnionAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/HllUnionAgg.java
@@ -37,7 +37,8 @@ import java.util.List;
  * AggregateFunction 'hll_union_agg'. This class is generated by 
GenerateFunction.
  */
 public class HllUnionAgg extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(BigIntType.INSTANCE).args(HllType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/IntersectCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/IntersectCount.java
index 5c178210e0f..994a173bb79 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/IntersectCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/IntersectCount.java
@@ -37,7 +37,7 @@ import java.util.List;
  * AggregateFunction 'intersect_count'. This class is generated by 
GenerateFunction.
  */
 public class IntersectCount extends NotNullableAggregateFunction
-        implements ExplicitlyCastableSignature, BitmapIntersectFunction {
+        implements ExplicitlyCastableSignature, BitmapIntersectFunction, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = 
DataType.trivialTypes().stream()
             .map(type -> 
FunctionSignature.ret(BigIntType.INSTANCE).varArgs(BitmapType.INSTANCE, type, 
type))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Kurt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Kurt.java
index d48cf37089c..4c48d53fd28 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Kurt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Kurt.java
@@ -34,7 +34,8 @@ import java.util.List;
  * AggregateFunction 'Kurt'.
  */
 public class Kurt extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/LinearHistogram.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/LinearHistogram.java
index ace99ad65f9..f09da28b02a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/LinearHistogram.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/LinearHistogram.java
@@ -36,7 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'linear_histogram'.
  */
-public class LinearHistogram extends NotNullableAggregateFunction implements 
ExplicitlyCastableSignature {
+public class LinearHistogram extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT)
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 600ea1d939a..ae144c578db 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
@@ -37,7 +37,7 @@ import java.util.List;
 
 /** max agg function. */
 public class Max extends NullableAggregateFunction
-        implements UnaryExpression, CustomSignature, SupportWindowAnalytic, 
RollUpTrait {
+        implements UnaryExpression, CustomSignature, SupportWindowAnalytic, 
RollUpTrait, NullIgnoringAggregateFunction {
     public Max(Expression child) {
         this(false, false, child);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MaxBy.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MaxBy.java
index 63ca76c4800..96e6c040577 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MaxBy.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MaxBy.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'max_by'. This class is generated by GenerateFunction.
  */
 public class MaxBy extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX, 
AnyDataType.INSTANCE_WITHOUT_INDEX)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Median.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Median.java
index f91af0352de..7c396c90bf4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Median.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Median.java
@@ -41,7 +41,7 @@ import java.util.List;
  * AggregateFunction 'median'. This class is generated by GenerateFunction.
  */
 public class Median extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
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 515e2e7323f..50f44fe514d 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
@@ -37,7 +37,7 @@ import java.util.List;
 
 /** min agg function. */
 public class Min extends NullableAggregateFunction
-        implements UnaryExpression, CustomSignature, SupportWindowAnalytic, 
RollUpTrait {
+        implements UnaryExpression, CustomSignature, SupportWindowAnalytic, 
RollUpTrait, NullIgnoringAggregateFunction {
 
     public Min(Expression child) {
         this(false, false, child);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MinBy.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MinBy.java
index ab3f7a68e74..b59c1a63062 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MinBy.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MinBy.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'min_by'. This class is generated by GenerateFunction.
  */
 public class MinBy extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX, 
AnyDataType.INSTANCE_WITHOUT_INDEX)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctCount.java
index 014c1652d9a..65155cd3033 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctCount.java
@@ -35,7 +35,7 @@ import java.util.List;
 
 /** MultiDistinctCount */
 public class MultiDistinctCount extends NotNullableAggregateFunction
-        implements ExplicitlyCastableSignature, MultiDistinction {
+        implements ExplicitlyCastableSignature, MultiDistinction, 
NullIgnoringAggregateFunction {
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).varArgs(AnyDataType.INSTANCE_WITHOUT_INDEX)
     );
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum.java
index 0e34ea50ba5..8d3f3500c6a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum.java
@@ -33,7 +33,8 @@ import java.util.List;
 
 /** MultiDistinctSum */
 public class MultiDistinctSum extends NullableAggregateFunction implements 
UnaryExpression,
-        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction, 
NeedSessionVarGuard {
+        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction, 
NeedSessionVarGuard,
+        NullIgnoringAggregateFunction {
     public MultiDistinctSum(Expression arg0) {
         this(false, arg0);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum0.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum0.java
index f47adeac7d3..61e17bbf909 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum0.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum0.java
@@ -40,7 +40,8 @@ import java.util.List;
 
 /** MultiDistinctSum0 */
 public class MultiDistinctSum0 extends NotNullableAggregateFunction implements 
UnaryExpression,
-        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction, 
NeedSessionVarGuard {
+        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction, 
NeedSessionVarGuard,
+        NullIgnoringAggregateFunction {
     public MultiDistinctSum0(Expression arg0) {
         this(false, arg0);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Ndv.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Ndv.java
index 760a702d27b..a10a1dd60b2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Ndv.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Ndv.java
@@ -38,7 +38,8 @@ import java.util.List;
  * AggregateFunction 'ndv'. This class is generated by GenserateFunction.
  */
 public class Ndv extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, RollUpTrait {
+        implements UnaryExpression, ExplicitlyCastableSignature, RollUpTrait,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).args(AnyDataType.INSTANCE_WITHOUT_INDEX)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullIgnoringAggregateFunction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullIgnoringAggregateFunction.java
new file mode 100644
index 00000000000..6726922615c
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NullIgnoringAggregateFunction.java
@@ -0,0 +1,35 @@
+// 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;
+
+/**
+ * Marker for aggregate functions that ignore a row when any aggregate 
argument is SQL NULL.
+ *
+ * <p>Removing such rows does not change the aggregate result, so {@code 
InferAggNotNull} may add
+ * inferred not-null predicates for their arguments. Equivalently, adding or 
removing rows with a
+ * NULL aggregate argument is result-invariant; in particular, an input 
consisting only of rows in
+ * which at least one aggregate argument is NULL must produce the same result 
as an empty input.
+ * This describes input-row handling and is independent of whether the 
aggregate result itself is
+ * nullable. A not-null result such as zero or an empty collection can 
therefore satisfy this
+ * contract.
+ *
+ * <p>Implement this interface only when the contract holds for every 
signature and mode of the
+ * aggregate function, including DISTINCT.
+ */
+public interface NullIgnoringAggregateFunction {
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculate.java
index 6ddd211764d..eb17c454ee9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculate.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculate.java
@@ -34,7 +34,8 @@ import java.util.List;
 
 /** OrthogonalBitmapExprCalculate */
 public class OrthogonalBitmapExprCalculate extends NotNullableAggregateFunction
-        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature {
+        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature,
+        NullIgnoringAggregateFunction {
 
     static final List<FunctionSignature> FUNCTION_SIGNATURES = 
ImmutableList.of(
             FunctionSignature.ret(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculateCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculateCount.java
index 21b3232d4f7..f5f347f80d8 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculateCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculateCount.java
@@ -35,7 +35,8 @@ import java.util.List;
 
 /** OrthogonalBitmapExprCalculateCount */
 public class OrthogonalBitmapExprCalculateCount extends 
NotNullableAggregateFunction
-        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature {
+        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature,
+        NullIgnoringAggregateFunction {
 
     static final List<FunctionSignature> FUNCTION_SIGNATURES = 
ImmutableList.of(
             FunctionSignature.ret(BigIntType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersect.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersect.java
index 691f2866e77..6d1334f6418 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersect.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersect.java
@@ -34,7 +34,7 @@ import java.util.List;
  * AggregateFunction 'orthogonal_bitmap_intersect'. This class is generated by 
GenerateFunction.
  */
 public class OrthogonalBitmapIntersect extends NotNullableAggregateFunction
-        implements OrthogonalBitmapFunction, BitmapIntersectFunction {
+        implements OrthogonalBitmapFunction, BitmapIntersectFunction, 
NullIgnoringAggregateFunction {
 
     static final List<FunctionSignature> FUNCTION_SIGNATURES = 
SUPPORTED_TYPES.stream()
             .map(type -> 
FunctionSignature.ret(BitmapType.INSTANCE).varArgs(BitmapType.INSTANCE, type, 
type))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersectCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersectCount.java
index 6f7793944b7..030c7faf20e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersectCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapIntersectCount.java
@@ -31,7 +31,7 @@ import java.util.List;
  * AggregateFunction 'orthogonal_bitmap_intersect_count'. This class is 
generated by GenerateFunction.
  */
 public class OrthogonalBitmapIntersectCount extends 
NotNullableAggregateFunction
-        implements OrthogonalBitmapFunction, BitmapIntersectFunction {
+        implements OrthogonalBitmapFunction, BitmapIntersectFunction, 
NullIgnoringAggregateFunction {
 
     /**
      * constructor with 3 or more arguments.
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapUnionCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapUnionCount.java
index dbe83baa76c..7ead5151a2e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapUnionCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapUnionCount.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'orthogonal_bitmap_union_count'. This class is generated 
by GenerateFunction.
  */
 public class OrthogonalBitmapUnionCount extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).args(BitmapType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Percentile.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Percentile.java
index 41d85424f8e..a134414d361 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Percentile.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Percentile.java
@@ -40,7 +40,7 @@ import java.util.List;
  * AggregateFunction 'percentile'. This class is generated by GenerateFunction.
  */
 public class Percentile extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApprox.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApprox.java
index d889f588df6..cd4c2347e50 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApprox.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApprox.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'percentile_approx'. This class is generated by 
GenerateFunction.
  */
 public class PercentileApprox extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApproxWeighted.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApproxWeighted.java
index 86e3f40c781..5d3154c908c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApproxWeighted.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileApproxWeighted.java
@@ -33,7 +33,7 @@ import java.util.List;
  * AggregateFunction 'percentile_approx_weighted'.
  */
 public class PercentileApproxWeighted extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileArray.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileArray.java
index 560d1003383..77e48767f10 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileArray.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileArray.java
@@ -43,7 +43,7 @@ import java.util.List;
  * AggregateFunction 'percentile_array'. This class is generated by 
GenerateFunction.
  */
 public class PercentileArray extends NotNullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(ArrayType.of(DoubleType.INSTANCE))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileReservoir.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileReservoir.java
index 7c6f7bb6652..38978330ad7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileReservoir.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/PercentileReservoir.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'percentile_reservoir'
  */
 public class PercentileReservoir extends NullableAggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/QuantileUnion.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/QuantileUnion.java
index 6b433e7895d..b6c533d2559 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/QuantileUnion.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/QuantileUnion.java
@@ -36,7 +36,7 @@ import java.util.List;
  * AggregateFunction 'quantile_union'. This class is generated by 
GenerateFunction.
  */
 public class QuantileUnion extends NotNullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(QuantileStateType.INSTANCE).args(QuantileStateType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrIntercept.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrIntercept.java
index 7b37844d43b..35f09177ec0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrIntercept.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrIntercept.java
@@ -36,7 +36,8 @@ import java.util.List;
  * AggregateFunction 'regr_intercept'.
  */
 public class RegrIntercept extends AggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrSlope.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrSlope.java
index a3e76dea3cd..65f98d4b342 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrSlope.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/RegrSlope.java
@@ -36,7 +36,8 @@ import java.util.List;
  * AggregateFunction 'regr_slope'.
  */
 public class RegrSlope extends AggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable {
+        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, 
DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Retention.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Retention.java
index 87177f34b38..ec6888b42fe 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Retention.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Retention.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'retention'. This class is generated by GenerateFunction.
  */
 public class Retention extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     // The BE side stores the retention state in a fixed-size array
     // (RetentionState::MAX_EVENTS, uint8_t events[32]) and also serializes it 
into a single
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sem.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sem.java
index 7e0dbd53787..3f6be349fb1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sem.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sem.java
@@ -34,7 +34,7 @@ import java.util.List;
  */
 
 public class Sem extends NullableAggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceCount.java
index f0cc6fac537..813c63a9f34 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceCount.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceCount.java
@@ -40,7 +40,7 @@ import java.util.List;
  * AggregateFunction 'sequence_count'. This class is generated by 
GenerateFunction.
  */
 public class SequenceCount extends NotNullableAggregateFunction
-        implements ExplicitlyCastableSignature, SequenceFunction {
+        implements ExplicitlyCastableSignature, SequenceFunction, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(BigIntType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceMatch.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceMatch.java
index 24dc7f8367a..87bd7925506 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceMatch.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceMatch.java
@@ -38,7 +38,7 @@ import java.util.List;
  * AggregateFunction 'sequence_match'. This class is generated by 
GenerateFunction.
  */
 public class SequenceMatch extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature, SequenceFunction {
+        implements ExplicitlyCastableSignature, SequenceFunction, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(BooleanType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Skew.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Skew.java
index aa46bcecc12..bba96f772a4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Skew.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Skew.java
@@ -35,7 +35,8 @@ import java.util.List;
  */
 
 public class Skew extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable {
+        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Stddev.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Stddev.java
index 1dd4e46f998..bfeecf10fa9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Stddev.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Stddev.java
@@ -35,7 +35,7 @@ import java.util.List;
  */
 public class Stddev extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature,
-        StdDevOrVarianceFunction, DecimalStddevPrecision {
+        StdDevOrVarianceFunction, DecimalStddevPrecision, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/StddevSamp.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/StddevSamp.java
index 7eac03ca5c3..84e1359421a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/StddevSamp.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/StddevSamp.java
@@ -35,7 +35,7 @@ import java.util.List;
  */
 public class StddevSamp extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature,
-        StdDevOrVarianceFunction, DecimalStddevPrecision {
+        StdDevOrVarianceFunction, DecimalStddevPrecision, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE));
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 681bc2b6281..677c7797f24 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
@@ -48,7 +48,7 @@ import java.util.List;
  */
 public class Sum extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature, 
ComputePrecisionForSum, SupportWindowAnalytic,
-        RollUpTrait, SupportMultiDistinct, NeedSessionVarGuard {
+        RollUpTrait, SupportMultiDistinct, NeedSessionVarGuard, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum0.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum0.java
index c2514426226..3f989368b3e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum0.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum0.java
@@ -57,7 +57,8 @@ import java.util.List;
  */
 public class Sum0 extends NotNullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature, 
ComputePrecisionForSum,
-        SupportWindowAnalytic, RollUpTrait, SupportMultiDistinct, 
NeedSessionVarGuard {
+        SupportWindowAnalytic, RollUpTrait, SupportMultiDistinct, 
NeedSessionVarGuard,
+        NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopN.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopN.java
index b223b130cc0..cb5d94832ed 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopN.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopN.java
@@ -35,7 +35,7 @@ import java.util.List;
  * AggregateFunction 'topn'. This class is generated by GenerateFunction.
  */
 public class TopN extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT,
 IntegerType.INSTANCE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNArray.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNArray.java
index bc370be9619..bc0dae22a76 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNArray.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNArray.java
@@ -37,7 +37,7 @@ import java.util.List;
  * AggregateFunction 'topn_array'. This class is generated by GenerateFunction.
  */
 public class TopNArray extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(ArrayType.of(new FollowToAnyDataType(0)))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNWeighted.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNWeighted.java
index 3af51db6042..0f9b9575081 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNWeighted.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/TopNWeighted.java
@@ -50,7 +50,7 @@ import java.util.List;
  * AggregateFunction 'topn_weighted'. This class is generated by 
GenerateFunction.
  */
 public class TopNWeighted extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             // three arguments
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 756948ea9eb..f5c49b16ad1 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
@@ -35,7 +35,7 @@ import java.util.List;
  */
 public class Variance extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature,
-        StdDevOrVarianceFunction, DecimalStddevPrecision {
+        StdDevOrVarianceFunction, DecimalStddevPrecision, 
NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE));
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 ab3af3e7888..5c2a8581867 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
@@ -34,7 +34,7 @@ import java.util.List;
  */
 public class VarianceSamp extends NullableAggregateFunction
         implements UnaryExpression, ExplicitlyCastableSignature,
-        StdDevOrVarianceFunction {
+        StdDevOrVarianceFunction, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnel.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnel.java
index 9f152821c2f..6a844b22cdd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnel.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnel.java
@@ -43,7 +43,7 @@ import java.util.List;
  * AggregateFunction 'window_funnel'. This class is generated by 
GenerateFunction.
  */
 public class WindowFunnel extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(IntegerType.INSTANCE)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnelV2.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnelV2.java
index fabca97f744..c6d6bb02212 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnelV2.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/WindowFunnelV2.java
@@ -44,7 +44,7 @@ import java.util.List;
  * as (timestamp, event_index) pairs, dramatically reducing memory usage 
compared to V1.
  */
 public class WindowFunnelV2 extends NullableAggregateFunction
-        implements ExplicitlyCastableSignature {
+        implements ExplicitlyCastableSignature, NullIgnoringAggregateFunction {
 
     public static final int MAX_EVENT_CONDITIONS = 127;
 
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferAggNotNullTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferAggNotNullTest.java
index feea96e0f4d..c127f7e40ad 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferAggNotNullTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferAggNotNullTest.java
@@ -28,9 +28,18 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.IsNull;
 import org.apache.doris.nereids.trees.expressions.Not;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
+import org.apache.doris.nereids.trees.expressions.functions.agg.ArrayAgg;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Avg;
+import org.apache.doris.nereids.trees.expressions.functions.agg.BitmapAgg;
+import org.apache.doris.nereids.trees.expressions.functions.agg.CollectList;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
+import org.apache.doris.nereids.trees.expressions.functions.agg.CountByEnum;
+import org.apache.doris.nereids.trees.expressions.functions.agg.GroupConcat;
+import org.apache.doris.nereids.trees.expressions.functions.agg.MapAgg;
+import org.apache.doris.nereids.trees.expressions.functions.agg.MapAggV2;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.NullIgnoringAggregateFunction;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
+import org.apache.doris.nereids.trees.expressions.functions.agg.Sum0;
 import org.apache.doris.nereids.trees.plans.RelationId;
 import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
@@ -90,6 +99,66 @@ class InferAggNotNullTest implements 
MemoPatternMatchSupported {
                 );
     }
 
+    @Test
+    void testNotInferForNullSensitiveAggregate() {
+        LogicalPlan plan = new LogicalPlanBuilder(scan1)
+                .aggGroupUsingIndex(ImmutableList.of(),
+                        ImmutableList.of(new Alias(new 
ArrayAgg(scan1.getOutput().get(1)), "values")))
+                .build();
+
+        PlanChecker.from(MemoTestUtils.createConnectContext(), plan)
+                .applyTopDown(new InferAggNotNull())
+                .matches(
+                        logicalAggregate(
+                                logicalOlapScan()
+                        )
+                );
+    }
+
+    @Test
+    void testAuditedNullInputContractMarkers() {
+        Expression key = scan1.getOutput().get(0);
+        Expression value = scan1.getOutput().get(1);
+
+        List<AggregateFunction> nullIgnoring = ImmutableList.of(
+                new Sum(value),
+                new Sum0(value),
+                new CollectList(value),
+                new BitmapAgg(value));
+        nullIgnoring.forEach(function -> Assertions.assertTrue(
+                function instanceof NullIgnoringAggregateFunction,
+                function.getName() + " must declare the audited null-row 
contract"));
+
+        // NotNullableAggregateFunction does not imply that NULL argument rows 
can be removed.
+        List<AggregateFunction> withoutClassWideProof = ImmutableList.of(
+                new ArrayAgg(value),
+                new MapAgg(key, value),
+                new MapAggV2(key, value),
+                new CountByEnum(value),
+                new GroupConcat(value));
+        withoutClassWideProof.forEach(function -> Assertions.assertFalse(
+                function instanceof NullIgnoringAggregateFunction,
+                function.getName() + " must remain conservative until every 
mode is proven"));
+    }
+
+    @Test
+    void testNullSensitiveAggregateBlocksCommonInference() {
+        LogicalPlan plan = new LogicalPlanBuilder(scan1)
+                .aggGroupUsingIndex(ImmutableList.of(),
+                        ImmutableList.of(
+                                new Alias(new Count(false, 
scan1.getOutput().get(1)), "count_k"),
+                                new Alias(new 
ArrayAgg(scan1.getOutput().get(1)), "values")))
+                .build();
+
+        PlanChecker.from(MemoTestUtils.createConnectContext(), plan)
+                .applyTopDown(new InferAggNotNull())
+                .matches(
+                        logicalAggregate(
+                                logicalOlapScan()
+                        )
+                );
+    }
+
     @Test
     void testNotInferMultipleAggregateDifferentInputs() {
         LogicalPlan plan = new LogicalPlanBuilder(scan1)
diff --git 
a/regression-test/data/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.out
 
b/regression-test/data/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.out
index 8205077a801..4de89d48061 100644
--- 
a/regression-test/data/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.out
+++ 
b/regression-test/data/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.out
@@ -175,6 +175,58 @@ PhysicalResultSink
 ----PhysicalProject
 ------PhysicalOlapScan[t4]
 
+-- !array_agg_no_eliminate --
+PhysicalResultSink
+--PhysicalProject
+----hashAgg[GLOBAL]
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------PhysicalOlapScan[t4]
+
+-- !collect_list_eliminate --
+PhysicalResultSink
+--PhysicalProject
+----hashAgg[GLOBAL]
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------filter((t4.c4 = 102))
+------------PhysicalOlapScan[t4]
+
+-- !collect_list_distinct_eliminate --
+PhysicalResultSink
+--PhysicalProject
+----hashAgg[DISTINCT_GLOBAL]
+------hashAgg[DISTINCT_LOCAL]
+--------hashAgg[GLOBAL]
+----------hashAgg[LOCAL]
+------------PhysicalProject
+--------------PhysicalOlapScan[t4]
+
+-- !bool_or_eliminate --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------PhysicalProject
+--------filter((t4.c4 = 102))
+----------PhysicalOlapScan[t4]
+
+-- !sum0_eliminate --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------PhysicalProject
+--------filter((t4.c4 = 102))
+----------PhysicalOlapScan[t4]
+
+-- !bitmap_agg_eliminate --
+PhysicalResultSink
+--PhysicalProject
+----hashAgg[GLOBAL]
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------filter((t4.c4 = 102))
+------------PhysicalOlapScan[t4]
+
 -- !basic_1 --
 10
 
@@ -247,3 +299,24 @@ PhysicalResultSink
 102    1
 103    1
 
+-- !array_agg_preserves_null --
+2
+
+-- !array_agg_distinct_preserves_null --
+2
+
+-- !collect_list_ignores_null --
+1
+
+-- !collect_list_distinct_ignores_null --
+1
+
+-- !bool_or_ignores_null --
+true
+
+-- !sum0_ignores_null --
+102
+
+-- !bitmap_agg_ignores_null --
+1
+
diff --git 
a/regression-test/data/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.out
 
b/regression-test/data/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.out
new file mode 100644
index 00000000000..feb9fa5c982
--- /dev/null
+++ 
b/regression-test/data/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.out
@@ -0,0 +1,10 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !null_ignoring_aggregate_identities --
+9      9       1       1
+
+-- !all_null_equals_empty_input --
+\N     \N      0       0       0       0       0       0
+
+-- !null_sensitive_aggregates_keep_rows --
+3      3
+
diff --git 
a/regression-test/suites/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.groovy
 
b/regression-test/suites/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.groovy
index 1560310e43d..29bb3e7f74a 100644
--- 
a/regression-test/suites/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.groovy
+++ 
b/regression-test/suites/nereids_rules_p0/eliminate_aggregate_casewhen/eliminate_aggregate_casewhen.groovy
@@ -74,6 +74,34 @@ suite("eliminate_aggregate_casewhen") {
     qt_basic_4_5 """explain shape plan select count(case when t4.c4 > 100 then 
10 end) from t4;"""
     qt_basic_4_6 """explain shape plan select t4.c4, count(case when t4.c4 > 
100 then 10 end) from t4 group by t4.c4;"""
 
+    // NULL-preserving aggregates must keep the IF expression and all input 
rows.
+    qt_array_agg_no_eliminate """
+        explain shape plan
+        select array_size(array_agg(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
+
+    // Audited NULL-ignoring aggregates remain eligible for the rewrite.
+    qt_collect_list_eliminate """
+        explain shape plan
+        select array_size(collect_list(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
+    qt_collect_list_distinct_eliminate """
+        explain shape plan
+        select array_size(collect_list(distinct case when t4.c4 = 102 then 
t4.c4 end)) from t4;
+    """
+    qt_bool_or_eliminate """
+        explain shape plan
+        select bool_or(case when t4.c4 = 102 then cast(t4.c4 as boolean) end) 
from t4;
+    """
+    qt_sum0_eliminate """
+        explain shape plan
+        select sum0(case when t4.c4 = 102 then t4.c4 end) from t4;
+    """
+    qt_bitmap_agg_eliminate """
+        explain shape plan
+        select bitmap_count(bitmap_agg(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
+
     /* ******** Output ******** */
 
     /* ******** with one row ******** */
@@ -107,4 +135,26 @@ suite("eliminate_aggregate_casewhen") {
     order_qt_basic_4_4 """select max(case when t4.c4 > 100 then 10 end) from 
t4;"""
     order_qt_basic_4_5 """select count(case when t4.c4 > 100 then 10 end) from 
t4;"""
     order_qt_basic_4_6 """select t4.c4, count(case when t4.c4 > 100 then 10 
end) from t4 group by t4.c4;"""
+
+    order_qt_array_agg_preserves_null """
+        select array_size(array_agg(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
+    order_qt_array_agg_distinct_preserves_null """
+        select array_size(array_agg(distinct case when t4.c4 = 102 then t4.c4 
end)) from t4;
+    """
+    order_qt_collect_list_ignores_null """
+        select array_size(collect_list(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
+    order_qt_collect_list_distinct_ignores_null """
+        select array_size(collect_list(distinct case when t4.c4 = 102 then 
t4.c4 end)) from t4;
+    """
+    order_qt_bool_or_ignores_null """
+        select bool_or(case when t4.c4 = 102 then cast(t4.c4 as boolean) end) 
from t4;
+    """
+    order_qt_sum0_ignores_null """
+        select sum0(case when t4.c4 = 102 then t4.c4 end) from t4;
+    """
+    order_qt_bitmap_agg_ignores_null """
+        select bitmap_count(bitmap_agg(case when t4.c4 = 102 then t4.c4 end)) 
from t4;
+    """
 }
diff --git 
a/regression-test/suites/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.groovy
 
b/regression-test/suites/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.groovy
new file mode 100644
index 00000000000..056287766cd
--- /dev/null
+++ 
b/regression-test/suites/nereids_rules_p0/infer_agg_not_null/infer_agg_not_null.groovy
@@ -0,0 +1,76 @@
+// 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("infer_agg_not_null") {
+    sql "DROP TABLE IF EXISTS infer_agg_not_null_left"
+    sql "DROP TABLE IF EXISTS infer_agg_not_null_right"
+
+    sql """
+        CREATE TABLE infer_agg_not_null_left (
+            k INT NOT NULL
+        ) DUPLICATE KEY(k)
+        DISTRIBUTED BY HASH(k) BUCKETS 1
+        PROPERTIES ("replication_num" = "1")
+    """
+
+    sql """
+        CREATE TABLE infer_agg_not_null_right (
+            k INT NOT NULL,
+            v INT NULL
+        ) DUPLICATE KEY(k, v)
+        DISTRIBUTED BY HASH(k) BUCKETS 1
+        PROPERTIES ("replication_num" = "1")
+    """
+
+    sql "INSERT INTO infer_agg_not_null_left VALUES (1), (2), (3)"
+    sql "INSERT INTO infer_agg_not_null_right VALUES (2, 9), (3, NULL)"
+
+    order_qt_null_ignoring_aggregate_identities """
+        SELECT SUM(r.v), SUM0(r.v), ARRAY_SIZE(COLLECT_LIST(r.v)),
+               BITMAP_COUNT(BITMAP_AGG(r.v))
+        FROM infer_agg_not_null_left l
+        LEFT JOIN infer_agg_not_null_right r ON l.k = r.k
+    """
+
+    order_qt_all_null_equals_empty_input """
+        SELECT
+            (SELECT SUM(v) FROM infer_agg_not_null_right WHERE k = 3),
+            (SELECT SUM(v) FROM infer_agg_not_null_right WHERE FALSE),
+            (SELECT SUM0(v) FROM infer_agg_not_null_right WHERE k = 3),
+            (SELECT SUM0(v) FROM infer_agg_not_null_right WHERE FALSE),
+            (SELECT ARRAY_SIZE(COLLECT_LIST(v)) FROM infer_agg_not_null_right 
WHERE k = 3),
+            (SELECT ARRAY_SIZE(COLLECT_LIST(v)) FROM infer_agg_not_null_right 
WHERE FALSE),
+            (SELECT BITMAP_COUNT(BITMAP_AGG(v)) FROM infer_agg_not_null_right 
WHERE k = 3),
+            (SELECT BITMAP_COUNT(BITMAP_AGG(v)) FROM infer_agg_not_null_right 
WHERE FALSE)
+    """
+
+    order_qt_null_sensitive_aggregates_keep_rows """
+        SELECT ARRAY_SIZE(ARRAY_AGG(r.v)), MAP_SIZE(MAP_AGG(l.k, r.v))
+        FROM infer_agg_not_null_left l
+        LEFT JOIN infer_agg_not_null_right r ON l.k = r.k
+    """
+
+    explain {
+        sql """
+            SHAPE PLAN
+            SELECT ARRAY_SIZE(ARRAY_AGG(r.v)), MAP_SIZE(MAP_AGG(l.k, r.v))
+            FROM infer_agg_not_null_left l
+            LEFT JOIN infer_agg_not_null_right r ON l.k = r.k
+        """
+        contains "LEFT_OUTER_JOIN"
+    }
+}


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

Reply via email to