/* * 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"))) ; } } }