* from actually being generated.
*/
bool
-eclass_useful_for_merging(EquivalenceClass *eclass,
+eclass_useful_for_merging(PlannerInfo *root,
+ EquivalenceClass *eclass,
RelOptInfo *rel)
{
+ Relids relids;
ListCell *lc;
Assert(!eclass->ec_merged);
* possibly-overoptimistic heuristic.
*/
+ /* If specified rel is a child, we must consider the topmost parent rel */
+ if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL)
+ relids = find_childrel_top_parent(root, rel)->relids;
+ else
+ relids = rel->relids;
+
/* If rel already includes all members of eclass, no point in searching */
- if (bms_is_subset(eclass->ec_relids, rel->relids))
+ if (bms_is_subset(eclass->ec_relids, relids))
return false;
/* To join, we need a member not in the given rel */
if (cur_em->em_is_child)
continue; /* ignore children here */
- if (!bms_overlap(cur_em->em_relids, rel->relids))
+ if (!bms_overlap(cur_em->em_relids, relids))
return true;
}
* surely possible to generate a mergejoin clause using them.
*/
if (rel->has_eclass_joins &&
- eclass_useful_for_merging(pathkey->pk_eclass, rel))
+ eclass_useful_for_merging(root, pathkey->pk_eclass, rel))
matched = true;
else
{
RelOptInfo *rel1, RelOptInfo *rel2);
extern bool has_relevant_eclass_joinclause(PlannerInfo *root,
RelOptInfo *rel1);
-extern bool eclass_useful_for_merging(EquivalenceClass *eclass,
+extern bool eclass_useful_for_merging(PlannerInfo *root,
+ EquivalenceClass *eclass,
RelOptInfo *rel);
extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist);
drop cascades to table matest2
drop cascades to table matest3
--
+-- Check that use of an index with an extraneous column doesn't produce
+-- a plan with extraneous sorting
+--
+create table matest0 (a int, b int, c int, d int);
+create table matest1 () inherits(matest0);
+create index matest0i on matest0 (b, c);
+create index matest1i on matest1 (b, c);
+set enable_nestloop = off; -- we want a plan with two MergeAppends
+explain (costs off)
+select t1.* from matest0 t1, matest0 t2
+where t1.b = t2.b and t2.c = t2.d
+order by t1.b limit 10;
+ QUERY PLAN
+-------------------------------------------------------------------
+ Limit
+ -> Merge Join
+ Merge Cond: (t1.b = t2.b)
+ -> Merge Append
+ Sort Key: t1.b
+ -> Index Scan using matest0i on matest0 t1
+ -> Index Scan using matest1i on matest1 t1_1
+ -> Materialize
+ -> Merge Append
+ Sort Key: t2.b
+ -> Index Scan using matest0i on matest0 t2
+ Filter: (c = d)
+ -> Index Scan using matest1i on matest1 t2_1
+ Filter: (c = d)
+(14 rows)
+
+reset enable_nestloop;
+drop table matest0 cascade;
+NOTICE: drop cascades to table matest1
+--
-- Test merge-append for UNION ALL append relations
--
set enable_seqscan = off;
drop table matest0 cascade;
+--
+-- Check that use of an index with an extraneous column doesn't produce
+-- a plan with extraneous sorting
+--
+
+create table matest0 (a int, b int, c int, d int);
+create table matest1 () inherits(matest0);
+create index matest0i on matest0 (b, c);
+create index matest1i on matest1 (b, c);
+
+set enable_nestloop = off; -- we want a plan with two MergeAppends
+
+explain (costs off)
+select t1.* from matest0 t1, matest0 t2
+where t1.b = t2.b and t2.c = t2.d
+order by t1.b limit 10;
+
+reset enable_nestloop;
+
+drop table matest0 cascade;
+
--
-- Test merge-append for UNION ALL append relations
--