Skip to content

Commit

Permalink
Merge pull request #555 from RDFLib/initbindings-fix
Browse files Browse the repository at this point in the history
Fix initBindings handling. Fixes #294
  • Loading branch information
joernhees committed Nov 28, 2015
2 parents f8b658f + 6200934 commit 911427d
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 19 deletions.
4 changes: 3 additions & 1 deletion rdflib/plugins/sparql/algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def Filter(expr, p):
def Extend(p, expr, var):
return CompValue('Extend', p=p, expr=expr, var=var)

def Values(res):
return CompValue('values', res=res)

def Project(p, PV):
return CompValue('Project', p=p, PV=PV)
Expand Down Expand Up @@ -511,7 +513,7 @@ def translateValues(v):
for vals in v.value:
res.append(dict(zip(v.var, vals)))

return CompValue('values', res=res)
return Values(res)


def translate(q):
Expand Down
36 changes: 29 additions & 7 deletions rdflib/plugins/sparql/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
_filter, _eval, _join, _diff, _minus, _fillTemplate, _ebv)

from rdflib.plugins.sparql.aggregates import evalAgg

from rdflib.plugins.sparql.algebra import Join, ToMultiSet, Values

def evalBGP(ctx, bgp):

Expand Down Expand Up @@ -410,16 +410,38 @@ def evalQuery(graph, query, initBindings, base=None):

ctx.prologue = query.prologue

main = query.algebra

if initBindings:
for k, v in initBindings.iteritems():
# add initBindings as a values clause

values = {} # no dict comprehension in 2.6 :(
for k,v in initBindings.iteritems():
if not isinstance(k, Variable):
k = Variable(k)
ctx[k] = v
# ctx.push() # nescessary?
values[k] = v

main = main.clone() # clone to not change prepared q
main['p'] = main.p.clone()
# Find the right place to insert MultiSet join
repl = main.p
if repl.name == 'Slice':
repl['p'] = repl.p.clone()
repl = repl.p
if repl.name == 'Distinct':
repl['p'] = repl.p.clone()
repl = repl.p
if repl.p.name == 'OrderBy':
repl['p'] = repl.p.clone()
repl = repl.p
if repl.p.name == 'Extend':
repl['p'] = repl.p.clone()
repl = repl.p

repl['p'] = Join(repl.p, ToMultiSet(Values([values])))

# TODO: Vars?

main = query.algebra

# import pdb; pdb.set_trace()
if main.datasetClause:
if ctx.dataset is None:
raise Exception(
Expand Down
3 changes: 3 additions & 0 deletions rdflib/plugins/sparql/parserutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ def __init__(self, name, **values):
self.name = name
self.update(values)

def clone(self):
return CompValue(self.name, **self)

def __str__(self):
return self.name + "_" + OrderedDict.__str__(self)

Expand Down
108 changes: 97 additions & 11 deletions test/test_initbindings.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@

from nose import SkipTest

from rdflib.plugins.sparql import prepareQuery


from rdflib import ConjunctiveGraph, URIRef, Literal, Namespace, Variable
g = ConjunctiveGraph()


def testStr():
raise SkipTest('skipped - pending fix for #294')
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>)}"))
assert a==b, "STR: %r != %r"%(a,b)

def testIsIRI():
raise SkipTest('skipped - pending fix for #294')
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>)}"))
assert a==b, "isIRI: %r != %r"%(a,b)

def testIsBlank():
raise SkipTest('skipped - pending fix for #294')
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>)}"))
assert a==b, "isBlank: %r != %r"%(a,b)

def testIsLiteral():
raise SkipTest('skipped - pending fix for #294')
def testIsLiteral():
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')}"))
assert a==b, "isLiteral: %r != %r"%(a,b)

def testUCase():
raise SkipTest('skipped - pending fix for #294')
def testUCase():
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')}"))
assert a==b, "UCASE: %r != %r"%(a,b)
Expand All @@ -41,13 +38,102 @@ def testNoFunc():
b = set(g.query("SELECT ?target WHERE { } VALUES (?target) {('example')}"))
assert a==b, "no func: %r != %r"%(a,b)

