Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIND not working as expected in SPARQL #580

Closed
pchampin opened this issue Jan 21, 2016 · 5 comments
Closed

BIND not working as expected in SPARQL #580

pchampin opened this issue Jan 21, 2016 · 5 comments
Assignees
Labels
bug Something isn't working SPARQL
Milestone

Comments

@pchampin
Copy link
Contributor

Ok, consider the following data:

@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 . 

and the following query:

PREFIX s: <http://schema.org/>
PREFIX x: <http://example.org/>

#CONSTRUCT { ?s ?p ?o }
SELECT ?s ?p ?o ?x # for debugging
WHERE {
  ?x a s:Person .
  { ?x ?p ?o . BIND (?x as ?s) } UNION
  { ?s ?p ?x . BIND (?x as ?o) }
}

The goal of the query is to extract all incoming and outgoing arcs of every s:Person in the data
(and ultimately to construct a graph with those, but I use SELECT for debugging).

As I understand, the result should be

?s ?p ?o ?x
x:john rdf:type s:Person x:john
x:john s:name "John" x:john
x:jane s:knows x:john x:john
x:jane rdf:type s:Person x:jane
x:jane s:name "Jane" x:jane
x:jane s:knows x:john x:jane
x:ecorp s:employee x:jane x:jane

At least, this is what I get with Corese and Virtuoso.

But instead I get

?s ?p ?o ?x
rdf:type s:Person x:john
s:name "John" x:john
x:jane s:knows x:john
rdf:type s:Person x:jane
s:name "Jane" x:jane
s:knows x:john x:jane
x:ecorp s:employee x:jane

so the BIND (in this configuration) does not seem to work.

NB: the UNION is not the cause of the problem. I have the same problem without any UNION.

@joernhees joernhees added bug Something isn't working SPARQL labels Jan 27, 2016
@joernhees joernhees added this to the rdflib 4.2.2 milestone Jan 27, 2016
joernhees added a commit to joernhees/rdflib that referenced this issue Feb 27, 2016
joernhees added a commit to joernhees/rdflib that referenced this issue Feb 27, 2016
joernhees added a commit to joernhees/rdflib that referenced this issue Mar 17, 2016
@gromgull gromgull self-assigned this Jan 18, 2017
@gromgull
Copy link
Member

In @joernhees branch, the simple test without a union (simple_problematic_query):

select ?s ?o ?x where {
  ?x s:knows ?o .
  { BIND(?x as ?s) }
}

This is not meant to work. The group has it's own scope, and ?x is not visible inside. This also holds for UNION (which also induces it's own scope).

This is exactly what bind07 tests: https://www.w3.org/2009/sparql/docs/tests/summary.html#bind-bind07

and also bind10: https://www.w3.org/2009/sparql/docs/tests/summary.html#bind-bind10

The tests don't have a simple BIND in a group example, but you can see here that groups and unions should be treated the same: https://www.w3.org/TR/sparql11-query/#variableScope

I would claim to Cortese and Virtuoso are wrong :)

@pchampin
Copy link
Contributor Author

I agree that the simple_problematic_query is supposed to return NULL for ?s, not x:jane. The query was oversimplified, but a more accurate simple_problematic_query would be:

select ?s ?o ?x where {
  ?x s:knows ?o .
  { ?x a s:Person. BIND(?x as ?s) }
}

Now, the result should be (?s=x:jane, ?o=x:john, ?x=x:jane).

Indeed, the group would return two bindings: (?s=?x=x:jane) and (?s=?x=x:john),
but only the first one would pass the outer scope, which constrains ?x further.

The same thing happens in the original query I proposed. So I claim that Corese and Virtuoso are not wrong :)
BTW, I checked with Corese: it passes tests bind07 and bind10, and it returns NULL for ?s with @joernhees ' original simple_problematic_query.

But granted, this is a tricky problem! :-/

@gromgull
Copy link
Member

@pchampin thanks for the quick clarification! Even though it's one year since you first reported the issue!

I wasn't really very confident in declaring Virtuoso/Corese wrong, so I didn't close the issue :)

I see my error now, the bind doesn't see vars from outside, but that's not what you try to do. You use the bind to "rename" a variable inside, which then has another name outside.

I'll dig into it again!

@gromgull gromgull mentioned this issue Jan 18, 2017
@gromgull
Copy link
Member

So I fixed it. It was again caused by complications from doing lazy join evaluations (where the SPARQL engine "illegally" passes bindings from one side of a join into the other), just like: #615

These illegally passed bindings sometimes have to be forgotten, to fix scoping rules. Here we forgot too much. Your solution was very close @joernhees!

Although the examples given here now all work, I am not totally confident I have gotten them all. I think there are probably more edge-cases with sub-queries and/or exists clauses where the internal variables sort of have their own space. (I have more or less ignored the "substitute" function defined here: https://www.w3.org/TR/sparql11-query/#sparqlAlgebraEval) Doing #619 will probably highlight more.

@joernhees
Copy link
Member

awesome, thanks for fixing that... i guess #601 can be closed? (as far as i can see you rebased the stuff from it that made sense?)

gromgull added a commit that referenced this issue Jan 19, 2017
This was the same error as #580, but for SubQueries instead of binds.
Same fix as
c1b29ae

Excempt vars bound in the local scope from forgetting.
gromgull added a commit that referenced this issue Jan 19, 2017
This was the same error as #580, but for SubQueries instead of binds.
Same fix as
c1b29ae

Excempt vars bound in the local scope from forgetting.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working SPARQL
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants