rdflib: sparql: Variables bound with initBindings not working in some functions
When I bind a varialbe with initBindings and apply to it a function like STR, UCASE or isLiteral, I get an unexpected result. Using a BIND or VALUES clause instead of initBindings gives the expected result.
Example:
from rdflib import ConjunctiveGraph, URIRef, Literal
g = ConjunctiveGraph()
print("=== without function ===")
print("initBindings:")
for r in g.query("SELECT ?target WHERE { }", initBindings={'target': Literal('example')}): print(r)
print("BIND:")
for r in g.query("SELECT ?target WHERE { BIND('example' AS ?target) }"): print(r)
print("VALUES:")
for r in g.query("SELECT ?target WHERE { } VALUES (?target) {('example')}"): print(r)
print("")
print("=== isLiteral ===")
print("initBindings:")
for r in g.query("SELECT (isLiteral(?target) AS ?r) WHERE { }", initBindings={'target': Literal('example')}): print(r)
print("BIND:")
for r in g.query("SELECT (isLiteral(?target) AS ?r) WHERE { BIND ('example' AS ?target) }"): print(r)
print("VALUES:")
for r in g.query("SELECT (isLiteral(?target) AS ?r) WHERE { } VALUES (?target) {('example')}"): print(r)
print("")
print("=== UCASE ===")
print("initBindings:")
for r in g.query("SELECT (UCASE(?target) AS ?r) WHERE { }", initBindings={'target': Literal('example')}): print(r)
print("BIND:")
for r in g.query("SELECT (UCASE(?target) AS ?r) WHERE { BIND('example' AS ?target) }"): print(r)
print("VALUES:")
for r in g.query("SELECT (UCASE(?target) AS ?r) WHERE { } VALUES (?target) {('example')}"): print(r)
output:
=== without function ===
initBindings:
(rdflib.term.Literal(u'example'),)
BIND:
(rdflib.term.Literal(u'example'),)
VALUES:
(rdflib.term.Literal(u'example'),)
=== isLiteral ===
initBindings:
(None,)
BIND:
(rdflib.term.Literal(u'true', datatype=rdflib.term.URIRef(u'http://www.w3.org/2001/XMLSchema#boolean')),)
VALUES:
(rdflib.term.Literal(u'true', datatype=rdflib.term.URIRef(u'http://www.w3.org/2001/XMLSchema#boolean')),)
=== UCASE ===
initBindings:
(None,)
BIND:
(rdflib.term.Literal(u'EXAMPLE'),)
VALUES:
(rdflib.term.Literal(u'EXAMPLE'),)
In order to bisect I used this testcase:
failed = False
try:
from rdflib import ConjunctiveGraph, URIRef, Literal
g = ConjunctiveGraph()
a = set(g.query("SELECT (STR(?target) AS ?r) WHERE { }", initBindings={'target': URIRef('example:a')}))
b = set(g.query("SELECT (STR(?target) AS ?r) WHERE { } VALUES (?target) {(<example:a>)}"))
if a != b: failed = True
a = set(g.query("SELECT (isIRI(?target) AS ?r) WHERE { }", initBindings={'target': URIRef('example:a')}))
b = set(g.query("SELECT (isIRI(?target) AS ?r) WHERE { } VALUES (?target) {(<example:a>)}"))
if a != b: failed = True
a = set(g.query("SELECT (isBlank(?target) AS ?r) WHERE { }", initBindings={'target': URIRef('example:a')}))
b = set(g.query("SELECT (isBlank(?target) AS ?r) WHERE { } VALUES (?target) {(<example:a>)}"))
if a != b: failed = True
a = set(g.query("SELECT (isLiteral(?target) AS ?r) WHERE { }", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT (isLiteral(?target) AS ?r) WHERE { } VALUES (?target) {('example')}"))
if a != b: failed = True
a = set(g.query("SELECT (UCASE(?target) AS ?r) WHERE { }", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT (UCASE(?target) AS ?r) WHERE { } VALUES (?target) {('example')}"))
if a != b: failed = True
a = set(g.query("SELECT ?target WHERE { }", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } VALUES (?target) {('example')}"))
if a != b: failed = True
except:
print("Can't test")
exit(125)
if failed:
print("bad")
exit(1)
else:
print("good")
exit(0)
I had problems to bisect this. It could be that it only fails some of the time (or I am unable to bisect). It fails starting with commit 1456fe707c225ea0d85056b495a056529c793654. Take a look at the diff: Changing e = _eval(extend.expr, c.forget(ctx)) back to e = _eval(extend.expr, c) solves this problem. Of course it breaks other things, for example the dawg test case bind07 (explanation). That’s all I found out.
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Comments: 18 (15 by maintainers)
Commits related to this issue
- test for #294 — committed to RDFLib/rdflib by gromgull 11 years ago
- Fix initBindings handling. Fixes #294 This changes initBinding handling from adding values in the context object, to actually changing the query algebra and inserting a values clause in the right pla... — committed to RDFLib/rdflib by gromgull 9 years ago
- Merge pull request #555 from RDFLib/initbindings-fix Fix initBindings handling. Fixes #294 — committed to RDFLib/rdflib by joernhees 9 years ago
- Merge branch 'master' (4.2.2-dev) into 5.0.0-dev * master: (49 commits) Update reference to "Emulating container types" Avoid class reference to imported function Prevent RDFa parser from faili... — committed to RDFLib/rdflib by joernhees 8 years ago
- Fix initBindings in SPARQL initBindings are now special fixed bindings, they are always in scope in all parts of the query. Fixes #294 (once and for all) — committed to RDFLib/rdflib by gromgull 7 years ago
- Fix initBindings in SPARQL initBindings are now special fixed bindings, they are always in scope in all parts of the query. Fixes #294 (once and for all) — committed to RDFLib/rdflib by gromgull 7 years ago
Your
person = "Donna Fales"is a string. You are expected to pass a RDFLib object intoinitBindings, wrap the string in a literal and it should work.