diff --git a/rdflib/plugins/sparql/aggregates.py b/rdflib/plugins/sparql/aggregates.py index 0ac85801b..86bfb25a8 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 isinstance(val, NotBoundError): + continue c += 1 except: return # error in aggregate => no binding @@ -98,10 +100,11 @@ 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 not isinstance(val, NotBoundError): + bindings[a.res] = val + break def agg_GroupConcat(a, group, bindings): diff --git a/test/test_issue563.py b/test/test_issue563.py new file mode 100644 index 000000000..6f042bb7c --- /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 == set([ + (Literal(2), Literal(6), Literal(10)), + (Literal(3), Literal(9), Literal(15)), + (Literal(5), None, Literal(25)), + ]) + +def test_count(): + g = Graph() + results = set(tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT"))) + + 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() + test_count() + + +