summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/joinrels.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/joinrels.c')
-rw-r--r--src/backend/optimizer/path/joinrels.c65
1 files changed, 21 insertions, 44 deletions
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index a1681ae994f..f51e492eca1 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -8,12 +8,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.73 2005/06/05 22:32:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.74 2005/06/09 04:18:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "optimizer/joininfo.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
@@ -169,30 +170,20 @@ make_rels_by_joins(PlannerInfo *root, int level, List **joinrels)
if (!bms_overlap(old_rel->relids, new_rel->relids))
{
- ListCell *i;
-
/*
* OK, we can build a rel of the right level from this
* pair of rels. Do so if there is at least one
* usable join clause.
*/
- foreach(i, old_rel->joininfo)
+ if (have_relevant_joinclause(old_rel, new_rel))
{
- JoinInfo *joininfo = (JoinInfo *) lfirst(i);
-
- if (bms_is_subset(joininfo->unjoined_relids,
- new_rel->relids))
- {
- RelOptInfo *jrel;
-
- jrel = make_join_rel(root, old_rel, new_rel,
- JOIN_INNER);
- /* Avoid making duplicate entries ... */
- if (jrel && !list_member_ptr(result_rels, jrel))
- result_rels = lcons(jrel, result_rels);
- break; /* need not consider more
- * joininfos */
- }
+ RelOptInfo *jrel;
+
+ jrel = make_join_rel(root, old_rel, new_rel,
+ JOIN_INNER);
+ /* Avoid making duplicate entries ... */
+ if (jrel && !list_member_ptr(result_rels, jrel))
+ result_rels = lcons(jrel, result_rels);
}
}
}
@@ -269,7 +260,7 @@ make_rels_by_joins(PlannerInfo *root, int level, List **joinrels)
/*
* make_rels_by_clause_joins
* Build joins between the given relation 'old_rel' and other relations
- * that are mentioned within old_rel's joininfo nodes (i.e., relations
+ * that are mentioned within old_rel's joininfo list (i.e., relations
* that participate in join clauses that 'old_rel' also participates in).
* The join rel nodes are returned in a list.
*
@@ -278,10 +269,7 @@ make_rels_by_joins(PlannerInfo *root, int level, List **joinrels)
* rels to be considered for joining
*
* Currently, this is only used with initial rels in other_rels, but it
- * will work for joining to joinrels too, if the caller ensures there is no
- * membership overlap between old_rel and the rels in other_rels. (We need
- * no extra test for overlap for initial rels, since the is_subset test can
- * only succeed when other_rel is not already part of old_rel.)
+ * will work for joining to joinrels too.
*/
static List *
make_rels_by_clause_joins(PlannerInfo *root,
@@ -289,31 +277,20 @@ make_rels_by_clause_joins(PlannerInfo *root,
ListCell *other_rels)
{
List *result = NIL;
- ListCell *i,
- *j;
+ ListCell *l;
- foreach(i, old_rel->joininfo)
+ for_each_cell(l, other_rels)
{
- JoinInfo *joininfo = (JoinInfo *) lfirst(i);
- Relids unjoined_relids = joininfo->unjoined_relids;
+ RelOptInfo *other_rel = (RelOptInfo *) lfirst(l);
- for_each_cell(j, other_rels)
+ if (!bms_overlap(old_rel->relids, other_rel->relids) &&
+ have_relevant_joinclause(old_rel, other_rel))
{
- RelOptInfo *other_rel = (RelOptInfo *) lfirst(j);
-
- if (bms_is_subset(unjoined_relids, other_rel->relids))
- {
- RelOptInfo *jrel;
-
- jrel = make_join_rel(root, old_rel, other_rel, JOIN_INNER);
+ RelOptInfo *jrel;
- /*
- * Avoid entering same joinrel into our output list more
- * than once.
- */
- if (jrel && !list_member_ptr(result, jrel))
- result = lcons(jrel, result);
- }
+ jrel = make_join_rel(root, old_rel, other_rel, JOIN_INNER);
+ if (jrel)
+ result = lcons(jrel, result);
}
}