Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0cf1668

Browse files
committed
Back-patch "Fix EquivalenceClass processing for nested append relations".
When we committeda87c729, we somehowfailed to notice that it didn't merely improve plan quality for expressionindexes; there were very closely related cases that failed outright with"could not find pathkey item to sort". The failing cases seem to be thosewhere the planner was already capable of selecting a MergeAppend plan,and there was inheritance involved: the lack of appropriate eclass childmembers would prevent prepare_sort_from_pathkeys() from succeeding on theMergeAppend's child plan nodes for inheritance child tables.Accordingly, back-patch into 9.1 through 9.3, along with an extraregression test case covering the problem.Per trouble report from Michael Glaesemann.
1 parent4ee4594 commit0cf1668

File tree

5 files changed

+76
-9
lines changed

5 files changed

+76
-9
lines changed

‎src/backend/optimizer/path/allpaths.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,10 +1011,15 @@ get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel,
10111011
* accumulate_append_subpath
10121012
*Add a subpath to the list being built for an Append or MergeAppend
10131013
*
1014-
* It's possible that the child is itself an Append path, in which case
1015-
* we can "cut out the middleman" and just add its child paths to our
1016-
* own list. (We don't try to do this earlier because we need to
1017-
* apply both levels of transformation to the quals.)
1014+
* It's possible that the child is itself an Append or MergeAppend path, in
1015+
* which case we can "cut out the middleman" and just add its child paths to
1016+
* our own list. (We don't try to do this earlier because we need to apply
1017+
* both levels of transformation to the quals.)
1018+
*
1019+
* Note that if we omit a child MergeAppend in this way, we are effectively
1020+
* omitting a sort step, which seems fine: if the parent is to be an Append,
1021+
* its result would be unsorted anyway, while if the parent is to be a
1022+
* MergeAppend, there's no point in a separate sort on a child.
10181023
*/
10191024
staticList*
10201025
accumulate_append_subpath(List*subpaths,Path*path)
@@ -1026,6 +1031,13 @@ accumulate_append_subpath(List *subpaths, Path *path)
10261031
/* list_copy is important here to avoid sharing list substructure */
10271032
returnlist_concat(subpaths,list_copy(apath->subpaths));
10281033
}
1034+
elseif (IsA(path,MergeAppendPath))
1035+
{
1036+
MergeAppendPath*mpath= (MergeAppendPath*)path;
1037+
1038+
/* list_copy is important here to avoid sharing list substructure */
1039+
returnlist_concat(subpaths,list_copy(mpath->subpaths));
1040+
}
10291041
else
10301042
returnlappend(subpaths,path);
10311043
}

‎src/backend/optimizer/path/equivclass.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,16 +1937,20 @@ add_child_rel_equivalences(PlannerInfo *root,
19371937
if (cur_ec->ec_has_volatile)
19381938
continue;
19391939

1940-
/* No point in searching if parent rel not mentioned in eclass */
1941-
if (!bms_is_subset(parent_rel->relids,cur_ec->ec_relids))
1940+
/*
1941+
* No point in searching if parent rel not mentioned in eclass; but
1942+
* we can't tell that for sure if parent rel is itself a child.
1943+
*/
1944+
if (parent_rel->reloptkind==RELOPT_BASEREL&&
1945+
!bms_is_subset(parent_rel->relids,cur_ec->ec_relids))
19421946
continue;
19431947

19441948
foreach(lc2,cur_ec->ec_members)
19451949
{
19461950
EquivalenceMember*cur_em= (EquivalenceMember*)lfirst(lc2);
19471951

1948-
if (cur_em->em_is_const||cur_em->em_is_child)
1949-
continue;/* ignore constsand childrenhere */
1952+
if (cur_em->em_is_const)
1953+
continue;/* ignore consts here */
19501954

19511955
/* Does it reference parent_rel? */
19521956
if (bms_overlap(cur_em->em_relids,parent_rel->relids))

‎src/backend/optimizer/plan/createplan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
731731

732732
/* Compute sort column info, and adjust MergeAppend's tlist as needed */
733733
(void)prepare_sort_from_pathkeys(root,plan,pathkeys,
734-
NULL,
734+
best_path->path.parent->relids,
735735
NULL,
736736
true,
737737
&node->numCols,

‎src/test/regress/expected/union.out

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,39 @@ explain (costs off)
500500
Index Cond: (ab = 'ab'::text)
501501
(6 rows)
502502

503+
--
504+
-- Test that ORDER BY for UNION ALL can be pushed down to inheritance
505+
-- children.
506+
--
503507
reset enable_seqscan;
504508
reset enable_indexscan;
505509
reset enable_bitmapscan;
510+
set enable_indexonlyscan = off;
511+
create table events (event_id int primary key);
512+
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "events_pkey" for table "events"
513+
create table other_events (event_id int primary key);
514+
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "other_events_pkey" for table "other_events"
515+
create table events_child () inherits (events);
516+
explain (costs off)
517+
select event_id
518+
from (select event_id from events
519+
union all
520+
select event_id from other_events) ss
521+
order by event_id;
522+
QUERY PLAN
523+
----------------------------------------------------------------
524+
Result
525+
-> Merge Append
526+
Sort Key: public.events.event_id
527+
-> Index Scan using events_pkey on events
528+
-> Sort
529+
Sort Key: public.events.event_id
530+
-> Seq Scan on events_child events
531+
-> Index Scan using other_events_pkey on other_events
532+
(8 rows)
533+
534+
drop table events_child, events, other_events;
535+
reset enable_indexonlyscan;
506536
-- Test constraint exclusion of UNION ALL subqueries
507537
explain (costs off)
508538
SELECT * FROM

‎src/test/regress/sql/union.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,30 @@ explain (costs off)
196196
SELECT*FROM t2) t
197197
WHERE ab='ab';
198198

199+
--
200+
-- Test that ORDER BY for UNION ALL can be pushed down to inheritance
201+
-- children.
202+
--
203+
199204
reset enable_seqscan;
200205
reset enable_indexscan;
201206
reset enable_bitmapscan;
207+
set enable_indexonlyscan= off;
208+
209+
createtableevents (event_idintprimary key);
210+
createtableother_events (event_idintprimary key);
211+
createtableevents_child () inherits (events);
212+
213+
explain (costs off)
214+
select event_id
215+
from (select event_idfrom events
216+
union all
217+
select event_idfrom other_events) ss
218+
order by event_id;
219+
220+
droptable events_child, events, other_events;
221+
222+
reset enable_indexonlyscan;
202223

203224
-- Test constraint exclusion of UNION ALL subqueries
204225
explain (costs off)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp