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.c884
1 files changed, 467 insertions, 417 deletions
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 00f8a04a050..98762f9800c 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joinrels.c--
- * Routines to determine which relations should be joined
+ * Routines to determine which relations should be joined
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.4 1997/06/05 09:33:52 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.5 1997/09/07 04:43:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,467 +24,508 @@
#include "optimizer/pathnode.h"
#ifdef USE_RIGHT_SIDED_PLANS
-bool _use_right_sided_plans_ = true;
+bool _use_right_sided_plans_ = true;
+
#else
-bool _use_right_sided_plans_ = false;
+bool _use_right_sided_plans_ = false;
+
#endif
-static List *find_clause_joins(Query *root, Rel *outer_rel, List *joininfo_list);
-static List *find_clauseless_joins(Rel *outer_rel, List *inner_rels);
-static Rel *init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo);
-static List *new_join_tlist(List *tlist, List *other_relids,
- int first_resdomno);
-static List *new_joininfo_list(List *joininfo_list, List *join_relids);
-static void add_superrels(Rel *rel, Rel *super_rel);
-static bool nonoverlap_rels(Rel *rel1, Rel *rel2);
-static bool nonoverlap_sets(List *s1, List *s2);
-static void set_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel,
- JInfo *jinfo);
-
-/*
+static List *find_clause_joins(Query * root, Rel * outer_rel, List * joininfo_list);
+static List *find_clauseless_joins(Rel * outer_rel, List * inner_rels);
+static Rel *init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo);
+static List *
+new_join_tlist(List * tlist, List * other_relids,
+ int first_resdomno);
+static List *new_joininfo_list(List * joininfo_list, List * join_relids);
+static void add_superrels(Rel * rel, Rel * super_rel);
+static bool nonoverlap_rels(Rel * rel1, Rel * rel2);
+static bool nonoverlap_sets(List * s1, List * s2);
+static void
+set_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel,
+ JInfo * jinfo);
+
+/*
* find-join-rels--
- * Find all possible joins for each of the outer join relations in
- * 'outer-rels'. A rel node is created for each possible join relation,
- * and the resulting list of nodes is returned. If at all possible, only
- * those relations for which join clauses exist are considered. If none
- * of these exist for a given relation, all remaining possibilities are
- * considered.
- *
+ * Find all possible joins for each of the outer join relations in
+ * 'outer-rels'. A rel node is created for each possible join relation,
+ * and the resulting list of nodes is returned. If at all possible, only
+ * those relations for which join clauses exist are considered. If none
+ * of these exist for a given relation, all remaining possibilities are
+ * considered.
+ *
* 'outer-rels' is the list of rel nodes
- *
+ *
* Returns a list of rel nodes corresponding to the new join relations.
*/
-List *
-find_join_rels(Query *root, List *outer_rels)
+List *
+find_join_rels(Query * root, List * outer_rels)
{
- List *joins = NIL;
- List *join_list = NIL;
- List *r = NIL;
-
- foreach(r, outer_rels) {
- Rel *outer_rel = (Rel *)lfirst(r);
-
- if(!(joins = find_clause_joins(root, outer_rel,outer_rel->joininfo)))
- if (BushyPlanFlag)
- joins = find_clauseless_joins(outer_rel,outer_rels);
- else
- joins = find_clauseless_joins(outer_rel,root->base_relation_list_);
-
- join_list = nconc(join_list, joins);
- }
-
- return(join_list);
+ List *joins = NIL;
+ List *join_list = NIL;
+ List *r = NIL;
+
+ foreach(r, outer_rels)
+ {
+ Rel *outer_rel = (Rel *) lfirst(r);
+
+ if (!(joins = find_clause_joins(root, outer_rel, outer_rel->joininfo)))
+ if (BushyPlanFlag)
+ joins = find_clauseless_joins(outer_rel, outer_rels);
+ else
+ joins = find_clauseless_joins(outer_rel, root->base_relation_list_);
+
+ join_list = nconc(join_list, joins);
+ }
+
+ return (join_list);
}
-/*
+/*
* find-clause-joins--
- * Determines whether joins can be performed between an outer relation
- * 'outer-rel' and those relations within 'outer-rel's joininfo nodes
- * (i.e., relations that participate in join clauses that 'outer-rel'
- * participates in). This is possible if all but one of the relations
- * contained within the join clauses of the joininfo node are already
- * contained within 'outer-rel'.
+ * Determines whether joins can be performed between an outer relation
+ * 'outer-rel' and those relations within 'outer-rel's joininfo nodes
+ * (i.e., relations that participate in join clauses that 'outer-rel'
+ * participates in). This is possible if all but one of the relations
+ * contained within the join clauses of the joininfo node are already
+ * contained within 'outer-rel'.
*
* 'outer-rel' is the relation entry for the outer relation
- * 'joininfo-list' is a list of join clauses which 'outer-rel'
- * participates in
- *
+ * 'joininfo-list' is a list of join clauses which 'outer-rel'
+ * participates in
+ *
* Returns a list of new join relations.
*/
-static List *
-find_clause_joins(Query *root, Rel *outer_rel, List *joininfo_list)
+static List *
+find_clause_joins(Query * root, Rel * outer_rel, List * joininfo_list)
{
- List *join_list = NIL;
- List *i = NIL;
-
- foreach (i, joininfo_list) {
- JInfo *joininfo = (JInfo*)lfirst(i);
- Rel *rel;
-
- if(!joininfo->inactive) {
- List *other_rels = joininfo->otherrels;
-
- if(other_rels != NIL) {
- if(length(other_rels) == 1) {
- rel = init_join_rel(outer_rel,
- get_base_rel(root, lfirsti(other_rels)),
- joininfo);
- /* how about right-sided plan ? */
- if ( _use_right_sided_plans_ &&
- length (outer_rel->relids) > 1 )
- {
- if (rel != NULL)
- join_list = lappend(join_list, rel);
- rel = init_join_rel(get_base_rel(root, lfirsti(other_rels)),
- outer_rel,
- joininfo);
- }
- } else if (BushyPlanFlag) {
- rel = init_join_rel(outer_rel,
- get_join_rel(root, other_rels),
- joininfo);
- } else {
- rel = NULL;
- }
+ List *join_list = NIL;
+ List *i = NIL;
- if (rel != NULL)
- join_list = lappend(join_list, rel);
- }
+ foreach(i, joininfo_list)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(i);
+ Rel *rel;
+
+ if (!joininfo->inactive)
+ {
+ List *other_rels = joininfo->otherrels;
+
+ if (other_rels != NIL)
+ {
+ if (length(other_rels) == 1)
+ {
+ rel = init_join_rel(outer_rel,
+ get_base_rel(root, lfirsti(other_rels)),
+ joininfo);
+ /* how about right-sided plan ? */
+ if (_use_right_sided_plans_ &&
+ length(outer_rel->relids) > 1)
+ {
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
+ rel = init_join_rel(get_base_rel(root, lfirsti(other_rels)),
+ outer_rel,
+ joininfo);
+ }
+ }
+ else if (BushyPlanFlag)
+ {
+ rel = init_join_rel(outer_rel,
+ get_join_rel(root, other_rels),
+ joininfo);
+ }
+ else
+ {
+ rel = NULL;
+ }
+
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
+ }
+ }
}
- }
- return(join_list);
+ return (join_list);
}
-/*
+/*
* find-clauseless-joins--
- * Given an outer relation 'outer-rel' and a list of inner relations
- * 'inner-rels', create a join relation between 'outer-rel' and each
- * member of 'inner-rels' that isn't already included in 'outer-rel'.
- *
+ * Given an outer relation 'outer-rel' and a list of inner relations
+ * 'inner-rels', create a join relation between 'outer-rel' and each
+ * member of 'inner-rels' that isn't already included in 'outer-rel'.
+ *
* Returns a list of new join relations.
*/
-static List *
-find_clauseless_joins(Rel *outer_rel, List *inner_rels)
+static List *
+find_clauseless_joins(Rel * outer_rel, List * inner_rels)
{
- Rel *inner_rel;
- List *t_list = NIL;
- List *temp_node = NIL;
- List *i = NIL;
-
- foreach (i, inner_rels) {
- inner_rel = (Rel *)lfirst(i);
- if(nonoverlap_rels(inner_rel, outer_rel)) {
- temp_node = lcons(init_join_rel(outer_rel,
- inner_rel,
- (JInfo*)NULL),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ Rel *inner_rel;
+ List *t_list = NIL;
+ List *temp_node = NIL;
+ List *i = NIL;
+
+ foreach(i, inner_rels)
+ {
+ inner_rel = (Rel *) lfirst(i);
+ if (nonoverlap_rels(inner_rel, outer_rel))
+ {
+ temp_node = lcons(init_join_rel(outer_rel,
+ inner_rel,
+ (JInfo *) NULL),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* init-join-rel--
- * Creates and initializes a new join relation.
- *
+ * Creates and initializes a new join relation.
+ *
* 'outer-rel' and 'inner-rel' are relation nodes for the relations to be
- * joined
+ * joined
* 'joininfo' is the joininfo node(join clause) containing both
- * 'outer-rel' and 'inner-rel', if any exists
- *
+ * 'outer-rel' and 'inner-rel', if any exists
+ *
* Returns the new join relation node.
*/
-static Rel *
-init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo)
+static Rel *
+init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo)
{
- Rel *joinrel = makeNode(Rel);
- List *joinrel_joininfo_list = NIL;
- List *new_outer_tlist;
- List *new_inner_tlist;
-
- /*
- * Create a new tlist by removing irrelevant elements from both
- * tlists of the outer and inner join relations and then merging
- * the results together.
- */
- new_outer_tlist =
- new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
- inner_rel->relids, 1);
- new_inner_tlist =
- new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
- outer_rel->relids,
- length(new_outer_tlist) + 1);
-
- joinrel->relids = NIL;
- joinrel->indexed = false;
- joinrel->pages = 0;
- joinrel->tuples = 0;
- joinrel->width = 0;
-/* joinrel->targetlist = NIL;*/
- joinrel->pathlist = NIL;
- joinrel->unorderedpath = (Path *)NULL;
- joinrel->cheapestpath = (Path *)NULL;
- joinrel->pruneable = true;
- joinrel->classlist = NULL;
- joinrel->relam = InvalidOid;
- joinrel->ordering = NULL;
- joinrel->clauseinfo = NIL;
- joinrel->joininfo = NULL;
- joinrel->innerjoin = NIL;
- joinrel->superrels = NIL;
-
- joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists? -ay */
- lcons(inner_rel->relids, NIL));
-
- new_outer_tlist = nconc(new_outer_tlist,new_inner_tlist);
- joinrel->targetlist = new_outer_tlist;
-
- if (joininfo) {
- joinrel->clauseinfo = joininfo->jinfoclauseinfo;
- if (BushyPlanFlag)
- joininfo->inactive = true;
- }
-
- joinrel_joininfo_list =
- new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
- intAppend(outer_rel->relids, inner_rel->relids));
-
- joinrel->joininfo = joinrel_joininfo_list;
-
- set_joinrel_size(joinrel, outer_rel, inner_rel, joininfo);
-
- return(joinrel);
+ Rel *joinrel = makeNode(Rel);
+ List *joinrel_joininfo_list = NIL;
+ List *new_outer_tlist;
+ List *new_inner_tlist;
+
+ /*
+ * Create a new tlist by removing irrelevant elements from both tlists
+ * of the outer and inner join relations and then merging the results
+ * together.
+ */
+ new_outer_tlist =
+ new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
+ inner_rel->relids, 1);
+ new_inner_tlist =
+ new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
+ outer_rel->relids,
+ length(new_outer_tlist) + 1);
+
+ joinrel->relids = NIL;
+ joinrel->indexed = false;
+ joinrel->pages = 0;
+ joinrel->tuples = 0;
+ joinrel->width = 0;
+/* joinrel->targetlist = NIL;*/
+ joinrel->pathlist = NIL;
+ joinrel->unorderedpath = (Path *) NULL;
+ joinrel->cheapestpath = (Path *) NULL;
+ joinrel->pruneable = true;
+ joinrel->classlist = NULL;
+ joinrel->relam = InvalidOid;
+ joinrel->ordering = NULL;
+ joinrel->clauseinfo = NIL;
+ joinrel->joininfo = NULL;
+ joinrel->innerjoin = NIL;
+ joinrel->superrels = NIL;
+
+ joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists?
+ * -ay */
+ lcons(inner_rel->relids, NIL));
+
+ new_outer_tlist = nconc(new_outer_tlist, new_inner_tlist);
+ joinrel->targetlist = new_outer_tlist;
+
+ if (joininfo)
+ {
+ joinrel->clauseinfo = joininfo->jinfoclauseinfo;
+ if (BushyPlanFlag)
+ joininfo->inactive = true;
+ }
+
+ joinrel_joininfo_list =
+ new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
+ intAppend(outer_rel->relids, inner_rel->relids));
+
+ joinrel->joininfo = joinrel_joininfo_list;
+
+ set_joinrel_size(joinrel, outer_rel, inner_rel, joininfo);
+
+ return (joinrel);
}
-/*
+/*
* new-join-tlist--
- * Builds a join relations's target list by keeping those elements that
- * will be in the final target list and any other elements that are still
- * needed for future joins. For a target list entry to still be needed
- * for future joins, its 'joinlist' field must not be empty after removal
- * of all relids in 'other-relids'.
- *
+ * Builds a join relations's target list by keeping those elements that
+ * will be in the final target list and any other elements that are still
+ * needed for future joins. For a target list entry to still be needed
+ * for future joins, its 'joinlist' field must not be empty after removal
+ * of all relids in 'other-relids'.
+ *
* 'tlist' is the target list of one of the join relations
* 'other-relids' is a list of relids contained within the other
- * join relation
+ * join relation
* 'first-resdomno' is the resdom number to use for the first created
- * target list entry
- *
+ * target list entry
+ *
* Returns the new target list.
*/
-static List *
-new_join_tlist(List *tlist,
- List *other_relids,
- int first_resdomno)
+static List *
+new_join_tlist(List * tlist,
+ List * other_relids,
+ int first_resdomno)
{
- int resdomno = first_resdomno - 1;
- TargetEntry *xtl = NULL;
- List *temp_node = NIL;
- List *t_list = NIL;
- List *i = NIL;
- List *join_list = NIL;
- bool in_final_tlist =false;
-
-
- foreach(i,tlist) {
- xtl= lfirst(i);
- in_final_tlist = (join_list==NIL);
- if( in_final_tlist) {
- resdomno += 1;
- temp_node =
- lcons(create_tl_element(get_expr(xtl),
- resdomno),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ int resdomno = first_resdomno - 1;
+ TargetEntry *xtl = NULL;
+ List *temp_node = NIL;
+ List *t_list = NIL;
+ List *i = NIL;
+ List *join_list = NIL;
+ bool in_final_tlist = false;
+
+
+ foreach(i, tlist)
+ {
+ xtl = lfirst(i);
+ in_final_tlist = (join_list == NIL);
+ if (in_final_tlist)
+ {
+ resdomno += 1;
+ temp_node =
+ lcons(create_tl_element(get_expr(xtl),
+ resdomno),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* new-joininfo-list--
- * Builds a join relation's joininfo list by checking for join clauses
- * which still need to used in future joins involving this relation. A
- * join clause is still needed if there are still relations in the clause
- * not contained in the list of relations comprising this join relation.
- * New joininfo nodes are only created and added to
- * 'current-joininfo-list' if a node for a particular join hasn't already
- * been created.
+ * Builds a join relation's joininfo list by checking for join clauses
+ * which still need to used in future joins involving this relation. A
+ * join clause is still needed if there are still relations in the clause
+ * not contained in the list of relations comprising this join relation.
+ * New joininfo nodes are only created and added to
+ * 'current-joininfo-list' if a node for a particular join hasn't already
+ * been created.
*
- * 'current-joininfo-list' contains a list of those joininfo nodes that
- * have already been built
+ * 'current-joininfo-list' contains a list of those joininfo nodes that
+ * have already been built
* 'joininfo-list' is the list of join clauses involving this relation
- * 'join-relids' is a list of relids corresponding to the relations
- * currently being joined
- *
+ * 'join-relids' is a list of relids corresponding to the relations
+ * currently being joined
+ *
* Returns a list of joininfo nodes, new and old.
*/
-static List *
-new_joininfo_list(List *joininfo_list, List *join_relids)
+static List *
+new_joininfo_list(List * joininfo_list, List * join_relids)
{
- List *current_joininfo_list = NIL;
- List *new_otherrels = NIL;
- JInfo *other_joininfo = (JInfo*)NULL;
- List *xjoininfo = NIL;
-
- foreach (xjoininfo, joininfo_list) {
- List *or;
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- new_otherrels = joininfo->otherrels;
- foreach (or, new_otherrels)
- {
- if ( intMember (lfirsti(or), join_relids) )
- new_otherrels = lremove ((void*)lfirst(or), new_otherrels);
- }
- joininfo->otherrels = new_otherrels;
- if ( new_otherrels != NIL )
+ List *current_joininfo_list = NIL;
+ List *new_otherrels = NIL;
+ JInfo *other_joininfo = (JInfo *) NULL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoininfo, joininfo_list)
{
- other_joininfo = joininfo_member(new_otherrels,
- current_joininfo_list);
- if(other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(joininfo->jinfoclauseinfo,
- other_joininfo->jinfoclauseinfo);
- }else {
- other_joininfo = makeNode(JInfo);
-
- other_joininfo->otherrels =
- joininfo->otherrels;
- other_joininfo->jinfoclauseinfo =
- joininfo->jinfoclauseinfo;
- other_joininfo->mergesortable =
- joininfo->mergesortable;
- other_joininfo->hashjoinable =
- joininfo->hashjoinable;
- other_joininfo->inactive = false;
-
- current_joininfo_list = lcons(other_joininfo,
- current_joininfo_list);
- }
+ List *or;
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ new_otherrels = joininfo->otherrels;
+ foreach(or, new_otherrels)
+ {
+ if (intMember(lfirsti(or), join_relids))
+ new_otherrels = lremove((void *) lfirst(or), new_otherrels);
+ }
+ joininfo->otherrels = new_otherrels;
+ if (new_otherrels != NIL)
+ {
+ other_joininfo = joininfo_member(new_otherrels,
+ current_joininfo_list);
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(joininfo->jinfoclauseinfo,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ other_joininfo = makeNode(JInfo);
+
+ other_joininfo->otherrels =
+ joininfo->otherrels;
+ other_joininfo->jinfoclauseinfo =
+ joininfo->jinfoclauseinfo;
+ other_joininfo->mergesortable =
+ joininfo->mergesortable;
+ other_joininfo->hashjoinable =
+ joininfo->hashjoinable;
+ other_joininfo->inactive = false;
+
+ current_joininfo_list = lcons(other_joininfo,
+ current_joininfo_list);
+ }
+ }
}
- }
- return(current_joininfo_list);
+ return (current_joininfo_list);
}
/*
* add-new-joininfos--
- * For each new join relation, create new joininfos that
- * use the join relation as inner relation, and add
- * the new joininfos to those rel nodes that still
- * have joins with the join relation.
+ * For each new join relation, create new joininfos that
+ * use the join relation as inner relation, and add
+ * the new joininfos to those rel nodes that still
+ * have joins with the join relation.
*
* 'joinrels' is a list of join relations.
*
* Modifies the joininfo field of appropriate rel nodes.
*/
void
-add_new_joininfos(Query *root, List *joinrels, List *outerrels)
+add_new_joininfos(Query * root, List * joinrels, List * outerrels)
{
- List *xjoinrel = NIL;
- List *xrelid = NIL;
- List *xrel = NIL;
- List *xjoininfo = NIL;
-
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
- foreach(xrelid, joinrel->relids) {
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- add_superrels(rel,joinrel);
+ List *xjoinrel = NIL;
+ List *xrelid = NIL;
+ List *xrel = NIL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xrelid, joinrel->relids)
+ {
+ Relid relid = (Relid) lfirst(xrelid);
+ Rel *rel = get_join_rel(root, relid);
+
+ add_superrels(rel, joinrel);
+ }
}
- }
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
-
- foreach(xjoininfo, joinrel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
- List *other_rels = joininfo->otherrels;
- List *clause_info = joininfo->jinfoclauseinfo;
- bool mergesortable = joininfo->mergesortable;
- bool hashjoinable = joininfo->hashjoinable;
-
- foreach(xrelid, other_rels) {
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- List *super_rels = rel->superrels;
- List *xsuper_rel = NIL;
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = joinrel->relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- rel->joininfo =
- lappend(rel->joininfo, new_joininfo);
-
- foreach(xsuper_rel, super_rels) {
- Rel *super_rel = (Rel *)lfirst(xsuper_rel);
-
- if( nonoverlap_rels(super_rel,joinrel) ) {
- List *new_relids = super_rel->relids;
- JInfo *other_joininfo =
- joininfo_member(new_relids,
- joinrel->joininfo);
-
- if (other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(clause_info,
- other_joininfo->jinfoclauseinfo);
- } else {
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = new_relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- joinrel->joininfo =
- lappend(joinrel->joininfo,
- new_joininfo);
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xjoininfo, joinrel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+ List *other_rels = joininfo->otherrels;
+ List *clause_info = joininfo->jinfoclauseinfo;
+ bool mergesortable = joininfo->mergesortable;
+ bool hashjoinable = joininfo->hashjoinable;
+
+ foreach(xrelid, other_rels)
+ {
+ Relid relid = (Relid) lfirst(xrelid);
+ Rel *rel = get_join_rel(root, relid);
+ List *super_rels = rel->superrels;
+ List *xsuper_rel = NIL;
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = joinrel->relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ rel->joininfo =
+ lappend(rel->joininfo, new_joininfo);
+
+ foreach(xsuper_rel, super_rels)
+ {
+ Rel *super_rel = (Rel *) lfirst(xsuper_rel);
+
+ if (nonoverlap_rels(super_rel, joinrel))
+ {
+ List *new_relids = super_rel->relids;
+ JInfo *other_joininfo =
+ joininfo_member(new_relids,
+ joinrel->joininfo);
+
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(clause_info,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = new_relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ joinrel->joininfo =
+ lappend(joinrel->joininfo,
+ new_joininfo);
+ }
+ }
+ }
}
- }
}
- }
}
- }
- foreach(xrel, outerrels) {
- Rel *rel = (Rel *)lfirst(xrel);
- rel->superrels = NIL;
- }
+ foreach(xrel, outerrels)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+
+ rel->superrels = NIL;
+ }
}
/*
* final-join-rels--
- * Find the join relation that includes all the original
- * relations, i.e. the final join result.
+ * Find the join relation that includes all the original
+ * relations, i.e. the final join result.
*
* 'join-rel-list' is a list of join relations.
*
* Returns the list of final join relations.
*/
-List *
-final_join_rels(List *join_rel_list)
+List *
+final_join_rels(List * join_rel_list)
{
- List *xrel = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- /*
- * find the relations that has no further joins,
- * i.e., its joininfos all have otherrels nil.
- */
- foreach(xrel,join_rel_list) {
- Rel *rel = (Rel *)lfirst(xrel);
- List *xjoininfo = NIL;
- bool final = true;
-
- foreach (xjoininfo, rel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- if (joininfo->otherrels != NIL) {
- final = false;
- break;
- }
- }
- if (final) {
- temp = lcons(rel, NIL);
- t_list = nconc(t_list, temp);
+ List *xrel = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ /*
+ * find the relations that has no further joins, i.e., its joininfos
+ * all have otherrels nil.
+ */
+ foreach(xrel, join_rel_list)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+ List *xjoininfo = NIL;
+ bool final = true;
+
+ foreach(xjoininfo, rel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ if (joininfo->otherrels != NIL)
+ {
+ final = false;
+ break;
+ }
+ }
+ if (final)
+ {
+ temp = lcons(rel, NIL);
+ t_list = nconc(t_list, temp);
+ }
}
- }
- return(t_list);
+ return (t_list);
}
/*
* add_superrels--
- * add rel to the temporary property list superrels.
+ * add rel to the temporary property list superrels.
*
* 'rel' a rel node
* 'super-rel' rel node of a join relation that includes rel
@@ -492,60 +533,69 @@ final_join_rels(List *join_rel_list)
* Modifies the superrels field of rel
*/
static void
-add_superrels(Rel *rel, Rel *super_rel)
+add_superrels(Rel * rel, Rel * super_rel)
{
- rel->superrels = lappend(rel->superrels, super_rel);
+ rel->superrels = lappend(rel->superrels, super_rel);
}
/*
* nonoverlap-rels--
- * test if two join relations overlap, i.e., includes the same
- * relation.
+ * test if two join relations overlap, i.e., includes the same
+ * relation.
*
* 'rel1' and 'rel2' are two join relations
*
* Returns non-nil if rel1 and rel2 do not overlap.
*/
-static bool
-nonoverlap_rels(Rel *rel1, Rel *rel2)
+static bool
+nonoverlap_rels(Rel * rel1, Rel * rel2)
{
- return(nonoverlap_sets(rel1->relids, rel2->relids));
+ return (nonoverlap_sets(rel1->relids, rel2->relids));
}
-static bool
-nonoverlap_sets(List *s1, List *s2)
+static bool
+nonoverlap_sets(List * s1, List * s2)
{
- List *x = NIL;
-
- foreach(x,s1) {
- int e = lfirsti(x);
- if(intMember(e,s2))
- return(false);
- }
- return(true);
+ List *x = NIL;
+
+ foreach(x, s1)
+ {
+ int e = lfirsti(x);
+
+ if (intMember(e, s2))
+ return (false);
+ }
+ return (true);
}
static void
-set_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel, JInfo *jinfo)
+set_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel, JInfo * jinfo)
{
- int ntuples;
- float selec;
-
- /* voodoo magic. but better than a size of 0. I have no idea why
- we didn't set the size before. -ay 2/95 */
- if (jinfo==NULL) {
- /* worst case: the cartesian product */
- ntuples = outer_rel->tuples * inner_rel->tuples;
- } else {
- selec = product_selec(jinfo->jinfoclauseinfo);
-/* ntuples = Min(outer_rel->tuples,inner_rel->tuples) * selec; */
- ntuples = outer_rel->tuples * inner_rel->tuples * selec;
- }
-
- /* I bet sizes less than 1 will screw up optimization so
- make the best case 1 instead of 0 - jolly*/
- if (ntuples < 1)
- ntuples = 1;
-
- joinrel->tuples = ntuples;
+ int ntuples;
+ float selec;
+
+ /*
+ * voodoo magic. but better than a size of 0. I have no idea why we
+ * didn't set the size before. -ay 2/95
+ */
+ if (jinfo == NULL)
+ {
+ /* worst case: the cartesian product */
+ ntuples = outer_rel->tuples * inner_rel->tuples;
+ }
+ else
+ {
+ selec = product_selec(jinfo->jinfoclauseinfo);
+/* ntuples = Min(outer_rel->tuples,inner_rel->tuples) * selec; */
+ ntuples = outer_rel->tuples * inner_rel->tuples * selec;
+ }
+
+ /*
+ * I bet sizes less than 1 will screw up optimization so make the best
+ * case 1 instead of 0 - jolly
+ */
+ if (ntuples < 1)
+ ntuples = 1;
+
+ joinrel->tuples = ntuples;
}