summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-18 21:01:40 +0100
committerGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-18 21:02:49 +0100
commitc1b29aea3803e6e25287cfdf794f030538bdfa7c (patch)
treefb47ab0b8181967eed19adafaee3226dc913380e
parent87414fdd938238f1d73eb8b2ae2344c42cdbe2c0 (diff)
downloadrdflib-fix-issue-580.tar.gz
Fixed some BIND scoping issuesfix-issue-580
Made Extend eval only forget vars not bound outside. Made Extend only collect vars not in "expr" This fixes #580
-rw-r--r--rdflib/plugins/sparql/algebra.py23
-rw-r--r--rdflib/plugins/sparql/evaluate.py2
-rw-r--r--rdflib/plugins/sparql/sparql.py5
-rw-r--r--test/DAWG/rdflib/bindscope.rq6
-rw-r--r--test/DAWG/rdflib/bindscope.srx22
-rw-r--r--test/DAWG/rdflib/bindscope.ttl6
-rw-r--r--test/DAWG/rdflib/bindscope2.rq9
-rw-r--r--test/DAWG/rdflib/bindscope2.tsv8
-rw-r--r--test/DAWG/rdflib/manifest.ttl30
9 files changed, 99 insertions, 12 deletions
diff --git a/rdflib/plugins/sparql/algebra.py b/rdflib/plugins/sparql/algebra.py
index 4f24740f..026b58e4 100644
--- a/rdflib/plugins/sparql/algebra.py
+++ b/rdflib/plugins/sparql/algebra.py
@@ -435,16 +435,21 @@ def _addVars(x, children):
if isinstance(x, Variable):
return set([x])
elif isinstance(x, CompValue):
- x["_vars"] = set(reduce(operator.or_, children, set()))
- if x.name == "Bind":
- return set([x.var])
- elif x.name == 'SubSelect':
- if x.projection:
- s = set(v.var or v.evar for v in x.projection)
- else:
- s = set()
+ if x.name == "Extend":
+ # vars only used in the expr for a bind should not be included
+ x["_vars"] = reduce(operator.or_, [ child for child,part in zip(children,x) if part!='expr' ], set())
+
+ return set([x.var]) # perhaps this should expose all vars here too?
+ else:
+ x["_vars"] = set(reduce(operator.or_, children, set()))
+
+ if x.name == 'SubSelect':
+ if x.projection:
+ s = set(v.var or v.evar for v in x.projection)
+ else:
+ s = set()
- return s
+ return s
return reduce(operator.or_, children, set())
diff --git a/rdflib/plugins/sparql/evaluate.py b/rdflib/plugins/sparql/evaluate.py
index aab3ca61..e79e5149 100644
--- a/rdflib/plugins/sparql/evaluate.py
+++ b/rdflib/plugins/sparql/evaluate.py
@@ -74,7 +74,7 @@ def evalExtend(ctx, extend):
for c in evalPart(ctx, extend.p):
try:
- e = _eval(extend.expr, c.forget(ctx))
+ e = _eval(extend.expr, c.forget(ctx, _except=extend._vars))
if isinstance(e, SPARQLError):
raise e
diff --git a/rdflib/plugins/sparql/sparql.py b/rdflib/plugins/sparql/sparql.py
index 76eded8f..69505561 100644
--- a/rdflib/plugins/sparql/sparql.py
+++ b/rdflib/plugins/sparql/sparql.py
@@ -191,13 +191,14 @@ class FrozenBindings(FrozenDict):
bnodes = property(_bnodes)
now = property(_now)
- def forget(self, before):
+ def forget(self, before, _except=None):
"""
return a frozen dict only of bindings made in self
since before
"""
+ if not _except : _except = []
- return FrozenBindings(self.ctx, (x for x in self.iteritems() if before[x[0]] is None))
+ return FrozenBindings(self.ctx, (x for x in self.iteritems() if x[0] in _except or before[x[0]] is None))
def remember(self, these):
"""
diff --git a/test/DAWG/rdflib/bindscope.rq b/test/DAWG/rdflib/bindscope.rq
new file mode 100644
index 00000000..35ae3904
--- /dev/null
+++ b/test/DAWG/rdflib/bindscope.rq
@@ -0,0 +1,6 @@
+PREFIX s: <http://schema.org/>
+
+SELECT ?s ?o ?x WHERE {
+ ?x s:knows ?o .
+ { ?x a s:Person. BIND(?x as ?s) }
+}
diff --git a/test/DAWG/rdflib/bindscope.srx b/test/DAWG/rdflib/bindscope.srx
new file mode 100644
index 00000000..91cd6c93
--- /dev/null
+++ b/test/DAWG/rdflib/bindscope.srx
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+ <head>
+ <variable name="s"/>
+ <variable name="o"/>
+ <variable name="x"/>
+ </head>
+ <results>
+ <result>
+ <binding name="s">
+ <uri>http://example.org/jane</uri>
+ </binding>
+ <binding name="o">
+ <uri>http://example.org/john</uri>
+ </binding>
+ <binding name="x">
+ <uri>http://example.org/jane</uri>
+ </binding>
+
+ </result>
+ </results>
+</sparql>
diff --git a/test/DAWG/rdflib/bindscope.ttl b/test/DAWG/rdflib/bindscope.ttl
new file mode 100644
index 00000000..4f732820
--- /dev/null
+++ b/test/DAWG/rdflib/bindscope.ttl
@@ -0,0 +1,6 @@
+@prefix s: <http://schema.org/> .
+@prefix x: <http://example.org/> .
+
+x:john a s:Person ; s:name "John" .
+x:jane a s:Person ; s:name "Jane" ; s:knows x:john.
+x:ecorp a s:Organization ; s:name "Evil Corp" ; s:employee x:jane . \ No newline at end of file
diff --git a/test/DAWG/rdflib/bindscope2.rq b/test/DAWG/rdflib/bindscope2.rq
new file mode 100644
index 00000000..1e825d21
--- /dev/null
+++ b/test/DAWG/rdflib/bindscope2.rq
@@ -0,0 +1,9 @@
+PREFIX s: <http://schema.org/>
+PREFIX x: <http://example.org/>
+
+SELECT ?s ?p ?o ?x
+WHERE {
+ ?x a s:Person .
+ { ?x ?p ?o . BIND (?x as ?s) } UNION
+ { ?s ?p ?x . BIND (?x as ?o) }
+}
diff --git a/test/DAWG/rdflib/bindscope2.tsv b/test/DAWG/rdflib/bindscope2.tsv
new file mode 100644
index 00000000..8bed6717
--- /dev/null
+++ b/test/DAWG/rdflib/bindscope2.tsv
@@ -0,0 +1,8 @@
+?s ?p ?o ?x
+<http://example.org/john> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> <http://example.org/john>
+<http://example.org/john> <http://schema.org/name> "John" <http://example.org/john>
+<http://example.org/jane> <http://schema.org/knows> <http://example.org/john> <http://example.org/john>
+<http://example.org/jane> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> <http://example.org/jane>
+<http://example.org/jane> <http://schema.org/name> "Jane" <http://example.org/jane>
+<http://example.org/jane> <http://schema.org/knows> <http://example.org/john> <http://example.org/jane>
+<http://example.org/ecorp> <http://schema.org/employee> <http://example.org/jane> <http://example.org/jane> \ No newline at end of file
diff --git a/test/DAWG/rdflib/manifest.ttl b/test/DAWG/rdflib/manifest.ttl
index 732c594f..144a8662 100644
--- a/test/DAWG/rdflib/manifest.ttl
+++ b/test/DAWG/rdflib/manifest.ttl
@@ -16,6 +16,8 @@
:whitespacedot
:minusfilter
:notexistsfilter
+ :bindscope
+ :bindscope2
) .
@@ -81,3 +83,31 @@ From https://github.com/RDFLib/rdflib/issues/615, contributed by https://github.
qt:data <minusfilter.ttl> ] ;
mf:result <notexistsfilter.srx>
.
+
+
+:bindscope rdf:type mf:QueryEvaluationTest ;
+ mf:name "Scope of bind in groups";
+ rdfs:comment """
+ From https://github.com/RDFLib/rdflib/issues/580, contributed by https://github.com/pchampin
+""";
+ dawgt:approval dawgt:Approved ;
+ dawgt:approvedBy <http://gromgull.net/me> ;
+ mf:action
+ [ qt:query <bindscope.rq> ;
+ qt:data <bindscope.ttl> ] ;
+ mf:result <bindscope.srx>
+ .
+
+
+:bindscope2 rdf:type mf:QueryEvaluationTest ;
+ mf:name "Scope of bind in groups2";
+ rdfs:comment """
+ From https://github.com/RDFLib/rdflib/issues/580, contributed by https://github.com/pchampin
+""";
+ dawgt:approval dawgt:Approved ;
+ dawgt:approvedBy <http://gromgull.net/me> ;
+ mf:action
+ [ qt:query <bindscope2.rq> ;
+ qt:data <bindscope.ttl> ] ;
+ mf:result <bindscope2.tsv>
+ .