From e606bfc323df23a910e7280affeeb5511c3fc9ea Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Champin Date: Wed, 23 Dec 2015 13:29:03 +0100 Subject: [PATCH 1/5] fixing issue #563 --- rdflib/plugins/sparql/aggregates.py | 18 +++++++---- test/test_issue563.py | 48 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 test/test_issue563.py diff --git a/rdflib/plugins/sparql/aggregates.py b/rdflib/plugins/sparql/aggregates.py index 0ac85801b..16cbce40f 100644 --- a/rdflib/plugins/sparql/aggregates.py +++ b/rdflib/plugins/sparql/aggregates.py @@ -1,6 +1,6 @@ from rdflib import Literal, XSD -from rdflib.plugins.sparql.evalutils import _eval +from rdflib.plugins.sparql.evalutils import _eval, NotBoundError from rdflib.plugins.sparql.operators import numeric from rdflib.plugins.sparql.datatypes import type_promotion @@ -88,7 +88,9 @@ def agg_Count(a, group, bindings): for x in group: try: if a.vars != '*': - _eval(a.vars, x) + val = _eval(a.vars, x) + if type(val) is NotBoundError: + continue c += 1 except: return # error in aggregate => no binding @@ -98,10 +100,14 @@ def agg_Count(a, group, bindings): def agg_Sample(a, group, bindings): - try: - bindings[a.res] = _eval(a.vars, iter(group).next()) - except StopIteration: - pass # no res + for ctx in group: + val = _eval(a.vars, ctx) + if type(val) is not NotBoundError: + bindings[a.res] = val + break + else: + bindings[a.res] = Literal(0) + def agg_GroupConcat(a, group, bindings): diff --git a/test/test_issue563.py b/test/test_issue563.py new file mode 100644 index 000000000..c50573378 --- /dev/null +++ b/test/test_issue563.py @@ -0,0 +1,48 @@ +from rdflib import BNode, Literal, Graph, Namespace +from rdflib.compare import isomorphic + +EX = Namespace("http://example.org/") +QUERY = """ +PREFIX rdf: +PREFIX rdfs: +SELECT ?x (%s(?y) as ?ys) (%s(?z) as ?zs) WHERE { + VALUES (?x ?y ?z) { + + (2 6 UNDEF) + (2 UNDEF 10) + + (3 UNDEF 15) + (3 9 UNDEF) + + (5 UNDEF 25) + } +} +GROUP BY ?x +""" + +def test_sample(): + g = Graph() + results = set( tuple(i) for i in g.query(QUERY % ("SAMPLE", "SAMPLE")) ) + + assert results == { + (Literal(2), Literal(6), Literal(10)), + (Literal(3), Literal(9), Literal(15)), + (Literal(5), Literal(0), Literal(25)), + } + +def test_count(): + g = Graph() + results = set( tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT")) ) + + assert results == { + (Literal(2), Literal(1), Literal(1)), + (Literal(3), Literal(1), Literal(1)), + (Literal(5), Literal(0), Literal(1)), + } + +if __name__ == "__main__": + #test_sample() + test_count() + + + From 6f41f43fc421d66f283eafec888845cd4d22825b Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Champin Date: Wed, 23 Dec 2015 14:34:52 +0100 Subject: [PATCH 2/5] made test_issue563 py26 compatible --- test/test_issue563.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_issue563.py b/test/test_issue563.py index c50573378..06422b97c 100644 --- a/test/test_issue563.py +++ b/test/test_issue563.py @@ -24,21 +24,21 @@ def test_sample(): g = Graph() results = set( tuple(i) for i in g.query(QUERY % ("SAMPLE", "SAMPLE")) ) - assert results == { + assert results == set([ (Literal(2), Literal(6), Literal(10)), (Literal(3), Literal(9), Literal(15)), (Literal(5), Literal(0), Literal(25)), - } + ]) def test_count(): g = Graph() results = set( tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT")) ) - assert results == { + assert results == set([ (Literal(2), Literal(1), Literal(1)), (Literal(3), Literal(1), Literal(1)), (Literal(5), Literal(0), Literal(1)), - } + ]) if __name__ == "__main__": #test_sample() From fe0fed3d5f77fe02a108a9663b0b5b09620620ec Mon Sep 17 00:00:00 2001 From: Joern Hees Date: Tue, 29 Dec 2015 19:54:48 +0100 Subject: [PATCH 3/5] SAMPLE may return None if no binding is found --- test/test_issue563.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_issue563.py b/test/test_issue563.py index 06422b97c..6f042bb7c 100644 --- a/test/test_issue563.py +++ b/test/test_issue563.py @@ -22,17 +22,17 @@ def test_sample(): g = Graph() - results = set( tuple(i) for i in g.query(QUERY % ("SAMPLE", "SAMPLE")) ) + results = set(tuple(i) for i in g.query(QUERY % ("SAMPLE", "SAMPLE"))) assert results == set([ (Literal(2), Literal(6), Literal(10)), (Literal(3), Literal(9), Literal(15)), - (Literal(5), Literal(0), Literal(25)), + (Literal(5), None, Literal(25)), ]) def test_count(): g = Graph() - results = set( tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT")) ) + results = set(tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT"))) assert results == set([ (Literal(2), Literal(1), Literal(1)), @@ -41,7 +41,7 @@ def test_count(): ]) if __name__ == "__main__": - #test_sample() + test_sample() test_count() From cd73b9818bc0c19f3595795cfca226f6074bff14 Mon Sep 17 00:00:00 2001 From: Joern Hees Date: Tue, 29 Dec 2015 20:02:12 +0100 Subject: [PATCH 4/5] adapted agg_Sample to return None instead of 0 if no binding is found --- rdflib/plugins/sparql/aggregates.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/rdflib/plugins/sparql/aggregates.py b/rdflib/plugins/sparql/aggregates.py index 16cbce40f..ce9f8c9a6 100644 --- a/rdflib/plugins/sparql/aggregates.py +++ b/rdflib/plugins/sparql/aggregates.py @@ -105,9 +105,6 @@ def agg_Sample(a, group, bindings): if type(val) is not NotBoundError: bindings[a.res] = val break - else: - bindings[a.res] = Literal(0) - def agg_GroupConcat(a, group, bindings): From 609b0e06425c9487faee4ad6bf8835b1b2b28ba9 Mon Sep 17 00:00:00 2001 From: Joern Hees Date: Tue, 29 Dec 2015 20:03:32 +0100 Subject: [PATCH 5/5] minor: isinstance instead of type-equals --- rdflib/plugins/sparql/aggregates.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rdflib/plugins/sparql/aggregates.py b/rdflib/plugins/sparql/aggregates.py index ce9f8c9a6..86bfb25a8 100644 --- a/rdflib/plugins/sparql/aggregates.py +++ b/rdflib/plugins/sparql/aggregates.py @@ -89,7 +89,7 @@ def agg_Count(a, group, bindings): try: if a.vars != '*': val = _eval(a.vars, x) - if type(val) is NotBoundError: + if isinstance(val, NotBoundError): continue c += 1 except: @@ -102,7 +102,7 @@ def agg_Count(a, group, bindings): def agg_Sample(a, group, bindings): for ctx in group: val = _eval(a.vars, ctx) - if type(val) is not NotBoundError: + if not isinstance(val, NotBoundError): bindings[a.res] = val break