From 8265f6a5849c03128207a485a6d4ef177331bf2a Mon Sep 17 00:00:00 2001 From: shihao zhong 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)