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

Most upvoted comments

Your person = "Donna Fales" is a string. You are expected to pass a RDFLib object into initBindings, wrap the string in a literal and it should work.