Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bindings of variables are not carried into FILTERs in (NOT) EXISTS clauses #615

Closed
pfps opened this issue Mar 22, 2016 · 7 comments
Closed
Labels
bug Something isn't working discussion SPARQL
Milestone

Comments

@pfps
Copy link

pfps commented Mar 22, 2016

My understanding is that variable bindings carry into FILTER constructs. However, this sometime does not work in rdflib. I have a short example that shows this, with a FILTER inside a FILTER EXISTS. My belief is that the binding of ?this from the outermost portion should be visible in the innermost portion, meaning that the ?this = ?valu will only filter out solutions where the two variables have different bindings. However, all solutions appear to be filtered out, which would happen if the ?this binding(s) from the outermost portion are not making their way into the innermost portion.

This is very similar to the example in SPARQL 1.1 Query Language section 8.3.3.

bug2-rdflib.txt

@joernhees
Copy link
Member

so you're complaining that the following query doesn't return any results:

 SELECT ?this WHERE { 
  VALUES ?this { <y> <n> } 
  FILTER (EXISTS {
    VALUES ?valu { <y> <o> } 
    FILTER ( ?this = ?valu )
  })
 }

This is actually by design in SPARQL: The inner-most query is evaluated first.

The consequence is that we have the following execution order:

  EXISTS {
    VALUES ?valu { <y> <o> } 
    FILTER ( ?this = ?valu )  # ?this is an unknown variable here
  }

As the ?this in the above is still unbound the equality always fails, so the result of the EXISTS is false. Then the following is executed:

 SELECT ?this WHERE { 
  VALUES ?this { <y> <n> } 
  FILTER (false)
 }

Which correctly doesn't result in a binding for ?this.

@pfps
Copy link
Author

pfps commented Mar 28, 2016

I don't think that this reasoning is correct.

Look at Section 8.3.3 of SPARQL 1.1 Query Language, at
https://www.w3.org/TR/sparql11-query/#idp899488.

The example there is

PREFIX : http://example.com/
SELECT \* WHERE {
        ?x :p ?n
        FILTER NOT EXISTS {
                ?x :q ?m .
                FILTER(?n = ?m)
        }
}

which is analogous to my example and the wording says that ?n is bound in the
inner filter.

peter

On 03/28/2016 03:39 AM, Jörn Hees wrote:

so you're complaining that the following query doesn't return any results:

|SELECT ?this WHERE { VALUES ?this { } FILTER (EXISTS { VALUES ?valu {
} FILTER ( ?this = ?valu ) }) } |

This is actually by design in SPARQL: The inner-most query is evaluated first.

The consequence is that we have the following execution order:

|EXISTS { VALUES ?valu { } FILTER ( ?this = ?valu ) # ?this is an
unknown variable here } |

As the |?this| in the above is still unbound the equality always fails, so the
result of the |EXISTS| is false. Then the following is executed:

|SELECT ?this WHERE { VALUES ?this { } FILTER (false) } |

Which correctly doesn't result in a binding for |?this|.


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#615 (comment)

@joernhees joernhees reopened this Mar 28, 2016
@pfps
Copy link
Author

pfps commented Apr 9, 2016

Is this a bug or is my understanding of SPARQL incorrect?

@joernhees
Copy link
Member

To be honest, i'm not sure, which is why re-opened this...

The link you point to seems to support your view-point, but jena seems to support mine:

$ sparql -v --data=empty.n3 --query=<(echo '
>  SELECT ?this WHERE {
>   VALUES ?this { <y> <n> }
>   FILTER (EXISTS {
>     VALUES ?valu { <y> <o> }
>     FILTER ( ?this = ?valu )
>   })
>  }
> ')

  1 SELECT  ?this
  2 WHERE
  3   { VALUES ?this { <y> <n> }
  4     FILTER EXISTS { VALUES ?valu { <y> <o> }
  5                     FILTER ( ?this = ?valu )
  6                   }
  7   }

13:39:05 INFO  exec                 :: QUERY
  SELECT  ?this
  WHERE
    { VALUES ?this { <y> <n> }
      FILTER EXISTS { VALUES ?valu { <y> <o> }
                      FILTER ( ?this = ?valu )
                    }
    }
13:39:05 INFO  exec                 :: ALGEBRA
  (project (?this)
    (filter (exists
               (table empty))
      (table (vars ?this)
        (row [?this <file:///dev/fd/y>])
        (row [?this <file:///dev/fd/n>])
      )))
--------
| this |
========
--------

That said, the SPARQL parsing and its conversion to an algebra isn't the easiest code and i just didn't find the time to look into this properly.

@joernhees joernhees added this to the rdflib 4.2.2 milestone Apr 10, 2016
@pfps
Copy link
Author

pfps commented Apr 13, 2016

I put together the example from the SPARQL 1.1 QL spec and it has the incorrect behaviour as well.

[Again problems with uploading - I'll put it into a separate comment.]
Uploading q.txt…

@pfps
Copy link
Author

pfps commented Apr 13, 2016

import rdflib
from rdflib import Namespace
from rdflib.term import Literal
from rdflib.namespace import XSD

EX = Namespace("http://example.com/")

g = rdflib.Graph()
g.add ( ( EX.a, EX.p, Literal(1,datatype=XSD.integer) ) ) 
g.add ( ( EX.a, EX.q, Literal(1,datatype=XSD.integer) ) ) 
g.add ( ( EX.a, EX.q, Literal(2,datatype=XSD.integer) ) ) 

g.add ( ( EX.b, EX.p, Literal(3.0,datatype=XSD.decimal) ) ) 
g.add ( ( EX.b, EX.q, Literal(4.0,datatype=XSD.decimal) ) ) 
g.add ( ( EX.b, EX.q, Literal(5.0,datatype=XSD.decimal) ) ) 


print "MINUS"
query = """PREFIX : <http://example.com/>
SELECT * WHERE {
    ?x :p ?n
    MINUS {
        ?x :q ?m .
        FILTER(?n = ?m)
    }
}"""
result = g.query(query)
for row in result : print row
assert len(result) == 2

print "FILTER NOT EXISTS"
query = """PREFIX : <http://example.com/>
SELECT * WHERE {
    ?x :p ?n
    FILTER NOT EXISTS {
        ?x :q ?m .
        FILTER(?n = ?m)
    }
}"""
result = g.query(query)
for row in result : print row
assert len(result) == 1

@joernhees joernhees added the bug Something isn't working label May 10, 2016
@gromgull
Copy link
Member

I believe this was broken by: 6200934

@gromgull gromgull changed the title bindings of variables are not carried into FILTERs bindings of variables are not carried into FILTERs in (NOT) EXISTS clauses Jan 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working discussion SPARQL
Projects
None yet
Development

No branches or pull requests

3 participants