On 17/03/16 10:16, Jörn Hees wrote:
Hi,
i have a question about the "intended scope" of BIND...
Trying to fix an issue in the RDFLib SPARQL processor [1], i came up with what
i thought was a minimal breaking test [2] like this:
Thank you for providing a test.
This works (correctly binds ?z in RDFLib):
select * {
?s ?p ?o .
bind(?o as ?z)
}
Algebra:
(extend ((?z ?o))
(bgp (triple ?s ?p ?o)))
This doesn't:
select * {
?s ?p ?o .
{ bind(?o as ?z) }
}
Algebra:
(join
(bgp (triple ?s ?p ?o))
(extend ((?z ?o))
(table unit)))
The issue is what value ?z is being bound to.
The addition of {} means that the the BIND is run on what's before it in
that {}-group, then joined with the rest of the outer {}-group. SPARQL
evaluates the inner {}-groups and then combines the results.
{ bind(?o as ?z) } does not have ?o bound to anything -> evaluation error.
Try this:
select * { bind(?o as ?z) }
Andy
(At this time, my expectation was that the latter should also bind ?z. Later, I
found out that jena disagrees (see appendix).)
So i went down in our implementation and fixed the behaviour, making my tests
for [1] pass.
To my surprise the fix caused another test to fail, namely bind07 [3] from the
SPARQL 1.1 test cases:
SELECT ?s ?p ?o ?z {
?s ?p ?o .
{ BIND(?o+1 AS ?z) } UNION { BIND(?o+2 AS ?z) }
}
The test asserts that ?z is unbound.
I guess that the intention of that test was to make sure ?z isn't bound to
different values.
What i find weird about this is that it's inconsistent with other ways to bind
?z to different things which are allowed:
SELECT ?s ?p ?o ?z {
?s ?p ?o .
{ ?s ?p ?z } UNION { ?z ?p ?o }
}
So my questions are:
- Is [3] correct? What is the motivation?
- Should ?z be bound in this: select * { ?s ?p ?o . { bind(?o as ?z) } } ?
Cheers,
Jörn
[1]: https://github.com/RDFLib/rdflib/issues/580
[2]: https://github.com/RDFLib/rdflib/pull/601
[3]: https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/bind07.rq
Appendix: some tests in jena on the commandline
This works as expected:
$ sparql
--data=https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/data.ttl
--query=<(echo '
select * {
?s ?p ?o .
bind(?o as ?z)
}
')
------------------------------------------------------------
| s | p | o | z |
============================================================
| <http://example.org/s1> | <http://example.org/p> | 1 | 1 |
| <http://example.org/s4> | <http://example.org/p> | 4 | 4 |
| <http://example.org/s3> | <http://example.org/p> | 3 | 3 |
| <http://example.org/s2> | <http://example.org/p> | 2 | 2 |
------------------------------------------------------------
This doesn't:
$ sparql
--data=https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/data.ttl
--query=<(echo '
select * {
?s ?p ?o .
{ bind(?o as ?z) }
}
')
------------------------------------------------------------
| s | p | o | z |
============================================================
| <http://example.org/s1> | <http://example.org/p> | 1 | |
| <http://example.org/s4> | <http://example.org/p> | 4 | |
| <http://example.org/s3> | <http://example.org/p> | 3 | |
| <http://example.org/s2> | <http://example.org/p> | 2 | |
------------------------------------------------------------
Test [3]:
$ sparql
--data=https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/data.ttl
--query=https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/bind07.rq
--------------------
| s | p | o | z |
====================
| :s1 | :p | 1 | |
| :s4 | :p | 4 | |
| :s3 | :p | 3 | |
| :s2 | :p | 2 | |
| :s1 | :p | 1 | |
| :s4 | :p | 4 | |
| :s3 | :p | 3 | |
| :s2 | :p | 2 | |
--------------------
This binds ?z:
$ sparql
--data=https://www.w3.org/2009/sparql/docs/tests/data-sparql11/bind/data.ttl
--query=<(echo '
select * {
?s ?p ?o .
{{ ?s ?p ?z } UNION { ?z ?p ?o }}
}
')
----------------------------------------------------------------------------------
| s | p | o | z
|
==================================================================================
| <http://example.org/s1> | <http://example.org/p> | 1 | 1
|
| <http://example.org/s1> | <http://example.org/p> | 1 |
<http://example.org/s1> |
| <http://example.org/s4> | <http://example.org/p> | 4 | 4
|
| <http://example.org/s4> | <http://example.org/p> | 4 |
<http://example.org/s4> |
| <http://example.org/s3> | <http://example.org/p> | 3 | 3
|
| <http://example.org/s3> | <http://example.org/p> | 3 |
<http://example.org/s3> |
| <http://example.org/s2> | <http://example.org/p> | 2 | 2
|
| <http://example.org/s2> | <http://example.org/p> | 2 |
<http://example.org/s2> |
----------------------------------------------------------------------------------