This is an automated email from the ASF dual-hosted git repository.
924060929 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 6ee32534acd [fix](eager-agg) Fix NPE when pushing MAX below both sides
of join (#65005)
6ee32534acd is described below
commit 6ee32534acd201004b541a6e4b8c17281d653d9c
Author: feiniaofeiafei <[email protected]>
AuthorDate: Wed Jul 1 16:48:58 2026 +0800
[fix](eager-agg) Fix NPE when pushing MAX below both sides of join (#65005)
Related PR: #63690
Problem Summary:
When eager aggregation pushes aggregate operations below both sides of a
Join, the rewritten Join must be processed by
`buildCanonicalJoinProject`.
Previously, this method was invoked only when either child produced a
count slot. For aggregates such as `MAX`, no count slot is required. As
a result, bilateral pushdown could return the rewritten Join directly
without constructing the canonical Join Project.
The missing Project meant that the pushed aggregate output was not
registered in `BilateralState#idToPushedSlot`. Subsequent rewrites
retrieved a null slot from this map and triggered a
`NullPointerException`.
This change invokes `buildCanonicalJoinProject` whenever aggregation is
pushed to both Join children, even when neither side produces a count
slot. It ensures that pushed aggregate outputs are correctly projected
and registered.
A regression case covering bilateral `MAX` pushdown through a RIGHT JOIN
is also added.
### Release note
Fix a NullPointerException when eager aggregation pushes MAX below both
sides of a Join.
---
.../rewrite/eageraggregation/EagerAggRewriter.java | 3 +-
.../query_p0/eager_agg/bilateral_eager_agg.out | 4 ++
.../query_p0/eager_agg/bilateral_eager_agg.groovy | 59 ++++++++++++++++++++--
3 files changed, 62 insertions(+), 4 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
index 18562508fa4..5311cb96383 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
@@ -172,7 +172,8 @@ public class EagerAggRewriter extends
DefaultPlanRewriter<PushDownAggContext> {
LogicalJoin<? extends Plan, ? extends Plan> newJoin = (LogicalJoin<?
extends Plan, ? extends Plan>)
join.withChildren(newLeft, newRight);
- if (leftChildCountSlot.isPresent() || rightChildCountSlot.isPresent())
{
+ if ((leftChildContext.isPresent() && rightChildContext.isPresent())
+ || leftChildCountSlot.isPresent() ||
rightChildCountSlot.isPresent()) {
return buildCanonicalJoinProject(newJoin, context,
leftChildContext, rightChildContext,
leftChildCountSlot, rightChildCountSlot);
}
diff --git a/regression-test/data/query_p0/eager_agg/bilateral_eager_agg.out
b/regression-test/data/query_p0/eager_agg/bilateral_eager_agg.out
index 91d242877c1..a386ad329a1 100644
--- a/regression-test/data/query_p0/eager_agg/bilateral_eager_agg.out
+++ b/regression-test/data/query_p0/eager_agg/bilateral_eager_agg.out
@@ -331,3 +331,7 @@
1 1800 2400
2 900 600
+-- !bilateral_max --
+2000-06-03 true
+2020-01-01 false
+
diff --git
a/regression-test/suites/query_p0/eager_agg/bilateral_eager_agg.groovy
b/regression-test/suites/query_p0/eager_agg/bilateral_eager_agg.groovy
index 07b66767cd7..76c1cc5f1d7 100644
--- a/regression-test/suites/query_p0/eager_agg/bilateral_eager_agg.groovy
+++ b/regression-test/suites/query_p0/eager_agg/bilateral_eager_agg.groovy
@@ -18,6 +18,7 @@
suite("bilateral_eager_agg") {
sql """
+ set fe_debug=true;
drop table if exists t_pdajos_1;
CREATE TABLE `t_pdajos_1` (
`k` int NOT NULL COMMENT "join key",
@@ -894,7 +895,59 @@ suite("bilateral_eager_agg") {
GROUP BY t1.k;
"""
- // Reset session variables to defaults
- sql "SET eager_aggregation_mode = 0;"
- sql "SET force_eager_agg_hint = '';"
+ sql """
+ SET force_eager_agg_hint = '';
+ set eager_aggregation_mode=1;
+ DROP TABLE IF EXISTS bilateral_left;
+ DROP TABLE IF EXISTS bilateral_right;
+
+ CREATE TABLE bilateral_left (
+ filter_date DATE NULL,
+ value_date DATE NULL,
+ flag BOOLEAN NULL
+ )
+ DUPLICATE KEY(filter_date)
+ DISTRIBUTED BY HASH(filter_date) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1"
+ );
+
+ CREATE TABLE bilateral_right (
+ lower_bound BIGINT NULL,
+ upper_bound BIGINT NULL
+ )
+ DUPLICATE KEY(lower_bound)
+ DISTRIBUTED BY HASH(lower_bound) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1"
+ );
+
+ INSERT INTO bilateral_left VALUES
+ ('2018-01-08', '2019-01-01', FALSE),
+ ('2018-01-08', '2020-01-01', FALSE),
+ ('2018-01-08', '2021-01-01', TRUE),
+ ('2018-01-09', '2022-01-01', TRUE);
+
+ INSERT INTO bilateral_right VALUES
+ (1, 2),
+ (2, 2),
+ (3, 2),
+ (NULL, 2);
+ """
+
+ order_qt_bilateral_max """
+ SELECT
+ MAX(
+ CASE
+ WHEN l.flag THEN '2000-06-03'
+ WHEN TRUE THEN l.value_date
+ END
+ ) AS max_date,
+ l.flag AS group_flag
+ FROM bilateral_left l
+ RIGHT JOIN bilateral_right r
+ ON r.lower_bound <= r.upper_bound
+ WHERE l.filter_date = '2018-01-08'
+ GROUP BY group_flag;
+ """
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]