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

huajianlan pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new baedeb29e95 [feature](function) support 
orthogonal_bitmap_expr_calculate & orthogonal_bitmap_expr_calculate_count for 
nereids (#44671) (#44991) (#45011)
baedeb29e95 is described below

commit baedeb29e9572d5364cbbfbc45becc488571fe60
Author: 924060929 <lanhuaj...@selectdb.com>
AuthorDate: Thu Dec 5 19:03:56 2024 +0800

    [feature](function) support orthogonal_bitmap_expr_calculate & 
orthogonal_bitmap_expr_calculate_count for nereids (#44671) (#44991) (#45011)
    
    cherry pick from #44671 and #44991
    
    #44671
    AlwaysNotNullable agg functions must return a non-null value if it's a 
scalar agg. So a new base class NotNullableAggregateFunction is introduced, all 
sub classes must implement resultForEmptyInput method to get the non-null value 
correctly
    
    #44991
    support orthogonal_bitmap_expr_calculate & 
orthogonal_bitmap_expr_calculate_count for nereids
    
    
    Co-authored-by: starocean999 <li...@selectdb.com>
---
 .../aggregate_function_orthogonal_bitmap.h         |  2 +-
 .../doris/catalog/BuiltinAggregateFunctions.java   | 24 +++---
 .../nereids/rules/analysis/SubqueryToApply.java    |  8 +-
 .../rules/implementation/AggregateStrategies.java  | 14 +++-
 .../expressions/functions/AlwaysNotNullable.java   |  9 ---
 .../functions/agg/AggregateFunction.java           |  4 +
 .../AggregatePhase.java}                           | 24 +-----
 .../trees/expressions/functions/agg/ArrayAgg.java  |  5 +-
 .../trees/expressions/functions/agg/BitmapAgg.java |  5 +-
 .../expressions/functions/agg/BitmapIntersect.java |  5 +-
 .../expressions/functions/agg/BitmapUnion.java     |  5 +-
 .../functions/agg/BitmapUnionCount.java            |  5 +-
 .../expressions/functions/agg/BitmapUnionInt.java  |  5 +-
 .../expressions/functions/agg/CollectList.java     |  5 +-
 .../expressions/functions/agg/CollectSet.java      |  5 +-
 .../trees/expressions/functions/agg/Count.java     |  5 +-
 .../expressions/functions/agg/CountByEnum.java     |  3 +-
 .../functions/agg/GroupArrayIntersect.java         |  5 +-
 .../trees/expressions/functions/agg/Histogram.java |  5 +-
 .../trees/expressions/functions/agg/HllUnion.java  |  5 +-
 .../expressions/functions/agg/HllUnionAgg.java     |  5 +-
 .../expressions/functions/agg/IntersectCount.java  |  5 +-
 .../trees/expressions/functions/agg/MapAgg.java    |  5 +-
 .../functions/agg/MultiDistinctCount.java          |  5 +-
 .../functions/agg/MultiDistinctSum0.java           |  5 +-
 .../trees/expressions/functions/agg/Ndv.java       |  5 +-
 .../NotNullableAggregateFunction.java}             | 33 ++++++---
 .../agg/OrthogonalBitmapExprCalculate.java         | 84 +++++++++++++++++++++
 .../agg/OrthogonalBitmapExprCalculateCount.java    | 86 ++++++++++++++++++++++
 .../functions/agg/OrthogonalBitmapIntersect.java   | 11 ++-
 .../agg/OrthogonalBitmapIntersectCount.java        | 13 +++-
 .../functions/agg/OrthogonalBitmapUnionCount.java  | 11 ++-
 .../expressions/functions/agg/PercentileArray.java |  5 +-
 .../expressions/functions/agg/QuantileUnion.java   |  5 +-
 .../expressions/functions/agg/SequenceCount.java   |  5 +-
 .../trees/expressions/functions/agg/Sum0.java      |  5 +-
 .../trees/plans/logical/LogicalAggregate.java      | 12 +++
 .../test_orthogonal_bitmap_expr_calculate.groovy   | 55 ++++++++++++++
 38 files changed, 368 insertions(+), 135 deletions(-)

