The same problem (invalid query string) using QueryTransformOps.transformQuery().
On Sun, Jul 5, 2020 at 11:34 PM Martynas Jusevičius <[email protected]> wrote: > > ParameterizedSparqlString does not work either (not related to bnodes). > > With a mapping ?minCount => 0, it produces an invalid query string: > > SELECT (count(*) AS ?cardinality) > WHERE > { <http://spinrdf.org/spin#Templates> > <http://spinrdf.org/spin#body> ?value > FILTER bound(0) > } > HAVING ( ?cardinality < 0 ) > > On Sun, Jul 5, 2020 at 10:31 PM Andy Seaborne <[email protected]> wrote: > > > > > > > > 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 <[email protected]> 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 > > >>>
