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;