aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/initsplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/initsplan.c')
-rw-r--r--src/backend/optimizer/plan/initsplan.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index e06282c1265..e43c52f6dfe 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.75 2002/09/04 20:31:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.76 2002/11/19 23:21:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -785,6 +785,71 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
}
/*
+ * vars_known_equal
+ * Detect whether two Vars are known equal due to equijoin clauses.
+ *
+ * This is not completely accurate since we avoid adding redundant restriction
+ * clauses to individual base rels (see qual_is_redundant). However, after
+ * the implied-equality-deduction phase, it is complete for Vars of different
+ * rels; that's sufficient for planned uses.
+ */
+bool
+vars_known_equal(Query *root, Var *var1, Var *var2)
+{
+ Index irel1;
+ Index irel2;
+ RelOptInfo *rel1;
+ List *restrictlist;
+ List *itm;
+
+ /*
+ * Would need more work here if we wanted to check for known equality
+ * of general clauses: there might be multiple base rels involved.
+ */
+ Assert(IsA(var1, Var));
+ irel1 = var1->varno;
+ Assert(IsA(var2, Var));
+ irel2 = var2->varno;
+
+ /*
+ * If both vars belong to same rel, we need to look at that rel's
+ * baserestrictinfo list. If different rels, each will have a
+ * joininfo node for the other, and we can scan either list.
+ */
+ rel1 = find_base_rel(root, irel1);
+ if (irel1 == irel2)
+ restrictlist = rel1->baserestrictinfo;
+ else
+ {
+ JoinInfo *joininfo = find_joininfo_node(rel1,
+ makeListi1(irel2));
+
+ restrictlist = joininfo->jinfo_restrictinfo;
+ }
+
+ /*
+ * Scan to see if equality is known.
+ */
+ foreach(itm, restrictlist)
+ {
+ RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(itm);
+ Node *left,
+ *right;
+
+ if (restrictinfo->mergejoinoperator == InvalidOid)
+ continue; /* ignore non-mergejoinable clauses */
+ /* We now know the restrictinfo clause is a binary opclause */
+ left = (Node *) get_leftop(restrictinfo->clause);
+ right = (Node *) get_rightop(restrictinfo->clause);
+ if ((equal(var1, left) && equal(var2, right)) ||
+ (equal(var2, left) && equal(var1, right)))
+ return true; /* found a matching clause */
+ }
+
+ return false;
+}
+
+/*
* qual_is_redundant
* Detect whether an implied-equality qual that turns out to be a
* restriction clause for a single base relation is redundant with