diff --git 
a/be/src/vec/aggregate_functions/aggregate_function_orthogonal_bitmap.h 
b/be/src/vec/aggregate_functions/aggregate_function_orthogonal_bitmap.h
index a81bdcddaa3..d7d00140b49 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_orthogonal_bitmap.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_orthogonal_bitmap.h
@@ -234,7 +234,7 @@ public:
         if (first_init) {
             DCHECK(argument_size > 1);
             const auto& col =
-                    assert_cast<const ColVecData&, 
TypeCheckOnRelease::DISABLE>(*columns[2]);
+                    assert_cast<const ColumnString&, 
TypeCheckOnRelease::DISABLE>(*columns[2]);
             std::string expr = col.get_data_at(row_num).to_string();
             bitmap_expr_cal.bitmap_calculation_init(expr);
             first_init = false;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinAggregateFunctions.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinAggregateFunctions.java
index 8c7eaabe51d..624e701c033 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinAggregateFunctions.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinAggregateFunctions.java
@@ -56,6 +56,8 @@ import 
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctGro
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum0;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Ndv;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapExprCalculate;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapExprCalculateCount;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapIntersect;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapIntersectCount;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.OrthogonalBitmapUnionCount;
@@ -121,6 +123,7 @@ public class BuiltinAggregateFunctions implements 
FunctionHelper {
             agg(HllUnion.class, "hll_raw_agg", "hll_union"),
             agg(HllUnionAgg.class, "hll_union_agg"),
             agg(IntersectCount.class, "intersect_count"),
+            agg(Kurt.class, "kurt", "kurt_pop", "kurtosis"),
             agg(MapAgg.class, "map_agg"),
             agg(Max.class, "max"),
             agg(MaxBy.class, "max_by"),
@@ -131,17 +134,20 @@ public class BuiltinAggregateFunctions implements 
FunctionHelper {
             agg(MultiDistinctSum.class, "multi_distinct_sum"),
             agg(MultiDistinctSum0.class, "multi_distinct_sum0"),
             agg(Ndv.class, "approx_count_distinct", "ndv"),
+            agg(OrthogonalBitmapExprCalculate.class, 
"orthogonal_bitmap_expr_calculate"),
+            agg(OrthogonalBitmapExprCalculateCount.class, 
"orthogonal_bitmap_expr_calculate_count"),
             agg(OrthogonalBitmapIntersect.class, 
"orthogonal_bitmap_intersect"),
             agg(OrthogonalBitmapIntersectCount.class, 
"orthogonal_bitmap_intersect_count"),
-                    agg(OrthogonalBitmapUnionCount.class, 
"orthogonal_bitmap_union_count"),
-                    agg(Percentile.class, "percentile"),
-                    agg(PercentileApprox.class, "percentile_approx"),
-                    agg(PercentileApproxWeighted.class, 
"percentile_approx_weighted"),
-                    agg(PercentileArray.class, "percentile_array"),
-                    agg(QuantileUnion.class, "quantile_union"),
-                    agg(Retention.class, "retention"),
+            agg(OrthogonalBitmapUnionCount.class, 
"orthogonal_bitmap_union_count"),
+            agg(Percentile.class, "percentile"),
+            agg(PercentileApprox.class, "percentile_approx"),
+            agg(PercentileApproxWeighted.class, "percentile_approx_weighted"),
+            agg(PercentileArray.class, "percentile_array"),
+            agg(QuantileUnion.class, "quantile_union"),
+            agg(Retention.class, "retention"),
             agg(SequenceCount.class, "sequence_count"),
             agg(SequenceMatch.class, "sequence_match"),
+            agg(Skew.class, "skew", "skew_pop", "skewness"),
             agg(Stddev.class, "stddev_pop", "stddev"),
             agg(StddevSamp.class, "stddev_samp"),
             agg(Sum.class, "sum"),
@@ -151,9 +157,7 @@ public class BuiltinAggregateFunctions implements 
FunctionHelper {
             agg(TopNWeighted.class, "topn_weighted"),
             agg(Variance.class, "var_pop", "variance_pop", "variance"),
             agg(VarianceSamp.class, "var_samp", "variance_samp"),
-            agg(WindowFunnel.class, "window_funnel"),
-            agg(Skew.class, "skew", "skew_pop", "skewness"),
-            agg(Kurt.class, "kurt", "kurt_pop", "kurtosis")
+            agg(WindowFunnel.class, "window_funnel")
     );
 
     public final Set<String> aggFuncNames = aggregateFunctions.stream()
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
index 17e7d098cad..d64c7f2baed 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
@@ -42,9 +42,9 @@ import 
org.apache.doris.nereids.trees.expressions.ScalarSubquery;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
 import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import org.apache.doris.nereids.trees.expressions.functions.agg.AnyValue;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.NotNullableAggregateFunction;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.AssertTrue;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Nvl;
 import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
@@ -424,9 +424,9 @@ public class SubqueryToApply implements AnalysisRuleFactory 
{
                     Map<Expression, Expression> replaceMap = new HashMap<>();
                     NamedExpression agg = ((ScalarSubquery) 
subquery).getTopLevelScalarAggFunction().get();
                     if (agg instanceof Alias) {
-                        if (((Alias) agg).child() instanceof 
AlwaysNotNullable) {
-                            AlwaysNotNullable notNullableAggFunc =
-                                    (AlwaysNotNullable) ((Alias) agg).child();
+                        if (((Alias) agg).child() instanceof 
NotNullableAggregateFunction) {
+                            NotNullableAggregateFunction notNullableAggFunc =
+                                    (NotNullableAggregateFunction) ((Alias) 
agg).child();
                             if (subquery.getQueryPlan() instanceof 
LogicalProject) {
                                 LogicalProject logicalProject =
                                         (LogicalProject) 
subquery.getQueryPlan();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/AggregateStrategies.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/AggregateStrategies.java
index 6cf243bbfee..094882294fa 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/AggregateStrategies.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/AggregateStrategies.java
@@ -47,6 +47,7 @@ import 
org.apache.doris.nereids.trees.expressions.SlotReference;
 import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
 import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateParam;
+import org.apache.doris.nereids.trees.expressions.functions.agg.AggregatePhase;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
 import org.apache.doris.nereids.trees.expressions.functions.agg.GroupConcat;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Max;
@@ -294,31 +295,37 @@ public class AggregateStrategies implements 
ImplementationRuleFactory {
             RuleType.ONE_PHASE_AGGREGATE_WITHOUT_DISTINCT.build(
                 basePattern
                     .when(agg -> agg.getDistinctArguments().isEmpty())
+                    .when(agg -> agg.supportAggregatePhase(AggregatePhase.ONE))
                     .thenApplyMulti(ctx -> 
onePhaseAggregateWithoutDistinct(ctx.root, ctx.connectContext))
             ),
             RuleType.TWO_PHASE_AGGREGATE_WITHOUT_DISTINCT.build(
                 basePattern
                     .when(agg -> agg.getDistinctArguments().isEmpty())
+                    .when(agg -> agg.supportAggregatePhase(AggregatePhase.TWO))
                     .thenApplyMulti(ctx -> 
twoPhaseAggregateWithoutDistinct(ctx.root, ctx.connectContext))
             ),
             // RuleType.TWO_PHASE_AGGREGATE_WITH_COUNT_DISTINCT_MULTI.build(
             //     basePattern
             //         .when(this::containsCountDistinctMultiExpr)
+            //         .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.TWO))
             //         .thenApplyMulti(ctx -> 
twoPhaseAggregateWithCountDistinctMulti(ctx.root, ctx.cascadesContext))
             // ),
             RuleType.THREE_PHASE_AGGREGATE_WITH_COUNT_DISTINCT_MULTI.build(
                 basePattern
                     .when(this::containsCountDistinctMultiExpr)
+                    .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.THREE))
                     .thenApplyMulti(ctx -> 
threePhaseAggregateWithCountDistinctMulti(ctx.root, ctx.cascadesContext))
             ),
             RuleType.ONE_PHASE_AGGREGATE_SINGLE_DISTINCT_TO_MULTI.build(
                 basePattern
                     .when(agg -> agg.getDistinctArguments().size() == 1 && 
couldConvertToMulti(agg))
+                    .when(agg -> agg.supportAggregatePhase(AggregatePhase.ONE))
                     .thenApplyMulti(ctx -> 
onePhaseAggregateWithMultiDistinct(ctx.root, ctx.connectContext))
             ),
             RuleType.TWO_PHASE_AGGREGATE_SINGLE_DISTINCT_TO_MULTI.build(
                 basePattern
                     .when(agg -> agg.getDistinctArguments().size() == 1 && 
couldConvertToMulti(agg))
+                    .when(agg -> agg.supportAggregatePhase(AggregatePhase.TWO))
                     .thenApplyMulti(ctx -> 
twoPhaseAggregateWithMultiDistinct(ctx.root, ctx.connectContext))
             ),
             RuleType.TWO_PHASE_AGGREGATE_WITH_MULTI_DISTINCT.build(
@@ -326,17 +333,20 @@ public class AggregateStrategies implements 
ImplementationRuleFactory {
                     .when(agg -> agg.getDistinctArguments().size() > 1
                             && !containsCountDistinctMultiExpr(agg)
                             && couldConvertToMulti(agg))
+                    .when(agg -> agg.supportAggregatePhase(AggregatePhase.TWO))
                     .thenApplyMulti(ctx -> 
twoPhaseAggregateWithMultiDistinct(ctx.root, ctx.connectContext))
             ),
             // RuleType.TWO_PHASE_AGGREGATE_WITH_DISTINCT.build(
             //     basePattern
             //         .when(agg -> agg.getDistinctArguments().size() == 1)
+            //         .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.TWO))
             //         .thenApplyMulti(ctx -> 
twoPhaseAggregateWithDistinct(ctx.root, ctx.connectContext))
             // ),
             RuleType.THREE_PHASE_AGGREGATE_WITH_DISTINCT.build(
                 basePattern
                     .when(agg -> agg.getDistinctArguments().size() == 1)
-                     .whenNot(agg -> agg.mustUseMultiDistinctAgg())
+                    .whenNot(agg -> agg.mustUseMultiDistinctAgg())
+                    .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.THREE))
                     .thenApplyMulti(ctx -> 
threePhaseAggregateWithDistinct(ctx.root, ctx.connectContext))
             ),
             /*
@@ -361,6 +371,7 @@ public class AggregateStrategies implements 
ImplementationRuleFactory {
                     .when(agg -> agg.getDistinctArguments().size() == 1)
                     .when(agg -> agg.getGroupByExpressions().isEmpty())
                     .whenNot(agg -> agg.mustUseMultiDistinctAgg())
+                    .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.FOUR))
                     .thenApplyMulti(ctx -> {
                         Function<List<Expression>, RequireProperties> 
secondPhaseRequireDistinctHash =
                                 groupByAndDistinct -> RequireProperties.of(
@@ -408,6 +419,7 @@ public class AggregateStrategies implements 
ImplementationRuleFactory {
                         }
                         return couldConvertToMulti(agg);
                     })
+                    .when(agg -> 
agg.supportAggregatePhase(AggregatePhase.FOUR))
                     .thenApplyMulti(ctx -> {
                         Function<List<Expression>, RequireProperties> 
secondPhaseRequireGroupByAndDistinctHash =
                                 groupByAndDistinct -> RequireProperties.of(
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
index 6b12f9cd642..8fda4d4b020 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
@@ -17,9 +17,6 @@
 
 package org.apache.doris.nereids.trees.expressions.functions;
 
-import org.apache.doris.nereids.exceptions.AnalysisException;
-import org.apache.doris.nereids.trees.expressions.Expression;
-
 /**
  * nullable is always false.
  *
@@ -30,10 +27,4 @@ public interface AlwaysNotNullable extends ComputeNullable {
     default boolean nullable() {
         return false;
     }
-
-    // return value of this function if the input data is empty.
-    // for example, count(*) of empty table is 0;
-    default Expression resultForEmptyInput() {
-        throw new AnalysisException("should implement resultForEmptyInput() 
for " + this.getClass());
-    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregateFunction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregateFunction.java
index 58b9d0274dd..90df2f531da 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregateFunction.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregateFunction.java
@@ -131,6 +131,10 @@ public abstract class AggregateFunction extends 
BoundFunction implements Expects
         return getName() + "(" + (distinct ? "DISTINCT " : "") + args + ")";
     }
 
+    public boolean supportAggregatePhase(AggregatePhase aggregatePhase) {
+        return true;
+    }
+
     public List<Expression> getDistinctArguments() {
         return distinct ? getArguments() : ImmutableList.of();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregatePhase.java
similarity index 53%
copy from 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregatePhase.java
index 6b12f9cd642..9115e5890ad 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/AggregatePhase.java
@@ -15,25 +15,9 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.nereids.trees.expressions.functions;
+package org.apache.doris.nereids.trees.expressions.functions.agg;
 
-import org.apache.doris.nereids.exceptions.AnalysisException;
-import org.apache.doris.nereids.trees.expressions.Expression;
-
-/**
- * nullable is always false.
- *
- * e.g. `count(*)`, the output column is always not nullable
- */
-public interface AlwaysNotNullable extends ComputeNullable {
-    @Override
-    default boolean nullable() {
-        return false;
-    }
-
-    // return value of this function if the input data is empty.
-    // for example, count(*) of empty table is 0;
-    default Expression resultForEmptyInput() {
-        throw new AnalysisException("should implement resultForEmptyInput() 
for " + this.getClass());
-    }
+/** AggregatePhase */
+public enum AggregatePhase {
+    ONE, TWO, THREE, FOUR
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ArrayAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ArrayAgg.java
index bc91207e31f..6218569261a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ArrayAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/ArrayAgg.java
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'array_agg'.
  */
-public class ArrayAgg extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class ArrayAgg extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
     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/BitmapAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/BitmapAgg.java
index eaf766b908d..a0eaf88efaf 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'bitmap_agg'.
  */
-public class BitmapAgg extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class BitmapAgg extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
     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 1b7d2d3c3cd..80a9887d325 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -35,8 +34,8 @@ import java.util.List;
 /**
  * AggregateFunction 'bitmap_intersect'. This class is generated by 
GenerateFunction.
  */
-public class BitmapIntersect extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, BitmapFunction {
+public class BitmapIntersect extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction {
 
     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 cd0756a1c93..fce2f4fa70c 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
@@ -36,8 +35,8 @@ import java.util.List;
 /**
  * AggregateFunction 'bitmap_union'. This class is generated by 
GenerateFunction.
  */
-public class BitmapUnion extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, BitmapFunction, RollUpTrait {
+public class BitmapUnion extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait {
 
     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 593c814f22d..d1e2d6010a2 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'bitmap_union_count'. This class is generated by 
GenerateFunction.
  */
-public class BitmapUnionCount extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, BitmapFunction, RollUpTrait {
+public class BitmapUnionCount extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
BitmapFunction, RollUpTrait {
 
     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 2efe1631176..af569982c4e 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
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -41,8 +40,8 @@ import java.util.List;
 /**
  * AggregateFunction 'bitmap_union_int'. This class is generated by 
GenerateFunction.
  */
-public class BitmapUnionInt extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class BitmapUnionInt extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     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/CollectList.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CollectList.java
index d6cca2d0b90..ed0dd240621 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -38,8 +37,8 @@ import java.util.List;
 /**
  * AggregateFunction 'collect_list'. This class is generated by 
GenerateFunction.
  */
-public class CollectList extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class CollectList extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     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 d9e7e7227c6..2aba485fc7d 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -38,8 +37,8 @@ import java.util.List;
 /**
  * AggregateFunction 'collect_set'. This class is generated by 
GenerateFunction.
  */
-public class CollectSet extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class CollectSet extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     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/Count.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Count.java
index 10874d47ee3..e86e90974da 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
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import 
org.apache.doris.nereids.trees.expressions.functions.window.SupportWindowAnalytic;
@@ -37,8 +36,8 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** count agg function. */
-public class Count extends AggregateFunction
-        implements ExplicitlyCastableSignature, AlwaysNotNullable, 
SupportWindowAnalytic, RollUpTrait {
+public class Count extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature, SupportWindowAnalytic, 
RollUpTrait {
 
     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/CountByEnum.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CountByEnum.java
index 2a4ee7be3f4..f956854d687 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CountByEnum.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/CountByEnum.java
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@@ -31,7 +30,7 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** count_by_enum agg function. */
-public class CountByEnum extends AggregateFunction implements 
ExplicitlyCastableSignature, AlwaysNotNullable {
+public class CountByEnum extends NotNullableAggregateFunction implements 
ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(StringType.INSTANCE).varArgs(StringType.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 0720d6838bb..1cc0db1bd5e 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -36,8 +35,8 @@ import java.util.List;
 /**
  * AggregateFunction 'group_array_intersect'.
  */
-public class GroupArrayIntersect extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class GroupArrayIntersect extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     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/Histogram.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Histogram.java
index 6b0a2759823..827c57facd7 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.SearchSignature;
 import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'histogram'. This class is generated by GenerateFunction.
  */
-public class Histogram extends AggregateFunction
-        implements ExplicitlyCastableSignature, AlwaysNotNullable {
+public class Histogram extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature {
 
     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 b81fad270b0..8f6224f66b0 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HllEmpty;
@@ -36,8 +35,8 @@ import java.util.List;
 /**
  * AggregateFunction 'hll_union'. This class is generated by GenerateFunction.
  */
-public class HllUnion extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, HllFunction, RollUpTrait {
+public class HllUnion extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait {
 
     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 b14b61b5be0..b2c15b402aa 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'hll_union_agg'. This class is generated by 
GenerateFunction.
  */
-public class HllUnionAgg extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, HllFunction, RollUpTrait {
+public class HllUnionAgg extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, HllFunction, 
RollUpTrait {
 
     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 c013b2e8b4c..3eed9b9a6e4 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.BitmapIntersectFunction;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
@@ -37,8 +36,8 @@ import java.util.List;
 /**
  * AggregateFunction 'intersect_count'. This class is generated by 
GenerateFunction.
  */
-public class IntersectCount extends AggregateFunction
-        implements ExplicitlyCastableSignature, AlwaysNotNullable, 
BitmapIntersectFunction {
+public class IntersectCount extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature, BitmapIntersectFunction {
 
     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/MapAgg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MapAgg.java
index 744d4a23a66..798b3677ff1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MapAgg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MapAgg.java
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.MapLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
@@ -36,8 +35,8 @@ import java.util.List;
 /**
  * AggregateFunction 'map_agg'. This class is generated by GenerateFunction.
  */
-public class MapAgg extends AggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class MapAgg extends NotNullableAggregateFunction
+        implements BinaryExpression, ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(MapType.of(new FollowToAnyDataType(0), new 
FollowToAnyDataType(1)))
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 68d31e3e7bd..81768ef48dd 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
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.analyzer.Unbound;
 import org.apache.doris.nereids.trees.expressions.Cast;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@@ -36,8 +35,8 @@ import com.google.common.collect.ImmutableList;
 import java.util.List;
 
 /** MultiDistinctCount */
-public class MultiDistinctCount extends AggregateFunction
-        implements AlwaysNotNullable, ExplicitlyCastableSignature, 
MultiDistinction {
+public class MultiDistinctCount extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature, MultiDistinction {
     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/MultiDistinctSum0.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctSum0.java
index 2b0eda06b42..abd5292e31a 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
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ComputePrecisionForSum;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
@@ -39,8 +38,8 @@ import java.math.BigInteger;
 import java.util.List;
 
 /** MultiDistinctSum0 */
-public class MultiDistinctSum0 extends AggregateFunction implements 
UnaryExpression,
-        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction, 
AlwaysNotNullable {
+public class MultiDistinctSum0 extends NotNullableAggregateFunction implements 
UnaryExpression,
+        ExplicitlyCastableSignature, ComputePrecisionForSum, MultiDistinction {
 
     private final boolean mustUseMultiDistinctAgg;
 
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 ea90bc58791..c2a04b4fd99 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
@@ -21,7 +21,6 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
@@ -38,8 +37,8 @@ import java.util.List;
 /**
  * AggregateFunction 'ndv'. This class is generated by GenserateFunction.
  */
-public class Ndv extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable, RollUpTrait {
+public class Ndv extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, RollUpTrait {
 
     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/AlwaysNotNullable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NotNullableAggregateFunction.java
similarity index 51%
copy from 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NotNullableAggregateFunction.java
index 6b12f9cd642..f38decf439c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AlwaysNotNullable.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/NotNullableAggregateFunction.java
@@ -15,25 +15,34 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.nereids.trees.expressions.functions;
+package org.apache.doris.nereids.trees.expressions.functions.agg;
 
-import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
+
+import java.util.List;
 
 /**
- * nullable is always false.
- *
- * e.g. `count(*)`, the output column is always not nullable
+ * base class for AlwaysNotNullable aggregate function
  */
-public interface AlwaysNotNullable extends ComputeNullable {
-    @Override
-    default boolean nullable() {
-        return false;
+public abstract class NotNullableAggregateFunction extends AggregateFunction 
implements AlwaysNotNullable {
+    protected NotNullableAggregateFunction(String name, Expression 
...expressions) {
+        super(name, false, expressions);
+    }
+
+    protected NotNullableAggregateFunction(String name, List<Expression> 
expressions) {
+        super(name, false, expressions);
+    }
+
+    protected NotNullableAggregateFunction(String name, boolean distinct, 
Expression ...expressions) {
+        super(name, distinct, expressions);
+    }
+
+    protected NotNullableAggregateFunction(String name, boolean distinct, 
List<Expression> expressions) {
+        super(name, distinct, expressions);
     }
 
     // return value of this function if the input data is empty.
     // for example, count(*) of empty table is 0;
-    default Expression resultForEmptyInput() {
-        throw new AnalysisException("should implement resultForEmptyInput() 
for " + this.getClass());
-    }
+    public abstract Expression resultForEmptyInput();
 }
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
new file mode 100644
index 00000000000..4a91e520055
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculate.java
@@ -0,0 +1,84 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.agg;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.BitmapType;
+import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.coercion.CharacterType;
+import org.apache.doris.nereids.util.ExpressionUtils;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/** OrthogonalBitmapExprCalculate */
+public class OrthogonalBitmapExprCalculate extends NotNullableAggregateFunction
+        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature {
+
+    static final List<FunctionSignature> FUNCTION_SIGNATURES = 
ImmutableList.of(
+            FunctionSignature.ret(BitmapType.INSTANCE)
+                    .varArgs(BitmapType.INSTANCE, VarcharType.SYSTEM_DEFAULT, 
VarcharType.SYSTEM_DEFAULT)
+    );
+
+    /**
+     * constructor with 3 arguments.
+     */
+    public OrthogonalBitmapExprCalculate(
+            Expression bitmap, Expression filterColumn, VarcharLiteral 
inputString) {
+        super("orthogonal_bitmap_expr_calculate", 
ExpressionUtils.mergeArguments(bitmap, filterColumn, inputString));
+    }
+
+    /**
+     * constructor with 3 arguments.
+     */
+    public OrthogonalBitmapExprCalculate(boolean distinct,
+            Expression bitmap, Expression filterColumn, VarcharLiteral 
inputString) {
+        super("orthogonal_bitmap_expr_calculate", distinct,
+                ExpressionUtils.mergeArguments(bitmap, filterColumn, 
inputString));
+    }
+
+    @Override
+    public boolean supportAggregatePhase(AggregatePhase aggregatePhase) {
+        return aggregatePhase == AggregatePhase.TWO;
+    }
+
+    @Override
+    public OrthogonalBitmapExprCalculate withDistinctAndChildren(boolean 
distinct, List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 3
+                && children.get(2).getDataType() instanceof CharacterType
+                && children.get(2).getDataType() instanceof VarcharType);
+        return new OrthogonalBitmapExprCalculate(
+                distinct, children.get(0), children.get(1), (VarcharLiteral) 
children.get(2));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return FUNCTION_SIGNATURES;
+    }
+
+    @Override
+    public Expression resultForEmptyInput() {
+        return new BitmapEmpty();
+    }
+}
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
new file mode 100644
index 00000000000..3100cc9ae80
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/OrthogonalBitmapExprCalculateCount.java
@@ -0,0 +1,86 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.agg;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.BigIntType;
+import org.apache.doris.nereids.types.BitmapType;
+import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.coercion.CharacterType;
+import org.apache.doris.nereids.util.ExpressionUtils;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/** OrthogonalBitmapExprCalculateCount */
+public class OrthogonalBitmapExprCalculateCount extends 
NotNullableAggregateFunction
+        implements OrthogonalBitmapFunction, ExplicitlyCastableSignature {
+
+    static final List<FunctionSignature> FUNCTION_SIGNATURES = 
ImmutableList.of(
+            FunctionSignature.ret(BigIntType.INSTANCE)
+                    .varArgs(BitmapType.INSTANCE, VarcharType.SYSTEM_DEFAULT, 
VarcharType.SYSTEM_DEFAULT)
+    );
+
+    /**
+     * constructor with 3 arguments.
+     */
+    public OrthogonalBitmapExprCalculateCount(
+            Expression bitmap, Expression filterColumn, VarcharLiteral 
inputString) {
+        super("orthogonal_bitmap_expr_calculate_count",
+                ExpressionUtils.mergeArguments(bitmap, filterColumn, 
inputString));
+    }
+
+    /**
+     * constructor with 3 arguments.
+     */
+    public OrthogonalBitmapExprCalculateCount(boolean distinct,
+            Expression bitmap, Expression filterColumn, VarcharLiteral 
inputString) {
+        super("orthogonal_bitmap_expr_calculate_count", distinct,
+                ExpressionUtils.mergeArguments(bitmap, filterColumn, 
inputString));
+    }
+
+    @Override
+    public boolean supportAggregatePhase(AggregatePhase aggregatePhase) {
+        return aggregatePhase == AggregatePhase.TWO;
+    }
+
+    @Override
+    public OrthogonalBitmapExprCalculateCount withDistinctAndChildren(boolean 
distinct, List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 3
+                && children.get(2).getDataType() instanceof CharacterType
+                && children.get(2).getDataType() instanceof VarcharType);
+        return new OrthogonalBitmapExprCalculateCount(
+                distinct, children.get(0), children.get(1), (VarcharLiteral) 
children.get(2));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return FUNCTION_SIGNATURES;
+    }
+
+    @Override
+    public Expression resultForEmptyInput() {
+        return new BitmapEmpty();
+    }
+}
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 956f585f0a1..7837ea1bec7 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
@@ -19,8 +19,8 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.BitmapIntersectFunction;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapEmpty;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BitmapType;
 import org.apache.doris.nereids.util.ExpressionUtils;
@@ -33,8 +33,8 @@ import java.util.List;
 /**
  * AggregateFunction 'orthogonal_bitmap_intersect'. This class is generated by 
GenerateFunction.
  */
-public class OrthogonalBitmapIntersect extends AggregateFunction
-        implements AlwaysNotNullable, OrthogonalBitmapFunction, 
BitmapIntersectFunction {
+public class OrthogonalBitmapIntersect extends NotNullableAggregateFunction
+        implements OrthogonalBitmapFunction, BitmapIntersectFunction {
 
     static final List<FunctionSignature> FUNCTION_SIGNATURES = 
SUPPORTED_TYPES.stream()
             .map(type -> 
FunctionSignature.ret(BitmapType.INSTANCE).varArgs(BitmapType.INSTANCE, type, 
type))
@@ -75,4 +75,9 @@ public class OrthogonalBitmapIntersect extends 
AggregateFunction
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitOrthogonalBitmapIntersect(this, context);
     }
+
+    @Override
+    public Expression resultForEmptyInput() {
+        return new BitmapEmpty();
+    }
 }
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 82bfa911c26..fd282341249 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
@@ -18,8 +18,8 @@
 package org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.BitmapIntersectFunction;
+import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.util.ExpressionUtils;
 
@@ -30,8 +30,8 @@ import java.util.List;
 /**
  * AggregateFunction 'orthogonal_bitmap_intersect_count'. This class is 
generated by GenerateFunction.
  */
-public class OrthogonalBitmapIntersectCount extends AggregateFunction
-        implements AlwaysNotNullable, OrthogonalBitmapFunction, 
BitmapIntersectFunction {
+public class OrthogonalBitmapIntersectCount extends 
NotNullableAggregateFunction
+        implements OrthogonalBitmapFunction, BitmapIntersectFunction {
 
     /**
      * constructor with 3 or more arguments.
@@ -44,7 +44,7 @@ public class OrthogonalBitmapIntersectCount extends 
AggregateFunction
      * constructor with 3 or more arguments.
      */
     public OrthogonalBitmapIntersectCount(boolean distinct, Expression arg0, 
Expression arg1,
-            Expression arg2, Expression... varArgs) {
+                                          Expression arg2, Expression... 
varArgs) {
         super("orthogonal_bitmap_intersect_count", distinct,
                 ExpressionUtils.mergeArguments(arg0, arg1, arg2, varArgs));
     }
@@ -63,4 +63,9 @@ public class OrthogonalBitmapIntersectCount extends 
AggregateFunction
     public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
         return visitor.visitOrthogonalBitmapIntersectCount(this, context);
     }
+
+    @Override
+    public Expression resultForEmptyInput() {
+        return new BigIntLiteral(0);
+    }
 }
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 c08bb08aeec..081e5d7f6c4 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
@@ -19,8 +19,8 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.types.BigIntType;
@@ -34,8 +34,8 @@ import java.util.List;
 /**
  * AggregateFunction 'orthogonal_bitmap_union_count'. This class is generated 
by GenerateFunction.
  */
-public class OrthogonalBitmapUnionCount extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class OrthogonalBitmapUnionCount extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             
FunctionSignature.ret(BigIntType.INSTANCE).args(BitmapType.INSTANCE)
@@ -73,4 +73,9 @@ public class OrthogonalBitmapUnionCount extends 
AggregateFunction
     public List<FunctionSignature> getSignatures() {
         return SIGNATURES;
     }
+
+    @Override
+    public Expression resultForEmptyInput() {
+        return new BigIntLiteral(0);
+    }
 }
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 b4d7467e4c0..4412d96006f 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
 import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
@@ -41,8 +40,8 @@ import java.util.List;
 /**
  * AggregateFunction 'percentile_array'. This class is generated by 
GenerateFunction.
  */
-public class PercentileArray extends AggregateFunction
-        implements BinaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class PercentileArray extends NotNullableAggregateFunction
+        implements BinaryExpression, ExplicitlyCastableSignature {
 
     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/QuantileUnion.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/QuantileUnion.java
index 3d0729775a5..3d107ec282b 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
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.QuantileStateEmpty;
 import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
@@ -36,8 +35,8 @@ import java.util.List;
 /**
  * AggregateFunction 'quantile_union'. This class is generated by 
GenerateFunction.
  */
-public class QuantileUnion extends AggregateFunction
-        implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNotNullable {
+public class QuantileUnion extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature {
 
     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/SequenceCount.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/SequenceCount.java
index 7af112ef8e8..5ac114f00e8 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
@@ -19,7 +19,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@@ -39,8 +38,8 @@ import java.util.List;
 /**
  * AggregateFunction 'sequence_count'. This class is generated by 
GenerateFunction.
  */
-public class SequenceCount extends AggregateFunction
-        implements ExplicitlyCastableSignature, AlwaysNotNullable, 
SequenceFunction {
+public class SequenceCount extends NotNullableAggregateFunction
+        implements ExplicitlyCastableSignature, SequenceFunction {
 
     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/Sum0.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Sum0.java
index fd052a69c0e..5a1f0f9fb93 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
@@ -20,7 +20,6 @@ package 
org.apache.doris.nereids.trees.expressions.functions.agg;
 import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ComputePrecisionForSum;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Function;
@@ -53,8 +52,8 @@ import java.util.List;
  * AggregateFunction 'sum0'. sum0 returns the sum of the values which go into 
it like sum.
  * It differs in that when no non null values are applied zero is returned 
instead of null.
  */
-public class Sum0 extends AggregateFunction
-        implements UnaryExpression, AlwaysNotNullable, 
ExplicitlyCastableSignature, ComputePrecisionForSum,
+public class Sum0 extends NotNullableAggregateFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
ComputePrecisionForSum,
         SupportWindowAnalytic, RollUpTrait {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
index 9f65988da95..a925fe59f32 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
@@ -24,6 +24,8 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait;
+import 
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
+import org.apache.doris.nereids.trees.expressions.functions.agg.AggregatePhase;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
 import org.apache.doris.nereids.trees.expressions.functions.agg.Ndv;
 import org.apache.doris.nereids.trees.plans.Plan;
@@ -382,4 +384,14 @@ public class LogicalAggregate<CHILD_TYPE extends Plan>
     public void computeFd(DataTrait.Builder builder) {
         builder.addFuncDepsDG(child().getLogicalProperties().getTrait());
     }
+
+    /** supportAggregatePhase */
+    public boolean supportAggregatePhase(AggregatePhase aggregatePhase) {
+        for (AggregateFunction aggregateFunction : getAggregateFunctions()) {
+            if (!aggregateFunction.supportAggregatePhase(aggregatePhase)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git 
a/regression-test/suites/nereids_function_p0/agg_function/test_orthogonal_bitmap_expr_calculate.groovy
 
b/regression-test/suites/nereids_function_p0/agg_function/test_orthogonal_bitmap_expr_calculate.groovy
new file mode 100644
index 00000000000..b47315e96db
--- /dev/null
+++ 
b/regression-test/suites/nereids_function_p0/agg_function/test_orthogonal_bitmap_expr_calculate.groovy
@@ -0,0 +1,55 @@
+// 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("test_orthogonal_bitmap_expr_calculate") {
+    multi_sql """
+            drop table if exists test_orthogonal_bitmap_expr_calculate;
+
+            create table test_orthogonal_bitmap_expr_calculate(
+                id int,
+                tag int,
+                user_id bitmap bitmap_union
+            )
+            aggregate key(id, tag)
+            distributed by hash(id) buckets 1
+            properties(
+                'replication_num'='1'
+            );
+            
+            insert into test_orthogonal_bitmap_expr_calculate values
+            (1, 100, bitmap_from_string('1,2,3,4,5')),
+            (1, 200, bitmap_from_string('3,4,5,6,7'));
+
+            set enable_fallback_to_original_planner=false;
+            """
+
+    test {
+        sql """
+            select bitmap_to_string(orthogonal_bitmap_expr_calculate(user_id, 
tag, '(100&200)'))
+            from test_orthogonal_bitmap_expr_calculate
+            """
+        result([['3,4,5']])
+    }
+
+    test {
+        sql """
+            select orthogonal_bitmap_expr_calculate_count(user_id, tag, 
'(100&200)')
+            from test_orthogonal_bitmap_expr_calculate
+            """
+        result([[3L]])
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to