-
Notifications
You must be signed in to change notification settings - Fork 2
Description
It appears to me that one problem with deep injection for EXISTS is its interaction with SERVICE.
The substitution definition of EXISTS, although it has lots of problems, at least has a simple interaction with SERVICE. The query after substitution is sent to the remote service.
Deep injection (everywhere), on the other hand, requires the injected binding set(s) to be sent to the remote service, which then needs to take this information into account when evaluating the query. It needs to do this so that FILTER expressions in the SERVICE pattern can be correctly evaluated. This means that the remote service needs to correctly process these binding set(s), i.e., that the remote service implements SPARQL 1.2. (Actually the remote service needs to implement a little bit more than SPARQL 1.2, as the binding set(s) need to be applied outside of EXISTS patterns.) This is a problem if not all SPARQL services are updated to SPARQL 1.2 at the same time.
There is a second poblem. If the binding set(s) contain(s) a binding value that is a blank node this blank node needs to be injected. But blank nodes do not necessarily survive the transition to the remote service correctly. The worst case would be if a blank node identifier is transmitted and incorrectly interpreted as a different blank node that is in the graph being queried by the remote service. As Olaf has already mentioned, this can be alleviated by minting new blank nodes, except that even the identifiers for these new blank nodes might be in the remote graph.
So what to do? I suppose that it would be possible to just exclude SERVICE patterns from deep injection. But it appears to me that this would result in three different evaluation spaces as follows:
1/ Normal evaluation outside EXISTS, where bindings do not affect interior group graph patterns.
2/ Evaluation inside EXISTS, where there are bindings being injected.
3/ Evaluation inside SERVICE, where the EXISTS bindings from outside the SERVICE are not being injected.
Here are several queries showing the differences:
SELECT ?x WHERE {
BIND ex:a AS ?x .
FILTER ( ?x = ex:a )
}
one result
SELECT ?x WHERE {
BIND ex:a AS ?x .
{ FILTER ( ?x = ex:a ) }
}
no results
SELECT ?x WHERE {
BIND ex:a AS ?x .
FILTER EXISTS { FILTER ( ?x = ex:a ) }
}
one result
SELECT ?x WHERE {
BIND ex:a AS ?x .
FILTER EXISTS { { FILTER ( ?x = ex:a ) } }
}
one result
SELECT ?x WHERE {
BIND ex:a AS ?x .
SERVICE remote:b { FILTER ( ?x = ex:a ) }
}
no results
SELECT ?x WHERE {
BIND ex:a AS ?x .
FILTER EXISTS { SERVICE remote:b { FILTER ( ?x = ex:a ) } }
}
no results