Skip to content

EXISTS deep injection and SERVICE #275

@pfps

Description

@pfps

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions