treat_window_func_calc_parallel_restricted_v3.patch
application/octet-stream
Filename: treat_window_func_calc_parallel_restricted_v3.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/optimizer/util/clauses.c | 14 | 0 |
| src/test/regress/expected/select_parallel.out | 26 | 0 |
| src/test/regress/sql/select_parallel.sql | 6 | 0 |
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index a04ad6e..48fa34f 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1197,6 +1197,20 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
}
/*
+ * Treat window functions as parallel-restricted because we aren't sure
+ * whether the input row ordering is fully deterministic, and the output
+ * of window functions might vary across workers if not. (In some cases,
+ * like where the window frame orders by a primary key, we could relax
+ * this restriction. But it doesn't currently seem worth expending extra
+ * effort to do so.)
+ */
+ if (IsA(node, WindowFunc))
+ {
+ if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context))
+ return true;
+ }
+
+ /*
* As a notational convenience for callers, look through RestrictInfo.
*/
else if (IsA(node, RestrictInfo))
diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out
index f1b8cd4..d9c60c0 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -958,6 +958,32 @@ select count(*) from tenk1;
reset force_parallel_mode;
reset role;
+-- Window function calculation can't be pushed to workers.
+explain (costs off, verbose)
+ select count(*) from tenk1 where (unique1, two) in
+ (select unique1, row_number() over() from tenk1);
+ QUERY PLAN
+----------------------------------------------------------------------------------------------------
+ Aggregate
+ Output: count(*)
+ -> Hash Semi Join
+ Hash Cond: ((tenk1.unique1 = tenk1_1.unique1) AND (tenk1.two = (row_number() OVER (?))))
+ -> Gather
+ Output: tenk1.unique1, tenk1.two
+ Workers Planned: 4
+ -> Parallel Seq Scan on public.tenk1
+ Output: tenk1.unique1, tenk1.two
+ -> Hash
+ Output: tenk1_1.unique1, (row_number() OVER (?))
+ -> WindowAgg
+ Output: tenk1_1.unique1, row_number() OVER (?)
+ -> Gather
+ Output: tenk1_1.unique1
+ Workers Planned: 4
+ -> Parallel Index Only Scan using tenk1_unique1 on public.tenk1 tenk1_1
+ Output: tenk1_1.unique1
+(18 rows)
+
-- to increase the parallel query test coverage
SAVEPOINT settings;
SET LOCAL force_parallel_mode = 1;
diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql
index 7771e05..f8a0c08 100644
--- a/src/test/regress/sql/select_parallel.sql
+++ b/src/test/regress/sql/select_parallel.sql
@@ -362,6 +362,12 @@ select count(*) from tenk1;
reset force_parallel_mode;
reset role;
+-- Window function calculation can't be pushed to workers.
+explain (costs off, verbose)
+ select count(*) from tenk1 where (unique1, two) in
+ (select unique1, row_number() over() from tenk1);
+
+
-- to increase the parallel query test coverage
SAVEPOINT settings;
SET LOCAL force_parallel_mode = 1;