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

Commitd31e794

Browse files
committed
Fix eclass_useful_for_merging to give valid results for appendrel children.
Formerly, this function would always return "true" for an appendrel childrelation, because it would think that the appendrel parent was a potentialjoin target for the child. In principle that should only lead to someinefficiency in planning, but fuzz testing by Andreas Seltenreich disclosedthat it could lead to "could not find pathkey item to sort" planner errorsin odd corner cases. Specifically, we would think that all columns of achild table's multicolumn index were interesting pathkeys, causing us togenerate a MergeAppend path that sorts by all the columns. However, if anyof those columns weren't actually used above the level of the appendrel,they would not get added to that rel's targetlist, which would result inbeing unable to resolve the MergeAppend's sort keys against its targetlistduring createplan.c.Backpatch to 9.3. In older versions, columns of an appendrel get addedto its targetlist even if they're not mentioned above the scan level,so that the failure doesn't occur. It might be worth back-patching thisfix to older versions anyway, but I'll refrain for the moment.
1 parent7ef507a commitd31e794

File tree

5 files changed

+69
-5
lines changed

5 files changed

+69
-5
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,9 +2286,11 @@ has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1)
22862286
* from actually being generated.
22872287
*/
22882288
bool
2289-
eclass_useful_for_merging(EquivalenceClass*eclass,
2289+
eclass_useful_for_merging(PlannerInfo*root,
2290+
EquivalenceClass*eclass,
22902291
RelOptInfo*rel)
22912292
{
2293+
Relidsrelids;
22922294
ListCell*lc;
22932295

22942296
Assert(!eclass->ec_merged);
@@ -2306,8 +2308,14 @@ eclass_useful_for_merging(EquivalenceClass *eclass,
23062308
* possibly-overoptimistic heuristic.
23072309
*/
23082310

2311+
/* If specified rel is a child, we must consider the topmost parent rel */
2312+
if (rel->reloptkind==RELOPT_OTHER_MEMBER_REL)
2313+
relids=find_childrel_top_parent(root,rel)->relids;
2314+
else
2315+
relids=rel->relids;
2316+
23092317
/* If rel already includes all members of eclass, no point in searching */
2310-
if (bms_is_subset(eclass->ec_relids,rel->relids))
2318+
if (bms_is_subset(eclass->ec_relids,relids))
23112319
return false;
23122320

23132321
/* To join, we need a member not in the given rel */
@@ -2318,7 +2326,7 @@ eclass_useful_for_merging(EquivalenceClass *eclass,
23182326
if (cur_em->em_is_child)
23192327
continue;/* ignore children here */
23202328

2321-
if (!bms_overlap(cur_em->em_relids,rel->relids))
2329+
if (!bms_overlap(cur_em->em_relids,relids))
23222330
return true;
23232331
}
23242332

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,7 @@ pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
13731373
* surely possible to generate a mergejoin clause using them.
13741374
*/
13751375
if (rel->has_eclass_joins&&
1376-
eclass_useful_for_merging(pathkey->pk_eclass,rel))
1376+
eclass_useful_for_merging(root,pathkey->pk_eclass,rel))
13771377
matched= true;
13781378
else
13791379
{

‎src/include/optimizer/paths.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ extern bool have_relevant_eclass_joinclause(PlannerInfo *root,
130130
RelOptInfo*rel1,RelOptInfo*rel2);
131131
externboolhas_relevant_eclass_joinclause(PlannerInfo*root,
132132
RelOptInfo*rel1);
133-
externbooleclass_useful_for_merging(EquivalenceClass*eclass,
133+
externbooleclass_useful_for_merging(PlannerInfo*root,
134+
EquivalenceClass*eclass,
134135
RelOptInfo*rel);
135136
externboolis_redundant_derived_clause(RestrictInfo*rinfo,List*clauselist);
136137

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,40 @@ DETAIL: drop cascades to table matest1
13071307
drop cascades to table matest2
13081308
drop cascades to table matest3
13091309
--
1310+
-- Check that use of an index with an extraneous column doesn't produce
1311+
-- a plan with extraneous sorting
1312+
--
1313+
create table matest0 (a int, b int, c int, d int);
1314+
create table matest1 () inherits(matest0);
1315+
create index matest0i on matest0 (b, c);
1316+
create index matest1i on matest1 (b, c);
1317+
set enable_nestloop = off; -- we want a plan with two MergeAppends
1318+
explain (costs off)
1319+
select t1.* from matest0 t1, matest0 t2
1320+
where t1.b = t2.b and t2.c = t2.d
1321+
order by t1.b limit 10;
1322+
QUERY PLAN
1323+
-------------------------------------------------------------------
1324+
Limit
1325+
-> Merge Join
1326+
Merge Cond: (t1.b = t2.b)
1327+
-> Merge Append
1328+
Sort Key: t1.b
1329+
-> Index Scan using matest0i on matest0 t1
1330+
-> Index Scan using matest1i on matest1 t1_1
1331+
-> Materialize
1332+
-> Merge Append
1333+
Sort Key: t2.b
1334+
-> Index Scan using matest0i on matest0 t2
1335+
Filter: (c = d)
1336+
-> Index Scan using matest1i on matest1 t2_1
1337+
Filter: (c = d)
1338+
(14 rows)
1339+
1340+
reset enable_nestloop;
1341+
drop table matest0 cascade;
1342+
NOTICE: drop cascades to table matest1
1343+
--
13101344
-- Test merge-append for UNION ALL append relations
13111345
--
13121346
set enable_seqscan = off;

‎src/test/regress/sql/inherit.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,27 @@ reset enable_seqscan;
402402

403403
droptable matest0 cascade;
404404

405+
--
406+
-- Check that use of an index with an extraneous column doesn't produce
407+
-- a plan with extraneous sorting
408+
--
409+
410+
createtablematest0 (aint, bint, cint, dint);
411+
createtablematest1 () inherits(matest0);
412+
createindexmatest0ion matest0 (b, c);
413+
createindexmatest1ion matest1 (b, c);
414+
415+
set enable_nestloop= off;-- we want a plan with two MergeAppends
416+
417+
explain (costs off)
418+
select t1.*from matest0 t1, matest0 t2
419+
wheret1.b=t2.bandt2.c=t2.d
420+
order byt1.blimit10;
421+
422+
reset enable_nestloop;
423+
424+
droptable matest0 cascade;
425+
405426
--
406427
-- Test merge-append for UNION ALL append relations
407428
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp