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

Commit555d0b2

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 parent8658680 commit555d0b2

File tree

5 files changed

+71
-9
lines changed

5 files changed

+71
-9
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,10 +635,15 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
635635
* accumulate_append_subpath
636636
*Add a subpath to the list being built for an Append or MergeAppend
637637
*
638-
* It's possible that the child is itself an Append path, in which case
639-
* we can "cut out the middleman" and just add its child paths to our
640-
* own list. (We don't try to do this earlier because we need to
641-
* apply both levels of transformation to the quals.)
638+
* It's possible that the child is itself an Append or MergeAppend path, in
639+
* which case we can "cut out the middleman" and just add its child paths to
640+
* our own list. (We don't try to do this earlier because we need to apply
641+
* both levels of transformation to the quals.)
642+
*
643+
* Note that if we omit a child MergeAppend in this way, we are effectively
644+
* omitting a sort step, which seems fine: if the parent is to be an Append,
645+
* its result would be unsorted anyway, while if the parent is to be a
646+
* MergeAppend, there's no point in a separate sort on a child.
642647
*/
643648
staticList*
644649
accumulate_append_subpath(List*subpaths,Path*path)
@@ -650,6 +655,13 @@ accumulate_append_subpath(List *subpaths, Path *path)
650655
/* list_copy is important here to avoid sharing list substructure */
651656
returnlist_concat(subpaths,list_copy(apath->subpaths));
652657
}
658+
elseif (IsA(path,MergeAppendPath))
659+
{
660+
MergeAppendPath*mpath= (MergeAppendPath*)path;
661+
662+
/* list_copy is important here to avoid sharing list substructure */
663+
returnlist_concat(subpaths,list_copy(mpath->subpaths));
664+
}
653665
else
654666
returnlappend(subpaths,path);
655667
}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,16 +1850,20 @@ add_child_rel_equivalences(PlannerInfo *root,
18501850
if (cur_ec->ec_has_volatile)
18511851
continue;
18521852

1853-
/* No point in searching if parent rel not mentioned in eclass */
1854-
if (!bms_is_subset(parent_rel->relids,cur_ec->ec_relids))
1853+
/*
1854+
* No point in searching if parent rel not mentioned in eclass; but
1855+
* we can't tell that for sure if parent rel is itself a child.
1856+
*/
1857+
if (parent_rel->reloptkind==RELOPT_BASEREL&&
1858+
!bms_is_subset(parent_rel->relids,cur_ec->ec_relids))
18551859
continue;
18561860

18571861
foreach(lc2,cur_ec->ec_members)
18581862
{
18591863
EquivalenceMember*cur_em= (EquivalenceMember*)lfirst(lc2);
18601864

1861-
if (cur_em->em_is_child)
1862-
continue;/* ignorechildren here */
1865+
if (cur_em->em_is_const)
1866+
continue;/* ignoreconsts here */
18631867

18641868
/* Does it reference (only) parent_rel? */
18651869
if (bms_equal(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
@@ -700,7 +700,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
700700

701701
/* Compute sort column info, and adjust MergeAppend's tlist as needed */
702702
(void)prepare_sort_from_pathkeys(root,plan,pathkeys,
703-
NULL,
703+
best_path->path.parent->relids,
704704
NULL,
705705
true,
706706
&node->numCols,

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,37 @@ 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+
create table events (event_id int primary key);
511+
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "events_pkey" for table "events"
512+
create table other_events (event_id int primary key);
513+
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "other_events_pkey" for table "other_events"
514+
create table events_child () inherits (events);
515+
explain (costs off)
516+
select event_id
517+
from (select event_id from events
518+
union all
519+
select event_id from other_events) ss
520+
order by event_id;
521+
QUERY PLAN
522+
----------------------------------------------------------------
523+
Result
524+
-> Merge Append
525+
Sort Key: public.events.event_id
526+
-> Index Scan using events_pkey on events
527+
-> Sort
528+
Sort Key: public.events.event_id
529+
-> Seq Scan on events_child events
530+
-> Index Scan using other_events_pkey on other_events
531+
(8 rows)
532+
533+
drop table events_child, events, other_events;
506534
-- Test constraint exclusion of UNION ALL subqueries
507535
explain (costs off)
508536
SELECT * FROM

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,28 @@ 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;
202207

208+
createtableevents (event_idintprimary key);
209+
createtableother_events (event_idintprimary key);
210+
createtableevents_child () inherits (events);
211+
212+
explain (costs off)
213+
select event_id
214+
from (select event_idfrom events
215+
union all
216+
select event_idfrom other_events) ss
217+
order by event_id;
218+
219+
droptable events_child, events, other_events;
220+
203221
-- Test constraint exclusion of UNION ALL subqueries
204222
explain (costs off)
205223
SELECT*FROM

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp