On 02/06/14 22:41, Gary King wrote:
I recently ran into an edge case and want to clarify my understanding.

The issue is related to the difference between

1. select * { :x :p ?v . FILTER(?v = 1) }

2. select * { :x :p ?v . { FILTER(?v = 1) } }

Where #2 can never return results because ?v is not in scope when the filter is 
evaluated.

I'm interested in a more complex query that uses UNION. Suppose I have this 
data:

<http://ex#a1> <http://ex#p1> <http://ex#b1> .
<http://ex#c1> <http://ex#p2> <http://ex#no-match> .
<http://ex#c2> <http://ex#p2> <http://ex#b1> .
<http://ex#a2> <http://ex#p1> <http://ex#b2> .
<http://ex#c1> <http://ex#p3> <http://ex#no-match> .
<http://ex#c2> <http://ex#p3> <http://ex#b2> .

This query will return results

prefix : <http://ex#>
select * {
   ?a :p1 ?b .
   ?c :p2 ?d . filter( ?b = ?d )
}

as will this one

prefix : <http://ex#>
select * {
   ?a :p1 ?b .
   ?c :p3 ?d . filter( ?b = ?d )
}

Now lets combine them with UNION:

prefix : <http://ex#>
select * {
   ?a :p1 ?b .
   { ?c :p2 ?d . filter( ?b = ?d ) }
   union
   { ?c :p3 ?d . filter( ?b = ?d ) }
}

(base <http://example/base/>
  (prefix ((: <http://ex#>))
    (join
      (bgp (triple ?a :p1 ?b))
      (union
        (filter (= ?b ?d)
          (bgp (triple ?c :p2 ?d)))
        (filter (= ?b ?d)
          (bgp (triple ?c :p3 ?d)))))))


Whoopts! No results. I believe that the reason is the same as with the simpler 
FILTER case above: ?join1 is not in scope when the filter is evaluated. 
Obviously in this case the filters are the same and I can ask the query I want 
by moving it outside the UNION:

prefix : <http://ex#>
select * {
   ?a :p1 ?b .
   { ?c :p2 ?d . }
   union
   { ?c :p3 ?d . }
   filter( ?b = ?d )
}

(base <http://example/base/>
  (prefix ((: <http://ex#>))
    (filter (= ?b ?d)
      (join
        (bgp (triple ?a :p1 ?b))
        (union
          (bgp (triple ?c :p2 ?d))
          (bgp (triple ?c :p3 ?d)))))))


But it still seems counter-intuitive to me that adding the union should change 
the meaning of the query so much.


I'd appreciate any insight on this.

thanks,


See the algrebra expressions for the two queries above. The FILTER is in different places - inside and outside the UNION.

{} means, very loosely, evaluate this part and use the results.

In the algebra is like function call : evaluate the arguments then call the operation with the results of sub-evaluation.

Just as (1+2) * (3+4) becomes 3 * 7 and hence is 21.

int x = 8
sqrt(x+1)

is a function call to sqrt(9), not passing "x+1" into sqrt.

        Andy


Reply via email to