From ab30d192bf46ea6807d85539b10316e5c91d6b99 Mon Sep 17 00:00:00 2001 From: Gunnar Aastrand Grimnes Date: Wed, 18 Jan 2017 16:18:07 +0100 Subject: Fixes variable scope for filters inside (NOT) EXIST clauses in SPARQL Fixes #615 Also adds unit tests. --- rdflib/plugins/sparql/algebra.py | 3 +++ rdflib/plugins/sparql/evaluate.py | 2 +- test/DAWG/rdflib/manifest.ttl | 28 ++++++++++++++++++++++++++++ test/DAWG/rdflib/minusfilter.rq | 8 ++++++++ test/DAWG/rdflib/minusfilter.srx | 25 +++++++++++++++++++++++++ test/DAWG/rdflib/minusfilter.ttl | 8 ++++++++ test/DAWG/rdflib/notexistsfilter.rq | 8 ++++++++ test/DAWG/rdflib/notexistsfilter.srx | 17 +++++++++++++++++ 8 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 test/DAWG/rdflib/minusfilter.rq create mode 100644 test/DAWG/rdflib/minusfilter.srx create mode 100644 test/DAWG/rdflib/minusfilter.ttl create mode 100644 test/DAWG/rdflib/notexistsfilter.rq create mode 100644 test/DAWG/rdflib/notexistsfilter.srx diff --git a/rdflib/plugins/sparql/algebra.py b/rdflib/plugins/sparql/algebra.py index 099594a3..4f24740f 100644 --- a/rdflib/plugins/sparql/algebra.py +++ b/rdflib/plugins/sparql/algebra.py @@ -203,6 +203,9 @@ def translateExists(e): if isinstance(n, CompValue): if n.name in ('Builtin_EXISTS', 'Builtin_NOTEXISTS'): n.graph = translateGroupGraphPattern(n.graph) + if n.graph.name == 'Filter': + # filters inside (NOT) EXISTS can see vars bound outside + n.graph.no_isolated_scope = True e = traverse(e, visitPost=_c) diff --git a/rdflib/plugins/sparql/evaluate.py b/rdflib/plugins/sparql/evaluate.py index e6590a25..aab3ca61 100644 --- a/rdflib/plugins/sparql/evaluate.py +++ b/rdflib/plugins/sparql/evaluate.py @@ -152,7 +152,7 @@ def evalLeftJoin(ctx, join): def evalFilter(ctx, part): # TODO: Deal with dict returned from evalPart! for c in evalPart(ctx, part.p): - if _ebv(part.expr, c.forget(ctx)): + if _ebv(part.expr, c.forget(ctx) if not part.no_isolated_scope else c): yield c diff --git a/test/DAWG/rdflib/manifest.ttl b/test/DAWG/rdflib/manifest.ttl index 63b884ad..732c594f 100644 --- a/test/DAWG/rdflib/manifest.ttl +++ b/test/DAWG/rdflib/manifest.ttl @@ -14,6 +14,8 @@ :unicode :nestedbnode :whitespacedot + :minusfilter + :notexistsfilter ) . @@ -53,3 +55,29 @@ dawgt:approvedBy ; mf:action . + + + +:minusfilter rdf:type mf:QueryEvaluationTest ; + mf:name "Filter in MINUS"; + rdfs:comment """' with MINUS, the FILTER inside the pattern does not have a value for ?n and it is always unbound:' +From https://github.com/RDFLib/rdflib/issues/615, contributed by https://github.com/pfps""" ; + dawgt:approval dawgt:Approved ; + dawgt:approvedBy ; + mf:action + [ qt:query ; + qt:data ] ; + mf:result + . + +:notexistsfilter rdf:type mf:QueryEvaluationTest ; + mf:name "Filter in NOT EXISTS"; + rdfs:comment """'the FILTER inside the NOT EXISTS has access to the value of ?n for the solution being considered.' +From https://github.com/RDFLib/rdflib/issues/615, contributed by https://github.com/pfps""" ; + dawgt:approval dawgt:Approved ; + dawgt:approvedBy ; + mf:action + [ qt:query ; + qt:data ] ; + mf:result + . diff --git a/test/DAWG/rdflib/minusfilter.rq b/test/DAWG/rdflib/minusfilter.rq new file mode 100644 index 00000000..b381afe6 --- /dev/null +++ b/test/DAWG/rdflib/minusfilter.rq @@ -0,0 +1,8 @@ +PREFIX : +SELECT ?x ?n WHERE { + ?x :p ?n + MINUS { + ?x :q ?m . + FILTER(?n = ?m) + } +} diff --git a/test/DAWG/rdflib/minusfilter.srx b/test/DAWG/rdflib/minusfilter.srx new file mode 100644 index 00000000..94baded6 --- /dev/null +++ b/test/DAWG/rdflib/minusfilter.srx @@ -0,0 +1,25 @@ + + + + + + + + + + http://example.com/a + + + 1 + + + + + http://example.com/b + + + 3.0 + + + + diff --git a/test/DAWG/rdflib/minusfilter.ttl b/test/DAWG/rdflib/minusfilter.ttl new file mode 100644 index 00000000..a4ec1d64 --- /dev/null +++ b/test/DAWG/rdflib/minusfilter.ttl @@ -0,0 +1,8 @@ +@prefix : . +:a :p 1 . +:a :q 1 . +:a :q 2 . + +:b :p 3.0 . +:b :q 4.0 . +:b :q 5.0 . \ No newline at end of file diff --git a/test/DAWG/rdflib/notexistsfilter.rq b/test/DAWG/rdflib/notexistsfilter.rq new file mode 100644 index 00000000..586be72a --- /dev/null +++ b/test/DAWG/rdflib/notexistsfilter.rq @@ -0,0 +1,8 @@ +PREFIX : +SELECT ?x ?n WHERE { + ?x :p ?n + FILTER NOT EXISTS { + ?x :q ?m . + FILTER(?n = ?m) + } +} diff --git a/test/DAWG/rdflib/notexistsfilter.srx b/test/DAWG/rdflib/notexistsfilter.srx new file mode 100644 index 00000000..fede17eb --- /dev/null +++ b/test/DAWG/rdflib/notexistsfilter.srx @@ -0,0 +1,17 @@ + + + + + + + + + + http://example.com/b + + + 3.0 + + + + -- cgit v1.2.1