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

Reply via email to