Joshua, Andy, Thank you very much for your explanations. I had been tricked by two different queries, of which one worked on the projection, and the other accidentally with an unbound variable quite as well. Now I've changed my published queries to the suggested style, putting the VALUES at the start of the where clause. All works fine now, and the VALUES clause hopefully may be helpful for other users of the query as a starting point for tweaking.
Cheers, Joachim -----Ursprüngliche Nachricht----- Von: Andy Seaborne [mailto:[email protected]] Gesendet: Donnerstag, 30. Oktober 2014 22:06 An: [email protected] Betreff: Re: VALUES for setting required language in a query On 30/10/14 19:55, Joshua TAYLOR wrote: > On Thu, Oct 30, 2014 at 3:00 PM, Neubert, Joachim <[email protected]> wrote: >> I try to use the VALUES clause to set a language used in different places in >> a query, e.g. >> >> prefix skos: <http://www.w3.org/2004/02/skos/core#> >> select ?s ?prefLabel ?altLabel >> where { >> ?s skos:prefLabel ?prefLabel . >> optional {?s skos:altLabel ?altLabel }. >> filter (lang(?prefLabel) = ?language && lang(?altLabel) = >> ?language) } values ?language { "en" } >> >> This gives an empty result. When I move the values clause into the where >> block, the expected triples are found. >> >> In some cases, the values clause outside the where block works fine (e.g. >> also the third example at >> http://www.w3.org/TR/sparql11-query/#inline-data-examples). I'm sure the >> explanation is in the docs, but I couldn't figure it out. > > I'm not entirely sure, but perhaps `values` outside just get joined > with the *selected* variables, whereas the `values` inside gets joined > with all in-scope variables. If you add ?language to the list of > selected variables, .e.g, > > select ?s ?prefLabel ?altLabel ?language ... > > do you get the results that you'd expect? > > //JT Joshua hits the key point here - the WHERE {} block is evaluated separately from the VALUES block. In fact, it's joined in just after the WHERE{} block, and just before the projection. At the point of evaluation of the WHERE block is evaluated, ?language is not defined and the FILTER is false. If ?language were defined in the WHERE-{} part, the optimizer would execute it by setting ?language. But it is just used in a FILTER and not bound. The better style (IMO) is to put the VALUES block at the start of the query pattern: prefix skos: <http://www.w3.org/2004/02/skos/core#> select ?s ?prefLabel ?altLabel where { VALUES ?language { "en" } ?s skos:prefLabel ?prefLabel . optional {?s skos:altLabel ?altLabel }. filter (lang(?prefLabel) = ?language && lang(?altLabel) = ?language) } Andy
