diff options
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 14 | ||||
-rw-r--r-- | src/test/regress/expected/select_parallel.out | 23 | ||||
-rw-r--r-- | src/test/regress/sql/select_parallel.sql | 5 |
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; |