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