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

Reply via email to