From 8265f6a5849c03128207a485a6d4ef177331bf2a Mon Sep 17 00:00:00 2001
From: shihao zhong <zhong950419@gmail.com>
Date: Mon, 12 Oct 2026 03:10:36 -0400
Subject: [PATCH v1 2/2] Test eager aggregation with a volatile join clause.

Check that no partial aggregate is placed below a join with a volatile
clause, and that the clause runs once per joined row.
---
 src/test/regress/expected/eager_aggregate.out | 49 +++++++++++++++++++
 src/test/regress/sql/eager_aggregate.sql      | 28 +++++++++++
 2 files changed, 77 insertions(+)

diff --git a/src/test/regress/expected/eager_aggregate.out b/src/test/regress/expected/eager_aggregate.out
index b420a125e1c..3ffc2751a86 100644
--- a/src/test/regress/expected/eager_aggregate.out
+++ b/src/test/regress/expected/eager_aggregate.out
@@ -2111,3 +2111,52 @@ GROUP BY t1.x ORDER BY t1.x;
 RESET geqo;
 RESET geqo_threshold;
 DROP TABLE eager_agg_tab_ml;
+--
+-- Test that a volatile clause above the aggregate prevents eager aggregation
+--
+CREATE TABLE eager_agg_vf (k int, c int);
+CREATE TABLE eager_agg_vd (k int, g int);
+INSERT INTO eager_agg_vf SELECT i % 10, 1 FROM generate_series(1, 2000) i;
+INSERT INTO eager_agg_vd SELECT i % 10, i % 3 FROM generate_series(1, 30) i;
+ANALYZE eager_agg_vf;
+ANALYZE eager_agg_vd;
+CREATE SEQUENCE eager_agg_vseq;
+EXPLAIN (COSTS OFF)
+SELECT d.g, sum(f.c)
+  FROM eager_agg_vf f
+  JOIN eager_agg_vd d ON f.k = d.k AND nextval('eager_agg_vseq') > 0
+GROUP BY d.g ORDER BY d.g;
+                              QUERY PLAN                              
+----------------------------------------------------------------------
+ Sort
+   Sort Key: d.g
+   ->  HashAggregate
+         Group Key: d.g
+         ->  Hash Join
+               Hash Cond: (f.k = d.k)
+               Join Filter: (nextval('eager_agg_vseq'::regclass) > 0)
+               ->  Seq Scan on eager_agg_vf f
+               ->  Hash
+                     ->  Seq Scan on eager_agg_vd d
+(10 rows)
+
+SELECT d.g, sum(f.c)
+  FROM eager_agg_vf f
+  JOIN eager_agg_vd d ON f.k = d.k AND nextval('eager_agg_vseq') > 0
+GROUP BY d.g ORDER BY d.g;
+ g | sum  
+---+------
+ 0 | 2000
+ 1 | 2000
+ 2 | 2000
+(3 rows)
+
+-- the clause must have been evaluated once per joined row, 6000 in all
+SELECT last_value FROM eager_agg_vseq;
+ last_value 
+------------
+       6000
+(1 row)
+
+DROP SEQUENCE eager_agg_vseq;
+DROP TABLE eager_agg_vf, eager_agg_vd;
diff --git a/src/test/regress/sql/eager_aggregate.sql b/src/test/regress/sql/eager_aggregate.sql
index 7e3623aa6fd..9b1f38464cf 100644
--- a/src/test/regress/sql/eager_aggregate.sql
+++ b/src/test/regress/sql/eager_aggregate.sql
@@ -465,3 +465,31 @@ RESET geqo;
 RESET geqo_threshold;
 
 DROP TABLE eager_agg_tab_ml;
+
+--
+-- Test that a volatile clause above the aggregate prevents eager aggregation
+--
+CREATE TABLE eager_agg_vf (k int, c int);
+CREATE TABLE eager_agg_vd (k int, g int);
+INSERT INTO eager_agg_vf SELECT i % 10, 1 FROM generate_series(1, 2000) i;
+INSERT INTO eager_agg_vd SELECT i % 10, i % 3 FROM generate_series(1, 30) i;
+ANALYZE eager_agg_vf;
+ANALYZE eager_agg_vd;
+CREATE SEQUENCE eager_agg_vseq;
+
+EXPLAIN (COSTS OFF)
+SELECT d.g, sum(f.c)
+  FROM eager_agg_vf f
+  JOIN eager_agg_vd d ON f.k = d.k AND nextval('eager_agg_vseq') > 0
+GROUP BY d.g ORDER BY d.g;
+
+SELECT d.g, sum(f.c)
+  FROM eager_agg_vf f
+  JOIN eager_agg_vd d ON f.k = d.k AND nextval('eager_agg_vseq') > 0
+GROUP BY d.g ORDER BY d.g;
+
+-- the clause must have been evaluated once per joined row, 6000 in all
+SELECT last_value FROM eager_agg_vseq;
+
+DROP SEQUENCE eager_agg_vseq;
+DROP TABLE eager_agg_vf, eager_agg_vd;
-- 
2.37.1 (Apple Git-137.1)

