summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/path/allpaths.c20
-rw-r--r--src/test/regress/expected/partition_aggregate.out31
-rw-r--r--src/test/regress/sql/partition_aggregate.sql5
3 files changed, 49 insertions, 7 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 9c6436eb72f..41233b98373 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1810,9 +1810,11 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
* We generate a path for each ordering (pathkey list) appearing in
* all_child_pathkeys.
*
- * We consider both cheapest-startup and cheapest-total cases, ie, for each
- * interesting ordering, collect all the cheapest startup subpaths and all the
- * cheapest total paths, and build a suitable path for each case.
+ * We consider the cheapest-startup and cheapest-total cases, and also the
+ * cheapest-fractional case when not all tuples need to be retrieved. For each
+ * interesting ordering, we collect all the cheapest startup subpaths, all the
+ * cheapest total paths, and, if applicable, all the cheapest fractional paths,
+ * and build a suitable path for each case.
*
* We don't currently generate any parameterized ordered paths here. While
* it would not take much more code here to do so, it's very unclear that it
@@ -1977,14 +1979,18 @@ 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.
+ * We should not have a dummy child relation here. However,
+ * we cannot use childrel->rows to compute the tuple fraction,
+ * as childrel can be an upper relation with an unset row
+ * estimate. Instead, we use the row estimate from the
+ * cheapest_total path, which should already have been forced
+ * to a sane value.
*/
- Assert(childrel->rows > 0);
+ Assert(cheapest_total->rows > 0);
/* Convert absolute limit to a path fraction */
if (path_fraction >= 1.0)
- path_fraction /= childrel->rows;
+ path_fraction /= cheapest_total->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..c30304b99c7 100644
--- a/src/test/regress/expected/partition_aggregate.out
+++ b/src/test/regress/expected/partition_aggregate.out
@@ -339,6 +339,37 @@ SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1;
2
(3 rows)
+-- Test partitionwise aggregation with ordered append path built from fractional paths
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM pagg_tab GROUP BY c ORDER BY c LIMIT 1;
+ QUERY PLAN
+------------------------------------------------------------
+ Limit
+ -> Merge Append
+ Sort Key: pagg_tab.c
+ -> GroupAggregate
+ Group Key: pagg_tab.c
+ -> Sort
+ Sort Key: pagg_tab.c
+ -> Seq Scan on pagg_tab_p1 pagg_tab
+ -> GroupAggregate
+ Group Key: pagg_tab_1.c
+ -> Sort
+ Sort Key: pagg_tab_1.c
+ -> Seq Scan on pagg_tab_p2 pagg_tab_1
+ -> GroupAggregate
+ Group Key: pagg_tab_2.c
+ -> Sort
+ Sort Key: pagg_tab_2.c
+ -> Seq Scan on pagg_tab_p3 pagg_tab_2
+(18 rows)
+
+SELECT count(*) FROM pagg_tab GROUP BY c ORDER BY c LIMIT 1;
+ count
+-------
+ 250
+(1 row)
+
RESET enable_hashagg;
-- ROLLUP, partitionwise aggregation does not apply
EXPLAIN (COSTS OFF)
diff --git a/src/test/regress/sql/partition_aggregate.sql b/src/test/regress/sql/partition_aggregate.sql
index 124cc260461..7c725e2663a 100644
--- a/src/test/regress/sql/partition_aggregate.sql
+++ b/src/test/regress/sql/partition_aggregate.sql
@@ -76,6 +76,11 @@ EXPLAIN (COSTS OFF)
SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1;
SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1;
+-- Test partitionwise aggregation with ordered append path built from fractional paths
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM pagg_tab GROUP BY c ORDER BY c LIMIT 1;
+SELECT count(*) FROM pagg_tab GROUP BY c ORDER BY c LIMIT 1;
+
RESET enable_hashagg;
-- ROLLUP, partitionwise aggregation does not apply