aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/joininfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/joininfo.c')
-rw-r--r--src/backend/optimizer/util/joininfo.c110
1 files changed, 109 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index c202615b1f5..79a9f7a3bac 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.32 2003/01/20 18:54:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.33 2003/01/24 03:58:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "optimizer/joininfo.h"
+#include "optimizer/pathnode.h"
/*
@@ -63,3 +64,110 @@ make_joininfo_node(RelOptInfo *this_rel, Relids join_relids)
}
return joininfo;
}
+
+
+/*
+ * add_join_clause_to_rels
+ * For every relation participating in a join clause, add 'restrictinfo' to
+ * the appropriate joininfo list (creating a new list and adding it to the
+ * appropriate rel node if necessary).
+ *
+ * Note that the same copy of the restrictinfo node is linked to by all the
+ * lists it is in. This allows us to exploit caching of information about
+ * the restriction clause (but we must be careful that the information does
+ * not depend on context).
+ *
+ * 'restrictinfo' describes the join clause
+ * 'join_relids' is the list of relations participating in the join clause
+ * (there must be more than one)
+ */
+void
+add_join_clause_to_rels(Query *root,
+ RestrictInfo *restrictinfo,
+ Relids join_relids)
+{
+ List *join_relid;
+
+ /* For every relid, find the joininfo, and add the proper join entries */
+ foreach(join_relid, join_relids)
+ {
+ int cur_relid = lfirsti(join_relid);
+ Relids unjoined_relids = NIL;
+ JoinInfo *joininfo;
+ List *otherrel;
+
+ /* Get the relids not equal to the current relid */
+ foreach(otherrel, join_relids)
+ {
+ if (lfirsti(otherrel) != cur_relid)
+ unjoined_relids = lappendi(unjoined_relids, lfirsti(otherrel));
+ }
+ Assert(unjoined_relids != NIL);
+
+ /*
+ * Find or make the joininfo node for this combination of rels,
+ * and add the restrictinfo node to it.
+ */
+ joininfo = make_joininfo_node(find_base_rel(root, cur_relid),
+ unjoined_relids);
+ joininfo->jinfo_restrictinfo = lappend(joininfo->jinfo_restrictinfo,
+ restrictinfo);
+ /*
+ * Can't freeList(unjoined_relids) because new joininfo node may
+ * link to it. We could avoid leaking memory by doing listCopy()
+ * in make_joininfo_node, but for now speed seems better.
+ */
+ }
+}
+
+/*
+ * remove_join_clause_from_rels
+ * Delete 'restrictinfo' from all the joininfo lists it is in
+ *
+ * This reverses the effect of add_join_clause_to_rels. It's used when we
+ * discover that a join clause is redundant.
+ *
+ * 'restrictinfo' describes the join clause
+ * 'join_relids' is the list of relations participating in the join clause
+ * (there must be more than one)
+ */
+void
+remove_join_clause_from_rels(Query *root,
+ RestrictInfo *restrictinfo,
+ Relids join_relids)
+{
+ List *join_relid;
+
+ /* For every relid, find the joininfo */
+ foreach(join_relid, join_relids)
+ {
+ int cur_relid = lfirsti(join_relid);
+ Relids unjoined_relids = NIL;
+ JoinInfo *joininfo;
+ List *otherrel;
+
+ /* Get the relids not equal to the current relid */
+ foreach(otherrel, join_relids)
+ {
+ if (lfirsti(otherrel) != cur_relid)
+ unjoined_relids = lappendi(unjoined_relids, lfirsti(otherrel));
+ }
+ Assert(unjoined_relids != NIL);
+
+ /*
+ * Find the joininfo node for this combination of rels; it should
+ * exist already, if add_join_clause_to_rels was called.
+ */
+ joininfo = find_joininfo_node(find_base_rel(root, cur_relid),
+ unjoined_relids);
+ Assert(joininfo);
+ /*
+ * Remove the restrictinfo from the list. Pointer comparison
+ * is sufficient.
+ */
+ Assert(ptrMember(restrictinfo, joininfo->jinfo_restrictinfo));
+ joininfo->jinfo_restrictinfo = lremove(restrictinfo,
+ joininfo->jinfo_restrictinfo);
+ freeList(unjoined_relids);
+ }
+}