summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/util/clauses.c14
-rw-r--r--src/test/regress/expected/select_parallel.out23
-rw-r--r--src/test/regress/sql/select_parallel.sql5
3 files changed, 42 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 8cdee705d15..9f2ead73cb5 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1162,6 +1162,20 @@ has_parallel_hazard_walker(Node *node, has_parallel_hazard_arg *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.)
+ */
+ else if (IsA(node, WindowFunc))
+ {
+ if (!context->allow_restricted)
+ 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 43801e0f8a2..926202192b3 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -182,6 +182,29 @@ select count(*) from tenk1;
(1 row)
reset role;
+-- Window function calculation can't be pushed to workers.
+explain (costs off, verbose)
+ select count(*) from tenk1 a where (unique1, two) in
+ (select unique1, row_number() over() from tenk1 b);
+ QUERY PLAN
+------------------------------------------------------------------------------------
+ Aggregate
+ Output: count(*)
+ -> Hash Semi Join
+ Hash Cond: ((a.unique1 = b.unique1) AND (a.two = (row_number() OVER (?))))
+ -> Gather
+ Output: a.unique1, a.two
+ Workers Planned: 4
+ -> Parallel Seq Scan on public.tenk1 a
+ Output: a.unique1, a.two
+ -> Hash
+ Output: b.unique1, (row_number() OVER (?))
+ -> WindowAgg
+ Output: b.unique1, row_number() OVER (?)
+ -> Index Only Scan using tenk1_unique1 on public.tenk1 b
+ Output: b.unique1
+(15 rows)
+
explain (costs off)
select stringu1::int2 from tenk1 where unique1 = 1;
QUERY PLAN
diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql
index 7defc34cb78..266d0dd6464 100644
--- a/src/test/regress/sql/select_parallel.sql
+++ b/src/test/regress/sql/select_parallel.sql
@@ -83,6 +83,11 @@ drop role regress_parallel_worker;
select count(*) from tenk1;
reset role;
+-- Window function calculation can't be pushed to workers.
+explain (costs off, verbose)
+ select count(*) from tenk1 a where (unique1, two) in
+ (select unique1, row_number() over() from tenk1 b);
+
explain (costs off)
select stringu1::int2 from tenk1 where unique1 = 1;