I have a SPARQL query that uses several OPTIONAL
, some inside the others, as well as UNIONs
. I had heard that those are the ingredients for trouble but didn’t have problem until now, and I can’t understand what’s wrong.
The query is running on a local Virtuoso Open Source, latest version, and has been tried on the SPARQL GUI endpoint as well as through python’s rdflib
module.
The query is the following
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?n ?x ?y ?z ?xLabel ?yLabel ?zLabel ?y_aggr
?y_aggrLabel ?yColor ?yColorLabel
WHERE
{ { ?n rdf:type <http://example.com/test#Paper>
BIND(?n AS ?y)
}
UNION
{ ?n ?p1 ?y .
?y rdf:type <http://example.com/test#Paper>
}
UNION
{ ?n <http://example.com/test#Paper> ?y }
OPTIONAL
{ ?y rdfs:label ?yLabelOp }
BIND(coalesce(?yLabelOp, ?y) AS ?yLabel)
OPTIONAL
{ ?y <http://example.com/test#author> ?y_aggr
OPTIONAL
{ ?y_aggr rdfs:label ?y_aggrLabel }
OPTIONAL
{ ?y_aggr <http://example.com/test#team> ?yColor
OPTIONAL
{ ?yColor rdfs:label ?yColorLabel }
}
}
{ ?n rdf:type <http://example.com/test#submittedDate_s>
BIND(?n AS ?x)
}
UNION
{ ?n ?p2 ?x .
?x rdf:type <http://example.com/test#submittedDate_s>
}
UNION
{ ?n <http://example.com/test#submittedDate_s> ?x }
OPTIONAL
{ ?x rdfs:label ?xLabelOp }
BIND(coalesce(?xLabelOp, ?x) AS ?xLabel)
OPTIONAL
{ { ?n rdf:type <http://example.com/test#keyword>
BIND(?n AS ?z)
}
UNION
{ ?n ?p3 ?z .
?z rdf:type <http://example.com/test#keyword>
}
UNION
{ ?n <http://example.com/test#keyword> ?z }
OPTIONAL
{ ?z rdfs:label ?zLabelOp }
BIND(coalesce(?zLabelOp, ?z) AS ?zLabel)
}
}
ORDER BY ?x
That triple union might look strange, since some of the statements don’t make sense, but it’s there because this query is generated by some code, and serves as a sort of “prepared statement” that could have anything in it, so I must be prepared to have it be either a Class or Property. I have a suspicion the problem comes from there but I can’t really do without it.
The strange part is that encapsulated OPTIONAL
clause: Some results come back with ?yColorLabel
bound, but ?yColor
doesn’t have a value. I don’t understand how that’s possible, since the optional clause binding yColorLabel
should only be evaluated when I have properly retrieved yColor
.
The strangest part is that the value in yColorLabel
is consistent with my data and is what should be returned if the proper yColor
was returned; I just don’t understand how that variable becomes empty.