/* * 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 org.teiid.query.sql.lang; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.teiid.core.util.UnitTestUtil; import org.teiid.query.sql.lang.CompareCriteria; import org.teiid.query.sql.lang.CompoundCriteria; import org.teiid.query.sql.lang.Criteria; import org.teiid.query.sql.lang.FromClause; import org.teiid.query.sql.lang.JoinPredicate; import org.teiid.query.sql.lang.JoinType; import org.teiid.query.sql.lang.UnaryFromClause; import org.teiid.query.sql.symbol.*; import junit.framework.*; /** * 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); } }