diff options
author | Gunnar Aastrand Grimnes <gromgull@users.noreply.github.com> | 2017-01-19 07:59:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-19 07:59:26 +0100 |
commit | b6ce370fed4ec467041d11de949e06674ad005c0 (patch) | |
tree | fb47ab0b8181967eed19adafaee3226dc913380e | |
parent | ab30d192bf46ea6807d85539b10316e5c91d6b99 (diff) | |
parent | c1b29aea3803e6e25287cfdf794f030538bdfa7c (diff) | |
download | rdflib-b6ce370fed4ec467041d11de949e06674ad005c0.tar.gz |
Merge pull request #688 from RDFLib/fix-issue-580
Fix issue 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/parserutils.py | 25 | ||||
-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 | ||||
-rw-r--r-- | test/test_dawg.py | 2 |
11 files changed, 125 insertions, 13 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/parserutils.py b/rdflib/plugins/sparql/parserutils.py index b5c25600..7e4a3665 100644 --- a/rdflib/plugins/sparql/parserutils.py +++ b/rdflib/plugins/sparql/parserutils.py @@ -241,6 +241,31 @@ class Comp(TokenConverter): return self +def prettify_parsetree(t, indent='', depth=0): + out = [] + if isinstance(t, ParseResults): + for e in t.asList(): + out.append(prettify_parsetree(e, indent, depth + 1)) + for k, v in sorted(t.items()): + out.append("%s%s- %s:\n" % (indent, ' ' * depth, k)) + out.append(prettify_parsetree(v, indent, depth + 1)) + elif isinstance(t, CompValue): + out.append("%s%s> %s:\n" % (indent, ' ' * depth, t.name)) + for k, v in t.items(): + out.append("%s%s- %s:\n" % (indent, ' ' * (depth + 1), k)) + out.append(prettify_parsetree(v, indent, depth + 2)) + elif isinstance(t, dict): + for k, v in t.items(): + out.append("%s%s- %s:\n" % (indent, ' ' * (depth + 1), k)) + out.append(prettify_parsetree(v, indent, depth + 2)) + elif isinstance(t, list): + for e in t: + out.append(prettify_parsetree(e, indent, depth + 1)) + else: + out.append("%s%s- %r\n" % (indent, ' ' * depth, t)) + return "".join(out) + + if __name__ == '__main__': from pyparsing import Word, nums import sys 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> + . diff --git a/test/test_dawg.py b/test/test_dawg.py index 3903ff09..bdacd992 100644 --- a/test/test_dawg.py +++ b/test/test_dawg.py @@ -432,7 +432,7 @@ def query_test(t): assert bindingsCompatible( set(res), set(res2) - ), 'Bindings do not match: \n%s\n!=\n%s' % ( + ), 'Bindings do not match: \nexpected:\n%s\n!=\ngot:\n%s' % ( res.serialize(format='txt', namespace_manager=g.namespace_manager), res2.serialize(format='txt', namespace_manager=g.namespace_manager)) elif res.type == 'ASK': |