mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Fix assertion failure when Parallel Append is run serially.
Parallel-aware plan nodes must be prepared to run without parallelism
if it's not possible at execution time for whatever reason. Commit
ab72716778
, which introduced Parallel
Append, overlooked this.
Rajkumar Raghuwanshi reported this problem, and I included his test
case in this patch. The code changes are by me.
Discussion: http://postgr.es/m/CAKcux6=WqkUudLg1GLZZ7fc5ScWC1+Y9qD=pAHeqy32WoeJQvw@mail.gmail.com
This commit is contained in:
@ -162,7 +162,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
|
|||||||
appendstate->as_whichplan =
|
appendstate->as_whichplan =
|
||||||
appendstate->ps.plan->parallel_aware ? INVALID_SUBPLAN_INDEX : 0;
|
appendstate->ps.plan->parallel_aware ? INVALID_SUBPLAN_INDEX : 0;
|
||||||
|
|
||||||
/* If parallel-aware, this will be overridden later. */
|
/* For parallel query, this will be overridden later. */
|
||||||
appendstate->choose_next_subplan = choose_next_subplan_locally;
|
appendstate->choose_next_subplan = choose_next_subplan_locally;
|
||||||
|
|
||||||
return appendstate;
|
return appendstate;
|
||||||
@ -361,14 +361,21 @@ choose_next_subplan_locally(AppendState *node)
|
|||||||
{
|
{
|
||||||
int whichplan = node->as_whichplan;
|
int whichplan = node->as_whichplan;
|
||||||
|
|
||||||
/* We should never see INVALID_SUBPLAN_INDEX in this case. */
|
|
||||||
Assert(whichplan >= 0 && whichplan <= node->as_nplans);
|
|
||||||
|
|
||||||
if (ScanDirectionIsForward(node->ps.state->es_direction))
|
if (ScanDirectionIsForward(node->ps.state->es_direction))
|
||||||
{
|
{
|
||||||
if (whichplan >= node->as_nplans - 1)
|
/*
|
||||||
return false;
|
* We won't normally see INVALID_SUBPLAN_INDEX in this case, but we
|
||||||
node->as_whichplan++;
|
* might if a plan intended to be run in parallel ends up being run
|
||||||
|
* serially.
|
||||||
|
*/
|
||||||
|
if (whichplan == INVALID_SUBPLAN_INDEX)
|
||||||
|
node->as_whichplan = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (whichplan >= node->as_nplans - 1)
|
||||||
|
return false;
|
||||||
|
node->as_whichplan++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -121,6 +121,17 @@ select round(avg(aa)), sum(aa) from a_star a4;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
reset enable_parallel_append;
|
reset enable_parallel_append;
|
||||||
|
-- Parallel Append that runs serially
|
||||||
|
create or replace function foobar() returns setof text as
|
||||||
|
$$ select 'foo'::varchar union all select 'bar'::varchar $$
|
||||||
|
language sql stable;
|
||||||
|
select foobar() order by 1;
|
||||||
|
foobar
|
||||||
|
--------
|
||||||
|
bar
|
||||||
|
foo
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- test with leader participation disabled
|
-- test with leader participation disabled
|
||||||
set parallel_leader_participation = off;
|
set parallel_leader_participation = off;
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
|
@ -49,6 +49,12 @@ explain (costs off)
|
|||||||
select round(avg(aa)), sum(aa) from a_star a4;
|
select round(avg(aa)), sum(aa) from a_star a4;
|
||||||
reset enable_parallel_append;
|
reset enable_parallel_append;
|
||||||
|
|
||||||
|
-- Parallel Append that runs serially
|
||||||
|
create or replace function foobar() returns setof text as
|
||||||
|
$$ select 'foo'::varchar union all select 'bar'::varchar $$
|
||||||
|
language sql stable;
|
||||||
|
select foobar() order by 1;
|
||||||
|
|
||||||
-- test with leader participation disabled
|
-- test with leader participation disabled
|
||||||
set parallel_leader_participation = off;
|
set parallel_leader_participation = off;
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
|
Reference in New Issue
Block a user