summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-18 16:18:07 +0100
committerGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-18 16:22:01 +0100
commitab30d192bf46ea6807d85539b10316e5c91d6b99 (patch)
tree0ee289860bb26da72c98292df79074524116f71e
parentc5849501bd76ee60e3ea02632990e3b8eaee6365 (diff)
downloadrdflib-ab30d192bf46ea6807d85539b10316e5c91d6b99.tar.gz
Fixes variable scope for filters inside (NOT) EXIST clauses in SPARQL
Fixes #615 Also adds unit tests.
-rw-r--r--rdflib/plugins/sparql/algebra.py3
-rw-r--r--rdflib/plugins/sparql/evaluate.py2
-rw-r--r--test/DAWG/rdflib/manifest.ttl28
-rw-r--r--test/DAWG/rdflib/minusfilter.rq8
-rw-r--r--test/DAWG/rdflib/minusfilter.srx25
-rw-r--r--test/DAWG/rdflib/minusfilter.ttl8
-rw-r--r--test/DAWG/rdflib/notexistsfilter.rq8
-rw-r--r--test/DAWG/rdflib/notexistsfilter.srx17
8 files changed, 98 insertions, 1 deletions
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 <http://gromgull.net/me> ;
mf:action <whitespacedot.rq>
.
+
+
+
+: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 <http://gromgull.net/me> ;
+ mf:action
+ [ qt:query <minusfilter.rq> ;
+ qt:data <minusfilter.ttl> ] ;
+ mf:result <minusfilter.srx>
+ .
+
+: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 <http://gromgull.net/me> ;
+ mf:action
+ [ qt:query <notexistsfilter.rq> ;
+ qt:data <minusfilter.ttl> ] ;
+ mf:result <notexistsfilter.srx>
+ .
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 : <http://example.com/>
+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 @@
+<?xml version="1.0"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+ <head>
+ <variable name="x"/>
+ <variable name="n"/>
+ </head>
+ <results>
+ <result>
+ <binding name="x">
+ <uri>http://example.com/a</uri>
+ </binding>
+ <binding name="n">
+ <literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal>
+ </binding>
+ </result>
+ <result>
+ <binding name="x">
+ <uri>http://example.com/b</uri>
+ </binding>
+ <binding name="n">
+ <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">3.0</literal>
+ </binding>
+ </result>
+ </results>
+</sparql>
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 : <http://example.com/> .
+: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 : <http://example.com/>
+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 @@
+<?xml version="1.0"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+ <head>
+ <variable name="x"/>
+ <variable name="n"/>
+ </head>
+ <results>
+ <result>
+ <binding name="x">
+ <uri>http://example.com/b</uri>
+ </binding>
+ <binding name="n">
+ <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">3.0</literal>
+ </binding>
+ </result>
+ </results>
+</sparql>