On 8/10/2012 19:40, Andy Seaborne wrote:
On 10/08/12 02:12, Holger Knublauch wrote:
Andy,

we are evaluating the move to 2.7.3 and have been immediately hit by
what looks like a change of SPARQL semantics in ARQ. See the attached
Java test which returns "Test" in 272 but null in 273. The query is
really simple:

     SELECT *
     WHERE {
         {
             BIND ("Test" AS ?label) .
         } .
         BIND (?label AS ?result) .
     }

but ?label is no longer visible in the outer BIND. The same happens if
you replace the inner BIND with a BGP that binds ?label, but I wanted to
make the example model independent.

So my obvious question: is this the intended behavior, why the change etc?

2.7.3 is right - 2.7.2. is wrong (plain old bug, fixed due to having to clarify scoping in the SPARQL spec so I went back and check ARQ).

>          {
>              BIND ("Test" AS ?label) .
>          } .
>          BIND (?label AS ?result) .

That's a join of the inner, first BIND and the outer BIND.

The Outer BIND applies to the immediately preceeding BGP. BIND binds quite tightly (if you'll forgive the pun).

The preceeding BGP is actually empty - it's between the "}" and
"BIND (?label AS ?result) ."

Think of it as :

    {
        { BIND ("Test" AS ?label) . }
        {} BIND (?label AS ?result) .
    }

technically, that's structurally different but it stresses the empty part before second BIND.

The important factor is the scope of ?label.

The query joins "BIND ("Test" AS ?label)" and
"BIND (?label AS ?result)". So it evals "BIND (?label AS ?result)" not in the context of the "BIND ("Test" AS ?label)" i.e. the use of ?label in "BIND (?label AS ?result)" is unbound.

Thanks Andy. I cannot claim that I understand this yet. Nor do I believe many of our users will. Where does the "hidden {}" come from?

The pattern that I don't see how to solve with the new design is as follows:

    {
        ?x ex:prop ?value .
        FILTER (?value some condition) .
    }
    BIND (my:function(?value) AS ?result) .

I only want my:function to execute if the FILTER is passed. Therefore I cannot simply write

    ?x ex:prop ?value .
    FILTER (?value some condition) .
    BIND (my:function(?value) AS ?result) .

because 2.7.2 moves the FILTER to the end and makes it effectively

    ?x ex:prop ?value .
    BIND (my:function(?value) AS ?result) .
    FILTER (?value some condition) .

I had introduced the inner { ... } block to ensure that the FILTER is grouped together with the previous line. The mantra "SPARQL executes from the inside out" was just easy enough to explain, but now inner blocks seem to have become useless.

How would I have to rewrite the first query to make sure that the BIND is only executed after the FILTER, but with ?value bound?

Thanks
Holger

Reply via email to