/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.sparql.expr;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.query.* ;
import static org.apache.jena.query.Syntax.* ;
import org.apache.jena.rdf.model.Literal ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.aggregate.AggregateRegistry ;
import org.apache.jena.sparql.expr.aggregate.lib.StandardAggregates ;
import org.apache.jena.sparql.sse.SSE ;
import static org.junit.Assert.* ;
import org.junit.BeforeClass ;
import org.junit.Test ;
public class TestStatisticsAggregates {
static String NL = "\n" ;
static String PRE = StrUtils.strjoinNL
("PREFIX agg: <http://jena.apache.org/ARQ/function/aggregate#>") ;
static DatasetGraph ds = SSE.parseDatasetGraph("(dataset (graph (:x :p1 -1) (:x :p2 2) (:x :p3 3) (:x :p4 3) ))") ;
static DatasetGraph dsEmpty = SSE.parseDatasetGraph("(dataset)") ;
static DatasetGraph ds1 = SSE.parseDatasetGraph("(dataset (graph (:x :p -1)) )") ;
@BeforeClass public static void setupClass() {
StandardAggregates.register();
}
static double VALUEstdev_samp = 1.8929694486000912 ;
static double VALUEstdev_sampd = 2.0816659994661326 ;
static double VALUEstdev_pop = 1.6393596310755 ;
static double VALUEstdev_popd = 1.699673171197595 ;
static double VALUEvar_samp = 3.5833333333333333 ;
static double VALUEvar_sampd = 4.333333333333333 ;
static double VALUEvar_pop = 2.6875 ;
static double VALUEvar_popd = 2.888888888888889 ;
// For each aggregate function, there are the following tests.
// The aggregate <uri>() / SPARQL 1.1
// The DISTINCT aggregate / SPARQL 1.1
// ARQ keyword
// ARQ DISTINCT keyword
// AGG <uri>() / ARQ
// AGG DISTINCT <uri>() / ARQ
// ---- stdev
@Test public void agg_stat_stdev_uri() {
test("agg:stdev(?x)", VALUEstdev_samp, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_uri_distinct() {
test("agg:stdev(DISTINCT ?x)", VALUEstdev_sampd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_kw() {
test("STDEV(?x)", VALUEstdev_samp, syntaxARQ) ;
}
@Test public void agg_stat_stdev_kw_distinct() {
test("STDEV(DISTINCT ?x)", VALUEstdev_sampd, syntaxARQ) ;
}
@Test public void agg_stat_stdev_agg() {
test("AGG agg:stdev(?x)", VALUEstdev_samp, syntaxARQ) ;
}
@Test public void agg_stat_stdev_agg_distinct() {
test("AGG agg:stdev(DISTINCT ?x)", VALUEstdev_sampd, syntaxARQ) ;
}
// ---- stdev_samp
@Test public void agg_stat_stdev_samp_uri() {
test("agg:stdev_samp(?x)", VALUEstdev_samp, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_samp_uri_distinct() {
test("agg:stdev_samp(DISTINCT ?x)", VALUEstdev_sampd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_samp_kw() {
test("STDEV_SAMP(?x)", VALUEstdev_samp, syntaxARQ) ;
}
@Test public void agg_stat_stdev_samp_kw_distinct() {
test("STDEV_SAMP(DISTINCT ?x)", VALUEstdev_sampd, syntaxARQ) ;
}
@Test public void agg_stat_stdev_samp_agg() {
test("AGG agg:stdev_samp(?x)", VALUEstdev_samp, syntaxARQ) ;
}
@Test public void agg_stat_stdev_samp_agg_distinct() {
test("AGG agg:stdev_samp(DISTINCT ?x)", VALUEstdev_sampd, syntaxARQ) ;
}
// ---- stdev_pop
@Test public void agg_stat_stdevp_uri() {
test("agg:stdev_pop(?x)", VALUEstdev_pop, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_pop_uri_distinct() {
test("agg:stdev_pop(DISTINCT ?x)", VALUEstdev_popd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_stdev_pop_kw() {
test("STDEV_POP(?x)", VALUEstdev_pop, syntaxARQ) ;
}
@Test public void agg_stat_stdev_pop_kw_distinct() {
test("STDEV_POP(DISTINCT ?x)", VALUEstdev_popd, syntaxARQ) ;
}
@Test public void agg_stat_stdev_pop_agg() {
test("AGG agg:stdev_pop(?x)", VALUEstdev_pop, syntaxARQ) ;
}
@Test public void agg_stat_stdev_pop_agg_distinct() {
test("AGG agg:stdev_pop(DISTINCT ?x)", VALUEstdev_popd, syntaxARQ) ;
}
// ---- variance
@Test public void agg_stat_var_uri() {
test("agg:variance(?x)", VALUEvar_samp, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_uri_distinct() {
test("agg:variance(DISTINCT ?x)", VALUEvar_sampd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_kw() {
test("VARIANCE(?x)", VALUEvar_samp, syntaxARQ) ;
}
@Test public void agg_stat_var_kw_distinct() {
test("VARIANCE(DISTINCT ?x)", VALUEvar_sampd, syntaxARQ) ;
}
@Test public void agg_stat_var_agg() {
test("AGG agg:variance(?x)", VALUEvar_samp, syntaxARQ) ;
}
@Test public void agg_stat_var_agg_distinct() {
test("AGG agg:variance(DISTINCT ?x)", VALUEvar_sampd, syntaxARQ) ;
}
// ---- var_samp
@Test public void agg_stat_var_samp_uri() {
test("agg:var_samp(?x)", VALUEvar_samp, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_samp_uri_distinct() {
test("agg:var_samp(DISTINCT ?x)", VALUEvar_sampd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_samp_kw() {
test("VAR_SAMP(?x)", VALUEvar_samp, syntaxARQ) ;
}
@Test public void agg_stat_var_samp_kw_distinct() {
test("VAR_SAMP(DISTINCT ?x)", VALUEvar_sampd, syntaxARQ) ;
}
@Test public void agg_stat_var_samp_agg() {
test("AGG agg:var_samp(?x)", VALUEvar_samp, syntaxARQ) ;
}
@Test public void agg_stat_var_samp_agg_distinct() {
test("AGG agg:var_samp(DISTINCT ?x)", VALUEvar_sampd, syntaxARQ) ;
}
// ---- var_pop
@Test public void agg_stat_var_pop_uri() {
test("agg:var_pop(?x)", VALUEvar_pop, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_pop_uri_distinct() {
test("agg:var_pop(DISTINCT ?x)", VALUEvar_popd, syntaxSPARQL_11) ;
}
@Test public void agg_stat_var_pop_kw() {
test("VAR_POP(?x)", VALUEvar_pop, syntaxARQ) ;
}
@Test public void agg_stat_var_pop_kw_distinct() {
test("VAR_POP(DISTINCT ?x)", VALUEvar_popd, syntaxARQ) ;
}
@Test public void agg_stat_var_pop_agg() {
test("AGG agg:var_pop(?x)", VALUEvar_pop, syntaxARQ) ;
}
@Test public void agg_stat_var_pop_agg_distinct() {
test("AGG agg:var_pop(DISTINCT ?x)", VALUEvar_popd, syntaxARQ) ;
}
//<http://jena.apache.org/ARQ/function/aggregate#>
@Test public void agg_stat_stdev_full_uri() {
test("<http://jena.apache.org/ARQ/function/aggregate#stdev>(?x)", VALUEstdev_samp, syntaxSPARQL_11) ;
}
@Test public void agg_stat_registry() {
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#stdev")) ;
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#stdev_samp")) ;
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#stdev_pop")) ;
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#variance")) ;
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#var_samp")) ;
assertTrue(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function/aggregate#var_pop")) ;
assertFalse(AggregateRegistry.isRegistered("http://jena.apache.org/ARQ/function#e")) ; // Not an aggregate
}
// ---- Corner cases. 0 and 1 matches.
// Empty -> error
@Test public void agg_stat_stdev_empty() {
testErr("agg:stdev(?x)", dsEmpty, syntaxSPARQL_11) ;
}
// Empty -> error
@Test public void agg_stat_stdev_samp_empty() {
testErr("agg:stdev_samp(?x)", dsEmpty, syntaxSPARQL_11) ;
}
// Empty -> error
@Test public void agg_stat_stdev_pop_empty() {
testErr("agg:stdev_pop(?x)", dsEmpty, syntaxSPARQL_11) ;
}
// Sample of one -> error
@Test public void agg_stat_stdev_size_one() {
testErr("agg:stdev(?x)", ds1, syntaxSPARQL_11) ;
}
// Sample of one -> error
@Test public void agg_stat_stdev_samp_size_one() {
testErr("agg:stdev_samp(?x)", ds1, syntaxSPARQL_11) ;
}
// Sample of one -> error
@Test public void agg_stat_var_size_one_1() {
testErr("agg:var_samp(?x)", ds1, syntaxSPARQL_11) ;
}
// Population of one -> 0e0
@Test public void agg_stat_stdev_pop_size_one() {
Query query = build("agg:stdev_pop(?x)", syntaxSPARQL_11) ;
test(query, 0e0, ds1) ;
}
// Population of one -> 0e0
@Test public void agg_stat_var_pop_size_one() {
Query query = build("agg:var_pop(?x)", syntaxSPARQL_11) ;
test(query, 0e0, ds1) ;
}
// By keyword
private static void test(String qsAgg, double expected, Syntax syntax) {
test(qsAgg, expected, syntax, ds) ;
}
private static void test(String qsAgg, double expected, Syntax syntax, DatasetGraph dsg) {
Query query = build(qsAgg, syntax) ;
test(query, expected, dsg) ;
}
private static void test(Query query, double expected, DatasetGraph dsg) {
try ( QueryExecution qExec = QueryExecutionFactory.create(query, DatasetFactory.wrap(dsg)) ) {
Literal literal = qExec.execSelect().next().getLiteral("X") ;
double result = literal.getDouble() ;
assertEquals(expected, result, 0.001);
}
}
private static Query build(String qsAgg, Syntax syntax) {
String NL = "\n" ;
String qs = PRE+NL+"SELECT ("+qsAgg+NL+"AS ?X) WHERE {?s ?p ?x} GROUP BY ?s" ;
Query query = QueryFactory.create(qs, syntax) ;
return query ;
}
private void testErr(String qsAgg, DatasetGraph ds, Syntax syntax) {
Query query = build(qsAgg, syntax) ;
try ( QueryExecution qExec = QueryExecutionFactory.create(query, DatasetFactory.wrap(ds)) ) {
ResultSet rs = qExec.execSelect() ;
assertTrue(rs.hasNext()) ;
assertTrue(rs.getResultVars().contains("X")) ;
Binding b = rs.nextBinding() ;
assertFalse(b.contains(Var.alloc("X"))) ;
}
}
}