On 05/07/2020 20:36, Martynas Jusevičius wrote:
Thanks for the explanation.

What do you mean with "inject" in 1/? ParameterizedSparqlString?

initialBinding is done by making the starting condition for execution a binding of the variables instead of the empty root. (This works nearly always but is affected by variable name scopes - scopes, like subquery, didn't exist when the mechanism was introduced.

ParameterizedSparqlString builds which is parsed so you should be able to put in <_:....>.

    Andy


On Sun, Jul 5, 2020 at 8:53 PM Andy Seaborne <a...@apache.org> wrote:

<_:label> is a syntax feature, not built into the storage or query
execution.

model.createResource("_:" + id));

creates a resource with a strange URI (which is actually illegal by RFC
3986/7).

There are various ways:

1/ The app can put the bnode into the QSM and injected at execution - it
won't become a bnode-variable because that happens in parsing.

2/ To put a concrete node into a query:

String bn = "<_:" + id+">";

then put string into SPARQL syntax:

QueryFactory.create("SELECT * { VALUES ?s {"+bn+"} ?s ?p ?o }");
QueryFactory.create("SELECT * { "+bn+" ?p ?o }");

3/ rewrite the abstract syntax after parsing:

Map<String, Resource> substitutions =
    Collections.singletonMap("s", bnode);
query = QueryFactory.create("SELECT * { ?s ?p ?o }");
query = QueryTransformOps.transformQuery(query, substitutions);

Forms 2 and 3 have the advantage of not relying on how execution works -
QSMs are ingested inthe start of execution and e.g. aren't visible in
subqueries and also interact and bypass with query optimization.

      Andy

On 05/07/2020 15:22, Martynas Jusevičius wrote:
Hi,

I came across a situation where I want to carry over a blank node ID
in a QuerySolutionMap to QueryExecution, to match exact blank node
resources rather than have them as variables.

I found an old thread by Holger on this topic:
https://mail-archives.apache.org/mod_mbox/jena-users/201308.mbox/browser

The suggestion was to use <_:LABEL> URI scheme for blank nodes.
https://jena.apache.org/documentation/query/extension.html#blank-node-labels

Based on that, I tried this logic:

      if (instance.isURIResource()) qsm.add(SPIN.THIS_VAR_NAME, instance);
      if (instance.isAnon()) qsm.add(SPIN.THIS_VAR_NAME,
model.createResource("_:" + instance.getId()));

However I'm not getting the results I expect. So I decided to make an
isolated test:

      @Test
      public void bnodeQueryTest()
      {
          Model model = ModelFactory.createDefaultModel();
          Resource bnode = model.createResource().addProperty(FOAF.name,
"whateverest");
          AnonId id = bnode.getId();

          Query query = QueryFactory.create("SELECT * { ?s ?p ?o }");
          QuerySolutionMap qsm = new QuerySolutionMap();
          qsm.add("s", model.createResource("_:" + id));

          try (QueryExecution qex = QueryExecutionFactory.create(query,
model, qsm))
          {
              ResultSet resultSet = qex.execSelect();

              assertTrue(resultSet.hasNext());
              assertEquals(id, resultSet.next().get("s").asResource().getId());
          }
      }

The test fails on assertTrue() because SELECT returns no results.

Is the test flawed? Am I misunderstanding the use of this URI scheme?
If not, what's the purpose if it cannot match blank nodes in data?

Martynas

Reply via email to