diff options
author | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2017-01-18 21:01:40 +0100 |
---|---|---|
committer | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2017-01-18 21:02:49 +0100 |
commit | c1b29aea3803e6e25287cfdf794f030538bdfa7c (patch) | |
tree | fb47ab0b8181967eed19adafaee3226dc913380e | |
parent | 87414fdd938238f1d73eb8b2ae2344c42cdbe2c0 (diff) | |
download | rdflib-c1b29aea3803e6e25287cfdf794f030538bdfa7c.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.py | 23 | ||||
-rw-r--r-- | rdflib/plugins/sparql/evaluate.py | 2 | ||||
-rw-r--r-- | rdflib/plugins/sparql/sparql.py | 5 | ||||
-rw-r--r-- | test/DAWG/rdflib/bindscope.rq | 6 | ||||
-rw-r--r-- | test/DAWG/rdflib/bindscope.srx | 22 | ||||
-rw-r--r-- | test/DAWG/rdflib/bindscope.ttl | 6 | ||||
-rw-r--r-- | test/DAWG/rdflib/bindscope2.rq | 9 | ||||
-rw-r--r-- | test/DAWG/rdflib/bindscope2.tsv | 8 | ||||
-rw-r--r-- | test/DAWG/rdflib/manifest.ttl | 30 |
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> + . |