This is an automated email from the ASF dual-hosted git repository.
morrySnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new acd7e31685e [fix](rbo) Preserve nullability in distinct window
rewrites (#67666)
acd7e31685e is described below
commit acd7e31685e9160395224f35c823373cb10436d8
Author: morrySnow <[email protected]>
AuthorDate: Wed Sep 9 15:45:58 2026 +0800
[fix](rbo) Preserve nullability in distinct window rewrites (#67666)
### What problem does this PR solve?
Problem Summary:
DISTINCT window rewrites for SUM and GROUP_CONCAT manually reconstructed
their multi-distinct functions with the default non-nullable flag. For
empty window frames over NOT NULL inputs, the backend consequently
materialized empty aggregate states (0 or an empty string) instead of
NULL.
This change reuses each aggregate function's canonical multi-distinct
conversion, preserving the always-nullable contract established during
window-function analysis. COUNT(DISTINCT) behavior remains unchanged.
### Release note
Fix SUM(DISTINCT ...) and GROUP_CONCAT(DISTINCT ...) window functions to
return NULL for empty frames.
---
.../rules/rewrite/DistinctWindowExpression.java | 6 ++--
.../multi_distinct/multi_distinct_window.out | 8 +++++
.../multi_distinct/multi_distinct_window.groovy | 38 ++++++++++++++++++++++
3 files changed, 48 insertions(+), 4 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/DistinctWindowExpression.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/DistinctWindowExpression.java
index fd75e5382fc..28df6bbad64 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/DistinctWindowExpression.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/DistinctWindowExpression.java
@@ -27,8 +27,6 @@ import
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunctio
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.MultiDistinctCount;
-import
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctGroupConcat;
-import
org.apache.doris.nereids.trees.expressions.functions.agg.MultiDistinctSum;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalWindow;
@@ -92,9 +90,9 @@ public class DistinctWindowExpression extends
OneRewriteRuleFactory {
}
return Optional.of(new MultiDistinctCount(false,
func.child(0)));
} else if (func instanceof Sum) {
- return Optional.of(new MultiDistinctSum(false, ((Sum)
func).child()));
+ return Optional.of(((Sum) func).convertToMultiDistinct());
} else if (func instanceof GroupConcat) {
- return Optional.of(new MultiDistinctGroupConcat(false,
func.children()));
+ return Optional.of(((GroupConcat)
func).convertToMultiDistinct());
}
}
return Optional.empty();
diff --git
a/regression-test/data/query_p0/multi_distinct/multi_distinct_window.out
b/regression-test/data/query_p0/multi_distinct/multi_distinct_window.out
index f742696436a..57e864865f6 100644
--- a/regression-test/data/query_p0/multi_distinct/multi_distinct_window.out
+++ b/regression-test/data/query_p0/multi_distinct/multi_distinct_window.out
@@ -29,3 +29,11 @@
2 2 a
3 2 a
+-- !sum_empty_frame --
+1 \N \N 0
+2 10 10 1
+
+-- !group_concat_empty_frame --
+1 \N \N
+2 a a
+
diff --git
a/regression-test/suites/query_p0/multi_distinct/multi_distinct_window.groovy
b/regression-test/suites/query_p0/multi_distinct/multi_distinct_window.groovy
index a91cc74ef32..78fce086587 100644
---
a/regression-test/suites/query_p0/multi_distinct/multi_distinct_window.groovy
+++
b/regression-test/suites/query_p0/multi_distinct/multi_distinct_window.groovy
@@ -32,6 +32,22 @@ suite('multi_distinct_window') {
insert into multi values (1, 2, 'a'),(1, 2, 'a'), (2, 2, 'a'), (3, 2, 'a');
"""
+ sql """
+ drop table if exists multi_not_null;
+ CREATE TABLE multi_not_null (
+ id int NOT NULL,
+ v1 int NOT NULL,
+ v2 varchar NOT NULL
+ ) ENGINE = OLAP
+ DUPLICATE KEY(id) COMMENT 'OLAP'
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+
+ insert into multi_not_null values (1, 10, 'a'), (2, 20, 'b');
+ """
+
qt_count "select id, count(distinct v1) over() from multi order by id;"
qt_count_partition "select id, v1, count(distinct v1) over(partition by
id) from multi order by id;"
@@ -42,6 +58,28 @@ suite('multi_distinct_window') {
qt_distinct_group_concat "select id, v1, group_concat(distinct v2) over()
from multi order by id;"
+ qt_sum_empty_frame """
+ select id,
+ sum(distinct v1) over (
+ order by id rows between 1 preceding and 1 preceding),
+ multi_distinct_sum(v1) over (
+ order by id rows between 1 preceding and 1 preceding),
+ count(distinct v1) over (
+ order by id rows between 1 preceding and 1 preceding)
+ from multi_not_null
+ order by id;
+ """
+
+ qt_group_concat_empty_frame """
+ select id,
+ group_concat(distinct v2) over (
+ order by id rows between 1 preceding and 1 preceding),
+ multi_distinct_group_concat(v2) over (
+ order by id rows between 1 preceding and 1 preceding)
+ from multi_not_null
+ order by id;
+ """
+
test {
sql """select id, count(distinct v1, v2) over() from multi order by
id;"""
exception "COUNT with DISTINCT only support 1 parameter in analytic
function"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]