Author: loleary
Date: 2009-06-27 01:22:45 -0400 (Sat, 27 Jun 2009)
New Revision: 1089
Added:
trunk/engine/src/test/java/com/metamatrix/query/sql/lang/TestJoinPredicate.java
Modified:
trunk/engine/src/main/java/com/metamatrix/query/sql/lang/JoinPredicate.java
trunk/engine/src/test/java/com/metamatrix/query/parser/TestParser.java
Log:
TEIID-695: Equality comparison of JoinPredicate returns true even when JoinPredicate
criteria is different
Fixed JoinPredicate.equals(Object) method to compare its own criteria to the Object's
criteria instead of comparing its own criteria to itself.
Added TestJoinPredicate UnitTest to cover equality checks on JoinPredicate object.
Fixed TestParser to build JoinPredicate in the same manner that the Parser is building it
during parsing of a query which contains JoinPredicate.
Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/lang/JoinPredicate.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/lang/JoinPredicate.java 2009-06-26
22:06:04 UTC (rev 1088)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/lang/JoinPredicate.java 2009-06-27
05:22:45 UTC (rev 1089)
@@ -194,7 +194,7 @@
if(thisCrit != null && thisCrit.size() == 0) {
thisCrit = null;
}
- List otherCrit = this.getJoinCriteria();
+ List otherCrit = other.getJoinCriteria();
if(otherCrit != null && otherCrit.size() == 0) {
otherCrit = null;
}
Modified: trunk/engine/src/test/java/com/metamatrix/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/parser/TestParser.java 2009-06-26
22:06:04 UTC (rev 1088)
+++ trunk/engine/src/test/java/com/metamatrix/query/parser/TestParser.java 2009-06-27
05:22:45 UTC (rev 1089)
@@ -6231,13 +6231,10 @@
Select s = new Select();
s.addSymbol(new AllSymbol());
From f = new From();
- JoinPredicate jp = new JoinPredicate(new UnaryFromClause(new
GroupSymbol("m.g1")), new UnaryFromClause(new GroupSymbol("m.g2")),
JoinType.JOIN_INNER); //$NON-NLS-1$ //$NON-NLS-2$
CompareCriteria c1 = new CompareCriteria(new ElementSymbol("e1"),
CompareCriteria.EQ, new Constant(new Integer(0))); //$NON-NLS-1$
CompoundCriteria cc1 = new CompoundCriteria(CompoundCriteria.AND, c1, predCrit);
- List crits = new ArrayList();
- crits.add(cc1);
- jp.setJoinCriteria(crits);
+ JoinPredicate jp = new JoinPredicate(new UnaryFromClause(new
GroupSymbol("m.g1")), new UnaryFromClause(new GroupSymbol("m.g2")),
JoinType.JOIN_INNER, cc1); //$NON-NLS-1$ //$NON-NLS-2$
f.addClause(jp);
Query q = new Query();
@@ -6245,14 +6242,14 @@
q.setFrom(f);
helpTest("SELECT * FROM m.g1 JOIN m.g2 ON e1=0 AND " + sqlPred,
//$NON-NLS-1$
- "SELECT * FROM m.g1 INNER JOIN m.g2 ON e1 = 0 AND " + sqlPred, q);
//$NON-NLS-1$
+ "SELECT * FROM m.g1 INNER JOIN m.g2 ON e1 = 0 AND " + sqlPred, q);
//$NON-NLS-1$
}
public void testCompoundNonJoinCriteriaInFromWithComparisonCriteria() {
CompareCriteria c2 = new CompareCriteria(new ElementSymbol("e2"),
CompareCriteria.EQ, new Constant(new Integer(1))); //$NON-NLS-1$
- helpTestCompoundNonJoinCriteria("e2 IS NULL", c2); //$NON-NLS-1$
+ helpTestCompoundNonJoinCriteria("e2 = 1", c2); //$NON-NLS-1$
}
public void testCompoundNonJoinCriteriaInFromWithIsNull() {
Added: trunk/engine/src/test/java/com/metamatrix/query/sql/lang/TestJoinPredicate.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/sql/lang/TestJoinPredicate.java
(rev 0)
+++
trunk/engine/src/test/java/com/metamatrix/query/sql/lang/TestJoinPredicate.java 2009-06-27
05:22:45 UTC (rev 1089)
@@ -0,0 +1,347 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package com.metamatrix.query.sql.lang;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.*;
+import com.metamatrix.core.util.UnitTestUtil;
+import com.metamatrix.query.sql.symbol.*;
+
+/**
+ * Test the <code>JoinPredicate</code> implementation to verify it is
producing
+ * expected <code>JoinPredicate</code> objects.
+ */
+public class TestJoinPredicate extends TestCase {
+
+ // ################################## FRAMEWORK ################################
+
+ public TestJoinPredicate(String name) {
+ super(name);
+ }
+
+ // ################################## TEST HELPERS ################################
+
+ /**
+ * Constructs an example <code>JoinPredicate</code> object that can be used
+ * as join predicate in a query.
+ *
+ * @param joinType the type of join to be constructed
+ * @param joinOnElement the element name to be used in the left and right
+ * side criteria of the ON expression of the join
+ * @return a join predicate object
+ */
+ public static JoinPredicate example(JoinType joinType, String joinOnElement) {
+ JoinPredicate jp = new JoinPredicate();
+
+ GroupSymbol g1 = new GroupSymbol("m.g1"); //$NON-NLS-1$
+ GroupSymbol g2 = new GroupSymbol("m.g2"); //$NON-NLS-1$
+ FromClause lc = new UnaryFromClause(g1);
+ FromClause rc = new UnaryFromClause(g2);
+
+ Expression le = new ElementSymbol("m.g1." + joinOnElement); //$NON-NLS-1$
+ Expression re = new ElementSymbol("m.g2." + joinOnElement); //$NON-NLS-1$
+ Criteria c1 = new CompareCriteria(le, CompareCriteria.EQ, re);
+
+ jp.setLeftClause(lc);
+ jp.setRightClause(rc);
+ jp.setJoinType(joinType != null ? joinType : JoinType.JOIN_LEFT_OUTER);
+ jp.setJoinCriteria( Arrays.asList(new Object[]{c1}));
+
+ return jp;
+ }
+
+ /**
+ * Constructs an example <code>JoinPredicate</code> object that contains
+ * compound criteria in the join's ON expression. The resulting object
+ * could be used as join predicate in a query.
+ * <p>
+ * This method calls <code>example(joinType, joinOnElement)</code> to
+ * construct the initial join predicate object. The join criteria of
+ * the initial join predicate object is then modified to add the use
+ * of compound criteria which include the original criteria from the
+ * initial join predicate object and the newly constructed criteria
+ * specified from the <code>andJoinOnElement</code> string.
+ *
+ * @param joinType the type of join to be constructed
+ * @param joinOnElement the element name to be used in the left and right
+ * side criteria of the ON expression of the join
+ * @param andJoinOnElement the element name to be used in the left and right
+ * side criteria of the right hand expression of AND
+ * criteria of the ON expression of the join
+ * @return a join predicate object
+ */
+ public static JoinPredicate example(JoinType joinType, String joinOnElement, String
andJoinOnElement) {
+ JoinPredicate jp = example(joinType, joinOnElement);
+ List<Criteria> joinCrits = jp.getJoinCriteria();
+ List<Object> newJoinCrits = new ArrayList<Object>(1);
+
+ Expression le = new ElementSymbol("m.g1." + andJoinOnElement); //$NON-NLS-1$
+ Expression re = new ElementSymbol("m.g2." + andJoinOnElement); //$NON-NLS-1$
+ Criteria c1 = new CompareCriteria(le, CompareCriteria.EQ, re);
+
+ Iterator<Criteria> ci = joinCrits.iterator();
+
+ if (!ci.hasNext()) {
+ newJoinCrits.add(c1);
+ }
+
+ while (ci.hasNext()) {
+ Criteria crit = ci.next();
+ if ( ci.hasNext() ) newJoinCrits.add(crit);
+ else {
+ Criteria compundCrit = new CompoundCriteria(CompoundCriteria.AND, crit, c1);
+ newJoinCrits.add(compundCrit);
+ }
+ }
+
+ jp.setJoinCriteria(newJoinCrits);
+
+ return jp;
+ }
+
+ // ################################## ACTUAL TESTS ################################
+
+ /**
+ * Test <code>equals()</code> method of
<code>JoinPredicate</code> to
+ * verify it properly evaluates the equality of two
<code>JoinPredicate</code>
+ * objects.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * that were constructed with the same join type and with the same criteria
+ * evaluate as equal.
+ * <p>
+ * For example:
+ * ... m.g1 LEFT OUTER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ */
+ public void testEquals1() {
+ JoinPredicate jp1 = example(JoinType.JOIN_LEFT_OUTER, "e1"); //$NON-NLS-1$
+ JoinPredicate jp2 = example(JoinType.JOIN_LEFT_OUTER, "e1"); //$NON-NLS-1$
+ assertTrue("Equivalent join predicate don't compare as equal: " + jp1 +
", " + jp2, jp1.equals(jp2)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test <code>equals()</code> method of
<code>JoinPredicate</code> to
+ * verify it properly evaluates the equality of two
+ * <code>JoinPredicate</code> objects.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * that were constructed with the same join type and with the same
+ * compound criteria evaluate as equal.
+ * <p>
+ * For example:
+ * ... m.g1 LEFT OUTER JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ */
+ public void testEquals2() {
+ JoinPredicate jp1 = example(JoinType.JOIN_LEFT_OUTER, "e1", "e2");
//$NON-NLS-1$ //$NON-NLS-2$
+ JoinPredicate jp2 = example(JoinType.JOIN_LEFT_OUTER, "e1",
"e2"); //$NON-NLS-1$ //$NON-NLS-2$
+ assertTrue("Equivalent join predicate don't compare as equal: " + jp1 +
", " + jp2, jp1.equals(jp2)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test <code>equals()</code> method of
<code>JoinPredicate</code> to
+ * verify it properly evaluates the equality of two
<code>JoinPredicate</code>
+ * objects.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * that were constructed with different join types but with the same
+ * compound criteria evaluate as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 LEFT OUTER JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ * ... m.g1 RIGHT OUTER JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ */
+ public void testEquals3() {
+ JoinPredicate jp1 = example(JoinType.JOIN_LEFT_OUTER, "e1", "e2");
//$NON-NLS-1$ //$NON-NLS-2$
+ JoinPredicate jp2 = example(JoinType.JOIN_RIGHT_OUTER, "e1",
"e2"); //$NON-NLS-1$ //$NON-NLS-2$
+ assertTrue("Different join predicate compare as equal: " + jp1 + ",
" + jp2, !jp1.equals(jp2)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test <code>equals()</code> method of
<code>JoinPredicate</code> to
+ * verify it properly evaluates the equality of two
<code>JoinPredicate</code>
+ * objects.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * that were constructed with the same join type but with different
+ * criteria evaluate as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 INNER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ * ... m.g1 INNER JOIN m.g2 ON m.g1.e2 = m.g2.e2
+ */
+ public void testEquals4() {
+ JoinPredicate jp1 = example(JoinType.JOIN_INNER, "e1"); //$NON-NLS-1$
+ JoinPredicate jp2 = example(JoinType.JOIN_INNER, "e2"); //$NON-NLS-1$
+ assertTrue("Different join predicate compare as equal: " + jp1 + ",
" + jp2, !jp1.equals(jp2)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test <code>equals()</code> method of
<code>JoinPredicate</code> to
+ * verify it properly evaluates the equality of two
<code>JoinPredicate</code>
+ * objects.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * that were constructed with the same join type but with different
+ * compound criteria evaluate as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 CROSS JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ * ... m.g1 CROSS JOIN m.g2 ON ((m.g1.e2 = m.g2.e2) AND (m.g1.e2 = m.g2.e2))
+ */
+ public void testEquals5() {
+ JoinPredicate jp1 = example(JoinType.JOIN_CROSS, "e1", "e2");
//$NON-NLS-1$ //$NON-NLS-2$
+ JoinPredicate jp2 = example(JoinType.JOIN_CROSS, "e2", "e2");
//$NON-NLS-1$ //$NON-NLS-2$
+ assertTrue("Different join predicate compare as equal: " + jp1 + ",
" + jp2, !jp1.equals(jp2)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that the same <code>JoinPredicate</code> object
+ * evaluates as equal when it is compared to itself.
+ * <p>
+ * For example:
+ * ... m.g1 FULL OUTER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ */
+ public void testSelfEquivalence(){
+ JoinPredicate jp1 = example(JoinType.JOIN_FULL_OUTER, "e1"); //$NON-NLS-1$
+ int equals = 0;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp1);
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * constructed with the same join type and the same criteria evaluates as
+ * equal.
+ * <p>
+ * For example:
+ * ... m.g1 FULL OUTER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ * ... m.g1 FULL OUTER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ */
+ public void testEquivalence(){
+ JoinPredicate jp1 = example(JoinType.JOIN_FULL_OUTER, "e1"); //$NON-NLS-1$
+ JoinPredicate jp2 = example(JoinType.JOIN_FULL_OUTER, "e1"); //$NON-NLS-1$
+ int equals = 0;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp2);
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that a <code>JoinPredicate</code> object's clone
+ * evaluate as equal when compared to the original object.
+ * <p>
+ * For example:
+ * ... m.g1 UNION JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ */
+ public void testCloneEquivalence(){
+ JoinPredicate jp1 = example(JoinType.JOIN_UNION, "e1"); //$NON-NLS-1$
+ JoinPredicate jp2 = (JoinPredicate)jp1.clone();
+ int equals = 0;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp2);
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * constructed with the same join type but with different criteria evaluate
+ * as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 FULL OUTER JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ * ... m.g1 FULL OUTER JOIN m.g2 ON m.g1.e400 = m.g2.e400
+ */
+ public void testNonEquivalence1(){
+ JoinPredicate jp1 = example(JoinType.JOIN_FULL_OUTER, "e1",
"e2"); //$NON-NLS-1$ //$NON-NLS-2$
+ JoinPredicate jp2 = example(JoinType.JOIN_FULL_OUTER, "e400");
//$NON-NLS-1$
+ int equals = -1;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp2);
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * constructed with the same join type but with different criteria evaluate
+ * as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 FULL OUTER JOIN m.g2 ON ((m.g1.e1 = m.g2.e1) AND (m.g1.e2 = m.g2.e2))
+ * ... m.g1 FULL OUTER JOIN m.g2 ON ((m.g1.e2 = m.g2.e2) AND (m.g1.e1 = m.g2.e1))
+ */
+ public void testNonEquivalence2(){
+ JoinPredicate jp1 = example(JoinType.JOIN_LEFT_OUTER, "e1",
"e2"); //$NON-NLS-1$ //$NON-NLS-2$
+ JoinPredicate jp2 = example(JoinType.JOIN_LEFT_OUTER, "e2",
"e1"); //$NON-NLS-1$ //$NON-NLS-2$
+ int equals = -1;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp2);
+ }
+
+ /**
+ * Test a <code>JoinPredicate</code> object using
<code>UnitTestUtil.helpTestEquivalence</code>.
+ * <p>
+ * This test ensures that two different <code>JoinPredicate</code> objects
+ * constructed with different join types but with the same criteria evaluate
+ * as not equal.
+ * <p>
+ * For example:
+ * ... m.g1 LEFT OUTER JOIN m.g2 ON m.g1.e1 = m.g2.e1
+ * ... m.g1 RIGHT OUTER JOIN m.g2 ON m.g1.e2 = m.g2.e2
+ */
+ public void testNonEquivalence3(){
+ JoinPredicate jp1 = example(JoinType.JOIN_LEFT_OUTER, "e1");
//$NON-NLS-1$
+ JoinPredicate jp2 = example(JoinType.JOIN_RIGHT_OUTER, "e1");
//$NON-NLS-1$
+ int equals = -1;
+ UnitTestUtil.helpTestEquivalence(equals, jp1, jp2);
+ }
+
+
+ // ################################## TEST SUITE ################################
+
+
+ /**
+ * This suite of all tests could be defined in another class but it seems easier to
+ * maintain it here.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("TestJoinPredicate"); //$NON-NLS-1$
+ suite.addTestSuite(TestJoinPredicate.class);
+ return suite;
+ }
+
+ // ################################## MAIN ################################
+
+ /**
+ * This is a handy main that will run the suite defined in this class. It has no code
specific
+ * to this class and can be copied into any class that has a method "public static
Test suite()".
+ */
+ public static void main(String arg[]) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+}
Property changes on:
trunk/engine/src/test/java/com/metamatrix/query/sql/lang/TestJoinPredicate.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain