/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Jul 27, 2011
*/
package com.bigdata.bop.solutions;
import java.util.LinkedHashSet;
import junit.framework.TestCase2;
import org.openrdf.query.algebra.Compare.CompareOp;
import com.bigdata.bop.Bind;
import com.bigdata.bop.Constant;
import com.bigdata.bop.IConstraint;
import com.bigdata.bop.IValueExpression;
import com.bigdata.bop.IVariable;
import com.bigdata.bop.Var;
import com.bigdata.bop.aggregate.IAggregate;
import com.bigdata.bop.rdf.aggregate.MIN;
import com.bigdata.bop.rdf.aggregate.SUM;
import com.bigdata.journal.ITx;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.constraints.CompareBOp;
import com.bigdata.rdf.internal.constraints.MathBOp;
import com.bigdata.rdf.internal.constraints.MathBOp.MathOp;
import com.bigdata.rdf.internal.constraints.SPARQLConstraint;
import com.bigdata.rdf.internal.constraints.UcaseBOp;
import com.bigdata.rdf.internal.impl.literal.XSDBooleanIV;
import com.bigdata.rdf.internal.impl.literal.XSDNumericIV;
import com.bigdata.rdf.sparql.ast.GlobalAnnotations;
/**
* Test suite for {@link GroupByState}.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
public class TestGroupByState extends TestCase2 {
/**
*
*/
public TestGroupByState() {
}
/**
* @param name
*/
public TestGroupByState(String name) {
super(name);
}
private GlobalAnnotations globals;
protected void setUp() throws Exception {
super.setUp();
globals = new GlobalAnnotations(getName(), ITx.READ_COMMITTED);
}
protected void tearDown() throws Exception {
globals = null;
super.tearDown();
}
private static class MockGroupByState implements IGroupByState {
final IValueExpression<?>[] groupBy;
final LinkedHashSet<IVariable<?>> groupByVars;
final IValueExpression<?>[] select;
final LinkedHashSet<IVariable<?>> selectVars;
final IConstraint[] having;
final LinkedHashSet<IVariable<?>> columnVars;
// final LinkedHashSet<IVariable<?>> distinctColumnVars;
final boolean anyDistinct;
final boolean selectDependency;
final boolean nestedAggregates;
final boolean simpleHaving;
MockGroupByState(//
final IValueExpression<?>[] groupBy,
final LinkedHashSet<IVariable<?>> groupByVars,
final IValueExpression<?>[] select,
final LinkedHashSet<IVariable<?>> selectVars,
final IConstraint[] having,//
final LinkedHashSet<IVariable<?>> columnVars,//
// final LinkedHashSet<IVariable<?>> distinctColumnVars,//
final boolean anyDistinct,//
final boolean selectDependency,//
final boolean nestedAggregates,//
final boolean simpleHaving//
) {
this.groupBy = groupBy;
this.groupByVars = groupByVars;
this.select = select;
this.selectVars = selectVars;
this.having = having;
this.columnVars = columnVars;
// this.distinctColumnVars = distinctColumnVars;
this.anyDistinct = anyDistinct;
this.selectDependency = selectDependency;
this.nestedAggregates = nestedAggregates;
this.simpleHaving = simpleHaving;
}
public IValueExpression<?>[] getGroupByClause() {
return groupBy;
}
public LinkedHashSet<IVariable<?>> getGroupByVars() {
return groupByVars;
}
public IValueExpression<?>[] getSelectClause() {
return select;
}
public LinkedHashSet<IVariable<?>> getSelectVars() {
return selectVars;
}
public IConstraint[] getHavingClause() {
return having;
}
public LinkedHashSet<IVariable<?>> getColumnVars() {
return columnVars;
}
// public LinkedHashSet<IVariable<?>> getDistinctColumnVars() {
// return distinctColumnVars;
// }
public boolean isAnyDistinct() {
return anyDistinct;
}
public boolean isSelectDependency() {
return selectDependency;
}
public boolean isNestedAggregates() {
return nestedAggregates;
}
public boolean isSimpleHaving() {
return simpleHaving;
}
}
static void assertSameState(final IGroupByState expected,
final IGroupByState actual) {
assertEquals("groupByClause", expected.getGroupByClause(),
actual.getGroupByClause());
assertEquals("groupByVars", expected.getGroupByVars(),
actual.getGroupByVars());
assertEquals("selectClause", expected.getSelectClause(),
actual.getSelectClause());
assertEquals("selectVars", expected.getSelectVars(),
actual.getSelectVars());
assertEquals("havingClause", expected.getHavingClause(),
actual.getHavingClause());
assertEquals("columnVars", expected.getColumnVars(),
actual.getColumnVars());
// assertEquals("distinctColumnVars", expected.getDistinctColumnVars(),
// actual.getDistinctColumnVars());
assertEquals("anyDistinct", expected.isAnyDistinct(),
actual.isAnyDistinct());
assertEquals("selectDependency", expected.isSelectDependency(),
actual.isSelectDependency());
assertEquals("nestedAggregates", expected.isNestedAggregates(),
actual.isNestedAggregates());
assertEquals("simpleHaving", expected.isSimpleHaving(),
actual.isSimpleHaving());
}
/**
* Unit test with SELECT clause having one value expression, which is a
* simple variable also appearing as the sole value expression in the
* GROUP_BY clause.
* <pre>
* SELECT ?org
* GROUP BY ?org
* </pre>
*/
public void test_aggregateExpr_01() {
final IVariable<?> org = Var.var("org");
final IValueExpression<?>[] select = new IValueExpression[] { org };
final IValueExpression<?>[] groupBy = new IValueExpression[] { org };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(org);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(org);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test with SELECT clause having one value expression, which is a
* simple variable also appearing as the sole value expression in the
* GROUP_BY clause. However, in this case we rename the variable when it is
* projected out of the SELECT expression.
*
* <pre>
* SELECT ?org as ?newVar
* GROUP BY ?org
* </pre>
*/
public void test_aggregateExpr_02() {
final IVariable<?> org = Var.var("org");
final IVariable<?> newVar = Var.var("newVar");
@SuppressWarnings({ "unchecked", "rawtypes" })
final IValueExpression<?>[] select = new IValueExpression[] { new Bind(
newVar, org) };
final IValueExpression<?>[] groupBy = new IValueExpression[] { org };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(org);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(newVar);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test with simple aggregate function in SELECT clause.
* <pre>
* SELECT ?org, SUM(?lprice) AS ?totalPrice
* GROUP BY ?org
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_simpleAggregate() {
final IVariable<?> org = Var.var("org");
final IVariable<?> lprice = Var.var("lprice");
final IVariable<?> totalPrice = Var.var("totalPrice");
final IValueExpression<?> totalPriceExpr = new /* Conditional */Bind(
totalPrice, new SUM(false/* distinct */,
(IValueExpression<IV>) lprice));
final IValueExpression<?>[] select = new IValueExpression[] { org, totalPriceExpr };
final IValueExpression<?>[] groupBy = new IValueExpression[] { org };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(org);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(org);
selectVars.add(totalPrice);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(lprice);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test with simple aggregate function in SELECT clause and no GROUP BY
* clause (the aggregation is taken across all solutions as if they were a
* single group).
*
* <pre>
* SELECT SUM(?lprice) AS ?totalPrice
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_simpleAggregate_noGroupBy() {
final IVariable<?> lprice = Var.var("lprice");
final IVariable<?> totalPrice = Var.var("totalPrice");
final IValueExpression<?> totalPriceExpr = new /* Conditional */Bind(
totalPrice, new SUM(false/* distinct */,
(IValueExpression<IV>) lprice));
final IValueExpression<?>[] select = new IValueExpression[] { totalPriceExpr };
final IValueExpression<?>[] groupBy = null;
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(totalPrice);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(lprice);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test for references to aggregate declared in GROUP_BY with AS.
* <pre>
* SELECT ?org2
* GROUP BY UCASE(?org) as ?org2
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_aggregateExpr_03() {
// Note: UcaseBOp is what we need here.
final IVariable<IV<?,?>> org = Var.var("org");
final IVariable<IV<?,?>> org2 = Var.var("org2");
// The namespace of the lexicon relation.
final String namespace = "kb.lex";
final IValueExpression<?> ucaseExpr = new Bind(org2, new UcaseBOp(org,
globals));
final IValueExpression<?>[] select = new IValueExpression[] { org2 };
final IValueExpression<?>[] groupBy = new IValueExpression[] { ucaseExpr };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(org2);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(org2);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test verifies that a constant within a group by clause does not
* cause the group by clause to be interpreted as an aggregate.
*
* <pre>
* select ?index
* group by (?o + 1 AS ?index)
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_aggregateExpr_04() {
final IVariable<IV<?,?>> index = Var.var("index");
final IVariable<IV<?,?>> o = Var.var("o");
final IValueExpression<?> mathExpr = new Bind(index, //
new MathBOp(o, new Constant(new XSDNumericIV(1)),
MathBOp.MathOp.PLUS,globals));
final IValueExpression<?>[] select = new IValueExpression[] { new Bind(
index, index) };
final IValueExpression<?>[] groupBy = new IValueExpression[] { mathExpr };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(index);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(index);
final LinkedHashSet<IVariable<?>> havingVars = new LinkedHashSet<IVariable<?>>();
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, havingVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* <pre>
* SELECT SUM(?y) as ?x
* GROUP BY ?z
* HAVING ?x > 10
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_simpleHavingClause() {
final IVariable<IV> y = Var.var("y");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> xExpr = new /* Conditional */Bind(x, new SUM(
false/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV>[] select = new IValueExpression[] { xExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { z };
final IConstraint[] having = new IConstraint[] {//
new SPARQLConstraint<XSDBooleanIV>(new CompareBOp(x,
new Constant<XSDNumericIV>(new XSDNumericIV(10)), CompareOp.LT
))//
};
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(z);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(x);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(y);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* <pre>
* SELECT SUM(?y) as ?x
* GROUP BY ?z
* HAVING SUM(?y) > 10
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_complexHavingClause() {
final IVariable<IV> y = Var.var("y");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> xExpr = new /* Conditional */Bind(x,
new SUM(false/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV>[] select = new IValueExpression[] { xExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { z };
final IConstraint[] having = new IConstraint[] {//
new SPARQLConstraint<XSDBooleanIV>(new CompareBOp(new SUM(
false/* distinct */, (IValueExpression<IV>) y),
new Constant<XSDNumericIV>(new XSDNumericIV(10)), CompareOp.LT
)) //
};
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(z);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(x);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(y);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, false/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* <pre>
* SELECT SUM(?x+MIN(?y)) as ?z
* GROUP BY ?a
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_nestedAggregates() {
final IVariable<IV> a = Var.var("a");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> y = Var.var("y");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> zExpr = new /* Conditional */Bind(z,
new SUM(false/* distinct */,
(IValueExpression<IV>) new MathBOp(x, new MIN(
false/* distinct */, (IValueExpression<IV>) y),
MathOp.PLUS,globals)));
final IValueExpression<IV>[] select = new IValueExpression[] { zExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { a };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(a);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(z);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(x);
columnVars.add(y);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
true/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Verify that a reference to a variable defined by a previous select
* expression is allowed and that the select dependency is recognized.
*
* <pre>
* SELECT SUM(?y) as ?z, SUM(?x)+?z as ?a
* GROUP BY ?b
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_reverseReference_allowed_aka_select_dependency() {
final IVariable<IV> a = Var.var("a");
final IVariable<IV> b = Var.var("b");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> y = Var.var("y");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> zExpr = new /* Conditional */Bind(z,
new SUM(false/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV> aExpr = new /* Conditional */Bind(a,
new MathBOp(new SUM(false/* distinct */,
(IValueExpression<IV>) x), z, MathOp.PLUS,globals));
final IValueExpression<IV>[] select = new IValueExpression[] { zExpr, aExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { b };
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(b);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(z);
selectVars.add(a);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(y);
columnVars.add(x);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, true/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Forward references to a variable are not allowed.
*
* <pre>
* SELECT SUM(?x)+?z as ?a, SUM(?y) as ?z ... (forward reference to z)
* </pre>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void test_forwardReference_not_allowed() {
final IVariable<IV> a = Var.var("a");
final IVariable<IV> b = Var.var("b");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> y = Var.var("y");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> zExpr = new /* Conditional */Bind(z,
new SUM(false/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV> aExpr = new /* Conditional */Bind(a,
new MathBOp(new SUM(false/* distinct */,
(IValueExpression<IV>) x), z, MathOp.PLUS,globals));
final IValueExpression<IV>[] select = new IValueExpression[] { aExpr, zExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { b };
final IConstraint[] having = null;
try {
new GroupByState(select, groupBy, having);
fail("Expecting: " + IllegalArgumentException.class);
} catch (IllegalArgumentException ex) {
if (log.isInfoEnabled())
log.info("Ignoring expected exception: " + ex,ex);
}
}
/**
* Unit test for {@link IGroupByState#isAnyDistinct()) where the DISTINCT
* keyword appears within an {@link IAggregate} in the SELECT clause.
* <pre>
* SELECT SUM(DISTINCT ?y) as ?x
* GROUP BY ?z
* HAVING ?x > 10
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_isAnyDistinct_select() {
final IVariable<IV> y = Var.var("y");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> xExpr = new /* Conditional */Bind(x, new SUM(
true/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV>[] select = new IValueExpression[] { xExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { z };
final IConstraint[] having = new IConstraint[] {//
new SPARQLConstraint<XSDBooleanIV>(new CompareBOp(x,
new Constant<XSDNumericIV>(new XSDNumericIV(10)), CompareOp.LT
))//
};
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(z);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(x);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(y);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
true/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test for {@link IGroupByState#isAnyDistinct()) where the DISTINCT
* keyword appears within an {@link IAggregate} in the SELECT clause.
* <pre>
* SELECT SUM(?y) as ?x
* GROUP BY ?z
* HAVING SUM(DISTINCT ?y) > 10
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_isAnyDistinct_having() {
final IVariable<IV> y = Var.var("y");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV> xExpr = new /* Conditional */Bind(x, new SUM(
false/* distinct */, (IValueExpression<IV>) y));
final IValueExpression<IV>[] select = new IValueExpression[] { xExpr };
final IValueExpression<IV>[] groupBy = new IValueExpression[] { z };
final IConstraint[] having = new IConstraint[] {//
new SPARQLConstraint<XSDBooleanIV>(new CompareBOp(
new /* Conditional */Bind(x, new SUM(true/* distinct */,
(IValueExpression<IV>) y)), new Constant<XSDNumericIV>(
new XSDNumericIV(10)), CompareOp.LT)) //
};
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
groupByVars.add(z);
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(x);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
columnVars.add(y);
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
true/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, false/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test when projecting a constant
* <pre>
* SELECT 12 as ?x
* </pre>
*/
public void test_with_constant() {
@SuppressWarnings({ "unchecked", "rawtypes" })
final IVariable<IV> x = Var.var("x");
@SuppressWarnings({ "rawtypes", "unchecked" })
final IValueExpression<IV> xExpr = new /* Conditional */Bind(x,
new Constant<IV>(new XSDNumericIV(12)));
@SuppressWarnings({ "rawtypes", "unchecked" })
final IValueExpression<IV>[] select = new IValueExpression[] { xExpr };
@SuppressWarnings("rawtypes")
final IValueExpression<IV>[] groupBy = null;
final IConstraint[] having = null;
final LinkedHashSet<IVariable<?>> groupByVars = new LinkedHashSet<IVariable<?>>();
final LinkedHashSet<IVariable<?>> selectVars = new LinkedHashSet<IVariable<?>>();
selectVars.add(x);
final LinkedHashSet<IVariable<?>> columnVars = new LinkedHashSet<IVariable<?>>();
final MockGroupByState expected = new MockGroupByState(groupBy,
groupByVars, select, selectVars, having, columnVars,
false/* anyDistinct */, false/* selectDependency */,
false/* nestedAggregates */, true/* simpleHaving */);
final IGroupByState actual = new GroupByState(select, groupBy, having);
assertSameState(expected, actual);
}
/**
* Unit test for bad arguments.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void test_correctRejection() {
final IVariable<IV> y = Var.var("y");
final IVariable<IV> x = Var.var("x");
final IVariable<IV> z = Var.var("z");
final IValueExpression<IV>[] groupBy = new IValueExpression[] { z };
final IConstraint[] having = new IConstraint[] {//
new SPARQLConstraint<XSDBooleanIV>(new CompareBOp(
new /* Conditional */Bind(x, new SUM(true/* distinct */,
(IValueExpression<IV>) y)), new Constant<XSDNumericIV>(
new XSDNumericIV(10)), CompareOp.LT)) //
};
// SELECT may not be null.
try {
new GroupByState(null/* select */, groupBy, having);
fail("Expecting: " + IllegalArgumentException.class);
} catch (IllegalArgumentException ex) {
if (log.isInfoEnabled())
log.info("Ignoring expected exception: " + ex, ex);
}
// SELECT may not be empty.
try {
new GroupByState(new IValueExpression[] {}/* select */, groupBy,
having);
fail("Expecting: " + IllegalArgumentException.class);
} catch (IllegalArgumentException ex) {
if (log.isInfoEnabled())
log.info("Ignoring expected exception: " + ex, ex);
}
}
}