
|
If you were logged in you would be able to see more operations.
|
|
|
Environment:
|
Tested with the MemoryStore.
|
|
The following test case evaluates two nearly identical queries, one places a value inline, the other uses bindings. However, only the first query returns any results.
The second query only fails if the fist optional graph matches results in the data set, but fails the filter condition.
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:test="urn:test:"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<test:Person rdf:about="urn:test:person">
<test:name>decoy</test:name>
</test:Person>
<test:Person rdf:about="urn:test:friend"/>
</rdf:RDF>
TupleQuery qry;
qry = con.prepareTupleQuery("SELECT * WHERE { OPTIONAL { ?s <urn:test:name> ?absent } OPTIONAL { ?s a ?present } FILTER ( ?s = <urn:test:friend> ) }");
assertTrue(qry.evaluate().hasNext());
qry = con.prepareTupleQuery("SELECT * WHERE { OPTIONAL { ?s <urn:test:name> ?absent } OPTIONAL { ?s a ?present } FILTER ( ?s = $var ) }");
qry.setBinding("var", con.getValueFactory().createURI("urn:test:friend"));
assertTrue(qry.evaluate().hasNext()); // fails here
|
|
Actually, the first evaluation fails and the second is correct. The query should not produce any results due to the left-associativeness of optionals. Since there are urn:test:name statements, the first optional matches at least one statement, which binds ?s to the value urn:test:person. This, of course, makes the filter fail.
The first query probably fails to evaluate properly due to an invalid query optimization.
The problem was located in SameTermFilterOptimizer, which inlined "variable assignments" even in optional parts of a query, which influenced the result of optional joins.
|
|