mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Prohibit pushing subqueries containing window function calculation to
workers. Allowing window function calculation in workers leads to inconsistent results because if the input row ordering is not fully deterministic, the output of window functions might vary across workers. The fix is to treat them as parallel-restricted. In the passing, improve the coding pattern in max_parallel_hazard_walker so that it has a chain of mutually-exclusive if ... else if ... else if ... else if ... IsA tests. Reported-by: Marko Tiikkaja Bug: 15324 Author: Amit Kapila Reviewed-by: Tom Lane Backpatch-through: 9.6 Discussion: https://postgr.es/m/CAL9smLAnfPJCDUUG4ckX2iznj53V7VSMsYefzZieN93YxTNOcw@mail.gmail.com
This commit is contained in:
parent
7c9e19ca9a
commit
14e9b2a752
@ -1190,12 +1190,26 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsA(node, NextValueExpr))
|
else if (IsA(node, NextValueExpr))
|
||||||
{
|
{
|
||||||
if (max_parallel_hazard_test(PROPARALLEL_UNSAFE, context))
|
if (max_parallel_hazard_test(PROPARALLEL_UNSAFE, context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As a notational convenience for callers, look through RestrictInfo.
|
* As a notational convenience for callers, look through RestrictInfo.
|
||||||
*/
|
*/
|
||||||
|
@ -958,6 +958,32 @@ select count(*) from tenk1;
|
|||||||
|
|
||||||
reset force_parallel_mode;
|
reset force_parallel_mode;
|
||||||
reset role;
|
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 (?)
|
||||||
|
-> Gather
|
||||||
|
Output: b.unique1
|
||||||
|
Workers Planned: 4
|
||||||
|
-> Parallel Index Only Scan using tenk1_unique1 on public.tenk1 b
|
||||||
|
Output: b.unique1
|
||||||
|
(18 rows)
|
||||||
|
|
||||||
-- to increase the parallel query test coverage
|
-- to increase the parallel query test coverage
|
||||||
SAVEPOINT settings;
|
SAVEPOINT settings;
|
||||||
SET LOCAL force_parallel_mode = 1;
|
SET LOCAL force_parallel_mode = 1;
|
||||||
|
@ -362,6 +362,12 @@ select count(*) from tenk1;
|
|||||||
reset force_parallel_mode;
|
reset force_parallel_mode;
|
||||||
reset role;
|
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);
|
||||||
|
|
||||||
|
|
||||||
-- to increase the parallel query test coverage
|
-- to increase the parallel query test coverage
|
||||||
SAVEPOINT settings;
|
SAVEPOINT settings;
|
||||||
SET LOCAL force_parallel_mode = 1;
|
SET LOCAL force_parallel_mode = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user