/* * The contents of this file are subject to the Open Software License * Version 3.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.opensource.org/licenses/osl-3.0.txt * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. */ package org.mulgara.store.tuples; // Third party packages import junit.framework.*; // JUnit import org.apache.log4j.Logger; // Log4J // Locally written packages import org.mulgara.query.Variable; import static org.mulgara.query.filter.value.Bool.TRUE; import static org.mulgara.store.tuples.Tuples.UNBOUND; /** * Test case for {@link LeftJoin}. This is the * <a href="http://www.w3.org/TR/rdf-sparql-query/#optionals">OPTIONAL</a> operation in SPARQL. * * @created 2008-04-08 * @author <a href="mailto:pgearon@users.sourceforge.net">Paula Gearon</a> * @copyright © 2008 <A href="http://www.topazproject.org/">The Topaz Project</A> * @licence <a href="{@docRoot}/../../LICENCE">Open Software License v3.0</a> */ public class LeftJoinUnitTest extends TestCase { /**Logger. */ @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(LeftJoinUnitTest.class); /** Test variable. */ final Variable x = new Variable("x"); /** Test variable. */ final Variable y = new Variable("y"); /** Test variable. */ final Variable z = new Variable("z"); /** Test variable. */ final Variable w = new Variable("w"); /** Test variable. */ final Variable u = new Variable("u"); /** Test variable. */ final Variable v = new Variable("v"); /** * Constructs a new test with the given name. * @param name the name of the test */ public LeftJoinUnitTest(String name) { super(name); } /** * Hook for test runner to obtain a test suite from. * * @return The test suite */ public static Test suite() { TestSuite testSuite = new TestSuite(); testSuite.addTest(new LeftJoinUnitTest("testNoCommonVars")); testSuite.addTest(new LeftJoinUnitTest("testOneIntersectingVar")); testSuite.addTest(new LeftJoinUnitTest("testIntersectingVars")); return testSuite; } /** * Default text runner. * @param args The command line arguments */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** * Create test instance. */ public void setUp() { } /** * The teardown method for JUnit */ public void tearDown() { // null implementation } // // Test cases // /** * Test {@link LeftJoin}. When passed two arguments without common * variables, an IllegalArgumentException should be thrown. * @throws Exception if query fails when it should have succeeded */ public void testNoCommonVars() throws Exception { Tuples lhs = TuplesFactory.newInstance().newTuples( new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4)); Tuples rhs = TuplesFactory.newInstance().newTuples( new MemoryTuples(z, 5).and(w, 6).or(z, 7).and(w, 8)); Tuples tuples = new LeftJoin(lhs, rhs, TRUE, null); tuples.beforeFirst(); assertTrue(tuples.next()); assertTrue(tuples.next()); assertFalse(tuples.next()); TuplesTestingUtil.closeTuples(new Tuples[] { lhs, rhs, tuples }); } /** * Test {@link LeftJoin}. When passed arguments with some common variables, * the result should be the first argument, plus any matching rows from the * second, or unbound in the columns from the RHS. * @throws Exception if query fails when it should have succeeded */ public void testOneIntersectingVar() throws Exception { String[] lvars = new String[] {"x", "y"}; String[] rvars = new String[] {"y", "z"}; LiteralTuples lhs = new LiteralTuples(lvars); lhs.appendTuple(new long[] {1, 2}); lhs.appendTuple(new long[] {3, 4}); lhs.appendTuple(new long[] {5, 6}); lhs.appendTuple(new long[] {7, 8}); lhs.appendTuple(new long[] {9, 10}); lhs.appendTuple(new long[] {11, 12}); lhs.appendTuple(new long[] {13, 14}); LiteralTuples rhs = new LiteralTuples(rvars); rhs.appendTuple(new long[] {4, 11}); rhs.appendTuple(new long[] {6, 12}); rhs.appendTuple(new long[] {12, 31}); rhs.appendTuple(new long[] {12, 32}); rhs.appendTuple(new long[] {15, 16}); Tuples actual = new LeftJoin(lhs, rhs, TRUE, null); // Tuples actual = TuplesOperations.sort(opt); // // // check the variables // Variable[] variables = opt.getVariables(); // assertEquals(3, variables.length); // assertEquals(x, variables[0]); // assertEquals(y, variables[1]); // assertEquals(z, variables[2]); Variable[] variables = actual.getVariables(); assertEquals(3, variables.length); assertEquals(x, variables[0]); assertEquals(y, variables[1]); assertEquals(z, variables[2]); // First, try a straightforward iteration through all rows actual.beforeFirst(); TuplesTestingUtil.testTuplesRow(actual, new long[] {1, 2, UNBOUND}); TuplesTestingUtil.testTuplesRow(actual, new long[] {3, 4, 11}); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 12}); TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 8, UNBOUND}); TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, UNBOUND}); TuplesTestingUtil.testTuplesRow(actual, new long[] {11, 12, 31}); TuplesTestingUtil.testTuplesRow(actual, new long[] {11, 12, 32}); TuplesTestingUtil.testTuplesRow(actual, new long[] {13, 14, UNBOUND}); assertTrue(!actual.next()); // Second, try prefix searches actual.beforeFirst(new long[] { 7 }, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 8, UNBOUND }); assertTrue(!actual.next()); // Third, try more prefix searches actual.beforeFirst(new long[] { 9, 10 }, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, UNBOUND }); assertTrue(!actual.next()); // Fourth, try a prefix search into the last column actual.beforeFirst(new long[] { 9, 10, UNBOUND }, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, UNBOUND }); assertTrue(!actual.next()); // Fifth, try a prefix search into the last column with a bound value actual.beforeFirst(new long[] { 5, 6, 12 }, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 12 }); assertTrue(!actual.next()); actual.close(); // Try joining in the opposite order (RHS to LHS) // first, re-order the lhs lvars = new String[] {"y", "x"}; lhs = new LiteralTuples(lvars); lhs.appendTuple(new long[] {2, 1}); lhs.appendTuple(new long[] {4, 3}); lhs.appendTuple(new long[] {6, 5}); lhs.appendTuple(new long[] {8, 7}); lhs.appendTuple(new long[] {10, 9}); lhs.appendTuple(new long[] {12, 11}); lhs.appendTuple(new long[] {14, 13}); actual = new LeftJoin(rhs, lhs, TRUE, null); variables = actual.getVariables(); assertEquals(3, variables.length); assertEquals(y, variables[0]); assertEquals(z, variables[1]); assertEquals(x, variables[2]); actual.beforeFirst(); TuplesTestingUtil.testTuplesRow(actual, new long[] {4, 11, 3}); TuplesTestingUtil.testTuplesRow(actual, new long[] {6, 12, 5}); TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 31, 11}); TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 32, 11}); TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 16, UNBOUND}); assertTrue(!actual.next()); TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs}); } /** * Test {@link LeftJoin}. When passed arguments with some common variables, * the result should be the first argument, regardless of matching rows from the second. * @throws Exception if query fails when it should have succeeded */ public void testIntersectingVars() throws Exception { // lhs intersect rhs = rhs String[] lvars = new String[] {"x", "y", "z"}; String[] rvars = new String[] {"y", "z"}; LiteralTuples lhs = new LiteralTuples(lvars); lhs.appendTuple(new long[] {1, 2, 3}); lhs.appendTuple(new long[] {4, 5, 6}); lhs.appendTuple(new long[] {7, 5, 6}); lhs.appendTuple(new long[] {9, 10, 11}); lhs.appendTuple(new long[] {12, 13, 14}); lhs.appendTuple(new long[] {15, 16, 17}); lhs.appendTuple(new long[] {15, 7, 14}); LiteralTuples rhs = new LiteralTuples(rvars); rhs.appendTuple(new long[] {5, 6}); rhs.appendTuple(new long[] {6, 14}); rhs.appendTuple(new long[] {7, 14}); rhs.appendTuple(new long[] {8, 9}); LeftJoin join = new LeftJoin(lhs, rhs, TRUE, null); Tuples actual = TuplesOperations.sort(join); // check the variables Variable[] variables = actual.getVariables(); assertEquals(3, variables.length); assertEquals(x, variables[0]); assertEquals(y, variables[1]); assertEquals(z, variables[2]); // First, try a straightforward iteration through all rows actual.beforeFirst(); TuplesTestingUtil.testTuplesRow(actual, new long[] {1, 2, 3}); TuplesTestingUtil.testTuplesRow(actual, new long[] {4, 5, 6}); TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 5, 6}); TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, 11}); TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 13, 14}); TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 7, 14}); TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 16, 17}); assertTrue(!actual.next()); assertEquals(actual.getRowCount(), 7); // Second, try prefix searches actual.beforeFirst(new long[] {9}, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, 11}); assertTrue(!actual.next()); // Third, try more prefix searches actual.beforeFirst(new long[] {12, 13}, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 13, 14}); assertTrue(!actual.next()); // Now test the end actual.beforeFirst(new long[] {15}, 0); TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 7, 14}); TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 16, 17}); assertTrue(!actual.next()); actual.close(); // variables: lhs intersect rhs = lhs // first, reorder the lhs lvars = new String[] {"y", "z", "x"}; lhs = new LiteralTuples(lvars); lhs.appendTuple(new long[] {2, 3, 1}); lhs.appendTuple(new long[] {5, 6, 4}); lhs.appendTuple(new long[] {5, 6, 7}); lhs.appendTuple(new long[] {10, 11, 9}); lhs.appendTuple(new long[] {13, 14, 12}); lhs.appendTuple(new long[] {16, 17, 15}); lhs.appendTuple(new long[] {7, 14, 15}); actual = TuplesOperations.sort(new LeftJoin(rhs, lhs, TRUE, null)); actual.beforeFirst(); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 4}); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 7}); TuplesTestingUtil.testTuplesRow(actual, new long[] {6, 14, UNBOUND}); TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 14, 15}); TuplesTestingUtil.testTuplesRow(actual, new long[] {8, 9, UNBOUND}); assertTrue(!actual.next()); TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs}); // variables: rhs intersect lhs != rhs != lhs rvars = new String[] {"y", "z", "a"}; rhs = new LiteralTuples(rvars); rhs.appendTuple(new long[] {5, 6, 3}); rhs.appendTuple(new long[] {6, 14, 1}); rhs.appendTuple(new long[] {7, 14, 2}); rhs.appendTuple(new long[] {8, 9, 11}); actual = TuplesOperations.sort(new LeftJoin(rhs, lhs, TRUE, null)); actual.beforeFirst(); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 3, 4}); TuplesTestingUtil.testTuplesRow(actual, new long[] {5, 6, 3, 7}); TuplesTestingUtil.testTuplesRow(actual, new long[] {6, 14, 1, UNBOUND}); TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 14, 2, 15}); TuplesTestingUtil.testTuplesRow(actual, new long[] {8, 9, 11, UNBOUND}); assertTrue(!actual.next()); TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs}); } }