From bb8ecc7e7bac169d0cdc5e4b2bb8a18665b4b936 Mon Sep 17 00:00:00 2001 From: Kuntal Ghosh Date: Mon, 3 Nov 2025 04:45:01 +0000 Subject: [PATCH] Remove incorrect assertion for childrel rows in ordered append paths iThe assertion that childrel->rows > 0 is incorrect when aggregates are pushed down below merge append, as childrel may be an upperrel in such cases. Use clamp_row_est() to safely handle zero or near-zero row estimates when calculating path fractions. --- src/backend/optimizer/path/allpaths.c | 8 +------- .../regress/expected/partition_aggregate.out | 16 ++++++++++++++++ src/test/regress/sql/partition_aggregate.sql | 9 +++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 9c6436eb72f..f9eff4d45c6 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1976,15 +1976,9 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, { double path_fraction = root->tuple_fraction; - /* - * Merge Append considers only live children relations. Dummy - * relations must be filtered out before. - */ - Assert(childrel->rows > 0); - /* Convert absolute limit to a path fraction */ if (path_fraction >= 1.0) - path_fraction /= childrel->rows; + path_fraction /= clamp_row_est(childrel->rows); cheapest_fractional = get_cheapest_fractional_path_for_pathkeys(childrel->pathlist, diff --git a/src/test/regress/expected/partition_aggregate.out b/src/test/regress/expected/partition_aggregate.out index fc84929a002..992d016407f 100644 --- a/src/test/regress/expected/partition_aggregate.out +++ b/src/test/regress/expected/partition_aggregate.out @@ -930,6 +930,22 @@ SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAV 20 | 40 | 50 | 40.0000000000000000 | 5 (6 rows) +-- Test with relation having interesting order +CREATE TABLE pagg_tab3 (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id); +CREATE TABLE pagg_tab3_0 PARTITION OF pagg_tab3 FOR VALUES FROM ('0') TO ('1000'); +CREATE TABLE pagg_tab3_1 PARTITION OF pagg_tab3 FOR VALUES FROM ('1000') TO ('2000'); +SET enable_partitionwise_aggregate = true; +EXPLAIN (COSTS OFF) SELECT count(*) FROM pagg_tab3 x GROUP BY x.id ORDER BY x.id DESC LIMIT 2; + QUERY PLAN +-------------------------------------------------------------------------------------- + Limit + -> GroupAggregate + Group Key: x.id + -> Append + -> Index Only Scan Backward using pagg_tab3_1_pkey on pagg_tab3_1 x_2 + -> Index Only Scan Backward using pagg_tab3_0_pkey on pagg_tab3_0 x_1 +(6 rows) + -- Test with multi-level partitioning scheme CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE(a); CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12); diff --git a/src/test/regress/sql/partition_aggregate.sql b/src/test/regress/sql/partition_aggregate.sql index 124cc260461..31030c9b76f 100644 --- a/src/test/regress/sql/partition_aggregate.sql +++ b/src/test/regress/sql/partition_aggregate.sql @@ -202,6 +202,15 @@ EXPLAIN (COSTS OFF) SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3; SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3; +-- Test with relation having interesting order +CREATE TABLE pagg_tab3 (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id); +CREATE TABLE pagg_tab3_0 PARTITION OF pagg_tab3 FOR VALUES FROM ('0') TO ('1000'); +CREATE TABLE pagg_tab3_1 PARTITION OF pagg_tab3 FOR VALUES FROM ('1000') TO ('2000'); + +SET enable_partitionwise_aggregate = true; + +EXPLAIN (COSTS OFF) SELECT count(*) FROM pagg_tab3 x GROUP BY x.id ORDER BY x.id DESC LIMIT 2; + -- Test with multi-level partitioning scheme -- 2.47.3