def testOrderBy():
a = set(g.query("SELECT ?target WHERE { } ORDER BY ?target", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } ORDER BY ?target VALUES (?target) {('example')}"))
assert a==b, "orderby: %r != %r"%(a,b)

def testOrderByFunc():
a = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target VALUES (?target) {('example')} "))
assert a==b, "orderbyFunc: %r != %r"%(a,b)

def testNoFuncLimit():
a = set(g.query("SELECT ?target WHERE { } LIMIT 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } LIMIT 1 VALUES (?target) {('example')}"))
assert a==b, "limit: %r != %r"%(a,b)

def testOrderByLimit():
a = set(g.query("SELECT ?target WHERE { } ORDER BY ?target LIMIT 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } ORDER BY ?target LIMIT 1 VALUES (?target) {('example')}"))
assert a==b, "orderbyLimit: %r != %r"%(a,b)

def testOrderByFuncLimit():
a = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target LIMIT 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target LIMIT 1 VALUES (?target) {('example')}"))
assert a==b, "orderbyFuncLimit: %r != %r"%(a,b)

def testNoFuncOffset():
a = set(g.query("SELECT ?target WHERE { } OFFSET 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } OFFSET 1 VALUES (?target) {('example')}"))
assert a==b, "offset: %r != %r"%(a,b)

def testNoFuncLimitOffset():
a = set(g.query("SELECT ?target WHERE { } LIMIT 1 OFFSET 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } LIMIT 1 OFFSET 1 VALUES (?target) {('example')}"))
assert a==b, "limitOffset: %r != %r"%(a,b)

def testOrderByLimitOffset():
a = set(g.query("SELECT ?target WHERE { } ORDER BY ?target LIMIT 1 OFFSET 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT ?target WHERE { } ORDER BY ?target LIMIT 1 OFFSET 1 VALUES (?target) {('example')}"))
assert a==b, "orderbyLimitOffset: %r != %r"%(a,b)

def testOrderByFuncLimitOffset():
a = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target LIMIT 1 OFFSET 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT (UCASE(?target) as ?r) WHERE { } ORDER BY ?target LIMIT 1 OFFSET 1 VALUES (?target) {('example')}"))
assert a==b, "orderbyFuncLimitOffset: %r != %r"%(a,b)

def testDistinct():
a = set(g.query("SELECT DISTINCT ?target WHERE { }", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT DISTINCT ?target WHERE { } VALUES (?target) {('example')}"))
assert a==b, "distinct: %r != %r"%(a,b)

def testDistinctOrderBy():
a = set(g.query("SELECT DISTINCT ?target WHERE { } ORDER BY ?target", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT DISTINCT ?target WHERE { } ORDER BY ?target VALUES (?target) {('example')}"))
assert a==b, "distinctOrderby: %r != %r"%(a,b)

def testDistinctOrderByLimit():
a = set(g.query("SELECT DISTINCT ?target WHERE { } ORDER BY ?target LIMIT 1", initBindings={'target': Literal('example')}))
b = set(g.query("SELECT DISTINCT ?target WHERE { } ORDER BY ?target LIMIT 1 VALUES (?target) {('example')}"))
assert a==b, "distinctOrderbyLimit: %r != %r"%(a,b)

def testPrepare():
q = prepareQuery('SELECT ?target WHERE { }')
r = list(g.query(q))
e = [(None,)] # TODO: https://github.com/RDFLib/rdflib/issues/554
assert r == e, 'prepare: %r != %r'%(r,e)

r = list(g.query(q, initBindings={'target': Literal('example')}))
e = [(Literal('example'),)]
assert r == e, 'prepare: %r != %r'%(r, e)

r = list(g.query(q))
e = [(None,)] # TODO: https://github.com/RDFLib/rdflib/issues/554
assert r == e, 'prepare: %r != %r'%(r,e)


def testData():
data = ConjunctiveGraph()
data += [ ( URIRef('urn:a'), URIRef('urn:p'), Literal('a') ),
( URIRef('urn:b'), URIRef('urn:p'), Literal('b') ) ]

a = set(g.query("SELECT ?target WHERE { ?target <urn:p> ?val }", initBindings={'val': Literal('a')}))
b = set(g.query("SELECT ?target WHERE { ?target <urn:p> ?val } VALUES (?val) {('a')}"))
assert a==b, "data: %r != %r"%(a,b)

def testAsk():
a = set(g.query("ASK { }", initBindings={'target': Literal('example')}))
b = set(g.query("ASK { } VALUES (?target) {('example')}"))
assert a==b, "ask: %r != %r"%(a,b)


EX = Namespace("http://example.com/")
g2 = ConjunctiveGraph()
g2.bind('', EX)
g2.add((EX['s1'], EX['p'], EX['o1']))
g2.add((EX['s2'], EX['p'], EX['o2']))

def testStringKey():
results = list(g2.query("SELECT ?o WHERE { ?s :p ?o }", initBindings={"s": EX['s1']}))
assert len(results) == 1, results
Expand All @@ -63,11 +149,11 @@ def testVariableKey():
def testVariableKeyWithQuestionMark():
results = list(g2.query("SELECT ?o WHERE { ?s :p ?o }", initBindings={Variable("?s"): EX['s1']}))
assert len(results) == 1, results


if __name__ == "__main__":

import sys
import nose
if len(sys.argv)==1:
if len(sys.argv)==1:
nose.main(defaultTest=sys.argv[0])

0 comments on commit 911427d

Please sign in to comment.