/******************************************************************************* * Copyright (c) 2007 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cambridge Semantics Incorporated *******************************************************************************/ package org.openanzo.glitter; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import junit.framework.TestCase; import org.openanzo.glitter.expression.aggregate.Count; import org.openanzo.glitter.query.PatternSolution; import org.openanzo.glitter.query.PatternSolutionImpl; import org.openanzo.glitter.query.Projection; import org.openanzo.glitter.query.SolutionList; import org.openanzo.glitter.query.SolutionSet; import org.openanzo.glitter.syntax.abstrakt.Expression; import org.openanzo.glitter.syntax.abstrakt.FunctionCall; import org.openanzo.glitter.syntax.abstrakt.SimpleExpression; import org.openanzo.rdf.Literal; import org.openanzo.rdf.MemTypedLiteral; import org.openanzo.rdf.MemVariable; import org.openanzo.rdf.Variable; /** * Test group by projection * */ public class TestGroupByProjection extends TestCase { /* * setup a simple solution list with enough possible GROUP BY permutations for all the needs of the * below tests. * * x | y | z * ---------------- * x_1 | y_4 | z_1 * x_1 | y_4 | z_1 * x_3 | y_4 | z_1 * x_1 | y_4 | z_2 * */ private static SolutionList solution = new SolutionList(); private static Variable x = MemVariable.createVariable("x"); private static Variable y = MemVariable.createVariable("y"); private static Variable z = MemVariable.createVariable("z"); private static Variable count = MemVariable.createVariable("count"); private static Expression countStar, countDistinctStar, xExpression, zExpression; static { try { countStar = new FunctionCall(new Count(), Collections.<Expression> emptyList(), true, false); countDistinctStar = new FunctionCall(new Count(), Collections.<Expression> emptyList(), true, true); xExpression = new SimpleExpression(x); zExpression = new SimpleExpression(z); } catch (Exception e) { throw new RuntimeException(e); } } static { PatternSolutionImpl pattern1 = new PatternSolutionImpl(); pattern1.setBinding(x, MemTypedLiteral.create("x_1")); pattern1.setBinding(y, MemTypedLiteral.create("y_4")); pattern1.setBinding(z, MemTypedLiteral.create("z_1")); solution.add(pattern1); PatternSolutionImpl pattern2 = new PatternSolutionImpl(); pattern2.setBinding(x, MemTypedLiteral.create("x_1")); pattern2.setBinding(y, MemTypedLiteral.create("y_4")); pattern2.setBinding(z, MemTypedLiteral.create("z_1")); solution.add(pattern2); PatternSolutionImpl pattern3 = new PatternSolutionImpl(); pattern3.setBinding(x, MemTypedLiteral.create("x_3")); pattern3.setBinding(y, MemTypedLiteral.create("y_4")); pattern3.setBinding(z, MemTypedLiteral.create("z_1")); solution.add(pattern3); PatternSolutionImpl pattern4 = new PatternSolutionImpl(); pattern4.setBinding(x, MemTypedLiteral.create("x_1")); pattern4.setBinding(y, MemTypedLiteral.create("y_4")); pattern4.setBinding(z, MemTypedLiteral.create("z_2")); solution.add(pattern4); } /** * "SELECT count(*) ... GROUP BY ?x" should result in: * * <pre> * count * ------- * 3 * 1 * </pre> * * @throws Exception */ public void testProjectGroupedCount() throws Exception { List<Variable> groupBy = new ArrayList<Variable>(); groupBy.add(x); Projection p = new Projection(Collections.singletonList(countStar), Collections.singletonList(count), groupBy, false, false, false); SolutionSet countGroupBy = p.refineSolutionsBeforeOrdering(solution); countGroupBy = p.refineSolutionsAfterOrdering(countGroupBy, null); assertEquals(2, countGroupBy.size()); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(3)), countGroupBy.get(0).getBinding(count)); assertNull(countGroupBy.get(0).getBinding(x)); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(1)), countGroupBy.get(1).getBinding(count)); assertNull(countGroupBy.get(1).getBinding(x)); } /** * SELECT ?x COUNT(*) ... GROUP BY ?x" should result in: * * <pre> * x | count * ------------ * x_1 | 3 * x_3 | 1 * </pre> * * @throws Exception */ public void testProjectSingleBindingGroupAndCount() throws Exception { List<Variable> groupBy = new ArrayList<Variable>(); groupBy.add(x); List<Expression> projected = new ArrayList<Expression>(); projected.add(xExpression); projected.add(countStar); List<Variable> projectedAs = new ArrayList<Variable>(); projectedAs.add(x); projectedAs.add(count); Projection p = new Projection(projected, projectedAs, groupBy, false, false, false); SolutionSet countGroupBy = p.refineSolutionsBeforeOrdering(solution); countGroupBy = p.refineSolutionsAfterOrdering(countGroupBy, null); assertEquals(2, countGroupBy.size()); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(3)), countGroupBy.get(0).getBinding(count)); assertEquals(MemTypedLiteral.create("x_1"), countGroupBy.get(0).getBinding(x)); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(1)), countGroupBy.get(1).getBinding(count)); assertEquals(MemTypedLiteral.create("x_3"), countGroupBy.get(1).getBinding(x)); } /** * SELECT ?x ?z COUNT(*) ... GROUP BY ?x ?z" should result in: * * <pre> * x | z | count * ------------------ * x_1 | z_1 | 2 * x_3 | z_1 | 1 * x_1 | z_2 | 1 * </pre> * * @throws Exception */ public void testProjectMultiBindingGroupAndCount() throws Exception { List<Variable> groupBy = new ArrayList<Variable>(); groupBy = new ArrayList<Variable>(); groupBy.add(x); groupBy.add(z); List<Expression> projected = new ArrayList<Expression>(); projected.add(xExpression); projected.add(zExpression); projected.add(countStar); List<Variable> projectedAs = new ArrayList<Variable>(groupBy); projectedAs.add(count); Projection p = new Projection(projected, projectedAs, groupBy, false, false, false); SolutionSet countGroupBy = p.refineSolutionsBeforeOrdering(solution); countGroupBy = p.refineSolutionsAfterOrdering(countGroupBy, null); assertEquals(3, countGroupBy.size()); HashMap<String, HashMap<String, Integer>> expected = new HashMap<String, HashMap<String, Integer>>(); HashMap<String, Integer> x1 = new HashMap<String, Integer>(); x1.put("z_1", 2); x1.put("z_2", 1); HashMap<String, Integer> x3 = new HashMap<String, Integer>(); x3.put("z_1", 1); expected.put("x_1", x1); expected.put("x_3", x3); for (PatternSolution sol : countGroupBy) { HashMap<String, Integer> zmap = expected.get(((Literal) sol.getBinding(x)).getLabel()); assertNotNull(zmap); Integer i = zmap.get(((Literal) sol.getBinding(z)).getLabel()); assertNotNull(i); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(i)), sol.getBinding(count)); expected.remove(sol.getBinding(z)); } } /** * SELECT ?z COUNT(DISTINCT *) ... GROUP BY ?z" should result in: * * <pre> * z | count * ------------- * z_1 | 2 * z_2 | 1 * </pre> * * @throws Exception */ public void testGroupByDistinct() throws Exception { List<Variable> groupBy = new ArrayList<Variable>(); groupBy = new ArrayList<Variable>(); groupBy.add(z); List<Expression> projected = new ArrayList<Expression>(); projected.add(zExpression); projected.add(countDistinctStar); List<Variable> projectedAs = new ArrayList<Variable>(groupBy); projectedAs.add(count); Projection p = new Projection(projected, projectedAs, groupBy, false, false, false); SolutionSet countGroupBy = p.refineSolutionsBeforeOrdering(solution); countGroupBy = p.refineSolutionsAfterOrdering(countGroupBy, null); assertEquals(2, countGroupBy.size()); HashMap<String, Integer> expected = new HashMap<String, Integer>(); expected.put("z_1", 2); expected.put("z_2", 1); for (PatternSolution sol : countGroupBy) { Integer i = expected.get(((Literal) sol.getBinding(z)).getLabel()); assertNotNull(i); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(i)), sol.getBinding(count)); expected.remove(sol.getBinding(z)); } } /** * Sanity test to got with above 'testGroupByDistinct' SELECT ?z COUNT(*) ... GROUP BY ?z" should result in: * * <pre> * z | count * ------------- * z_1 | 3 <--- * 3 instead of 2 * z_2 | 1 * </pre> * * @throws Exception */ public void testGroupByNonDistinct() throws Exception { List<Variable> groupBy = new ArrayList<Variable>(); groupBy = new ArrayList<Variable>(); groupBy.add(z); List<Expression> projected = new ArrayList<Expression>(); projected.add(zExpression); projected.add(countStar); List<Variable> projectedAs = new ArrayList<Variable>(groupBy); projectedAs.add(count); Projection p = new Projection(projected, projectedAs, groupBy, false, false, false); SolutionSet countGroupBy = p.refineSolutionsBeforeOrdering(solution); countGroupBy = p.refineSolutionsAfterOrdering(countGroupBy, null); assertEquals(2, countGroupBy.size()); HashMap<String, Integer> expected = new HashMap<String, Integer>(); expected.put("z_1", 3); expected.put("z_2", 1); for (PatternSolution sol : countGroupBy) { Integer i = expected.get(((Literal) sol.getBinding(z)).getLabel()); assertNotNull(i); assertEquals(MemTypedLiteral.create(BigInteger.valueOf(i)), sol.getBinding(count)); expected.remove(sol.getBinding(z)); } } }