v1-0001-generate_useful_gather_paths-shouldn-t-skip-unsor.patch
text/x-patch
Filename: v1-0001-generate_useful_gather_paths-shouldn-t-skip-unsor.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch v1-0001
Subject: generate_useful_gather_paths shouldn't skip unsorted subpaths
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 0 | 8 |
| src/test/regress/expected/incremental_sort.out | 13 | 0 |
| src/test/regress/sql/incremental_sort.sql | 4 | 0 |
From b378e8c2bb76d61da11ce834d55939987ffa1289 Mon Sep 17 00:00:00 2001
From: jcoleman <jtc331@gmail.com>
Date: Fri, 20 Nov 2020 16:19:00 +0000
Subject: [PATCH v1 1/2] generate_useful_gather_paths shouldn't skip unsorted
subpaths
This appears to be a copy/paste thinko from when we added this function.
Here's the issue: the comment claims that we should skip subpaths that
aren't sorted at all since we can't possibly use a gather merge directly
or with an incremental sort applied first. It's true that we can't do
either of those things unless the subpath is already at least partially
sorted. But subsequently we attempt to construct a gather merge path on
top of a full sort (for the cheapest path), and there's no reason to
limit that to partially sorted paths (indeed in the presence of
incremental sort it seems unlikely that that would be the cheapest path).
We still don't want to build incremental sort paths if the subpath has
no pathkeys, but that will imply presorted_keys = 0, which we already
check.
---
src/backend/optimizer/path/allpaths.c | 8 --------
src/test/regress/expected/incremental_sort.out | 13 +++++++++++++
src/test/regress/sql/incremental_sort.sql | 4 ++++
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 84a69b064a..672a20760c 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2914,14 +2914,6 @@ generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_r
Path *subpath = (Path *) lfirst(lc2);
GatherMergePath *path;
- /*
- * If the path has no ordering at all, then we can't use either
- * incremental sort or rely on implicit sorting with a gather
- * merge.
- */
- if (subpath->pathkeys == NIL)
- continue;
-
is_sorted = pathkeys_count_contained_in(useful_pathkeys,
subpath->pathkeys,
&presorted_keys);
diff --git a/src/test/regress/expected/incremental_sort.out b/src/test/regress/expected/incremental_sort.out
index 7cf2eee7c1..51471ae92d 100644
--- a/src/test/regress/expected/incremental_sort.out
+++ b/src/test/regress/expected/incremental_sort.out
@@ -1468,6 +1468,19 @@ explain (costs off) select * from t union select * from t order by 1,3;
-> Parallel Seq Scan on t t_1
(13 rows)
+-- Full sort, not just incremental sort can be pushed below a gather merge path
+-- by generate_useful_gather_paths.
+explain (costs off) select distinct a,b from t;
+ QUERY PLAN
+------------------------------------------
+ Unique
+ -> Gather Merge
+ Workers Planned: 2
+ -> Sort
+ Sort Key: a, b
+ -> Parallel Seq Scan on t
+(6 rows)
+
drop table t;
-- Sort pushdown can't go below where expressions are part of the rel target.
-- In particular this is interesting for volatile expressions which have to
diff --git a/src/test/regress/sql/incremental_sort.sql b/src/test/regress/sql/incremental_sort.sql
index 3ee11c394b..cb48f200ce 100644
--- a/src/test/regress/sql/incremental_sort.sql
+++ b/src/test/regress/sql/incremental_sort.sql
@@ -220,6 +220,10 @@ explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1
set enable_hashagg to off;
explain (costs off) select * from t union select * from t order by 1,3;
+-- Full sort, not just incremental sort can be pushed below a gather merge path
+-- by generate_useful_gather_paths.
+explain (costs off) select distinct a,b from t;
+
drop table t;
-- Sort pushdown can't go below where expressions are part of the rel target.
--
2.17.1