summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Aastrand Grimnes <gromgull@gmail.com>2015-11-28 09:08:06 +0100
committerGunnar Aastrand Grimnes <gromgull@gmail.com>2015-11-28 09:08:06 +0100
commit6200934ace658ca05de693956b37623ce3a545eb (patch)
tree3ab65e07cce1f308ed980280ce369865e08f9df8
parentfa4172cc51a39b698ab7cb81240243ed6d62db1c (diff)
downloadrdflib-initbindings-fix.tar.gz
Fix initBindings handling. Fixes #294initbindings-fix
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 place. This also adds a bunch of tests.
-rw-r--r--rdflib/plugins/sparql/algebra.py4
-rw-r--r--rdflib/plugins/sparql/evaluate.py36
-rw-r--r--rdflib/plugins/sparql/parserutils.py3
-rw-r--r--test/test_initbindings.py108
4 files changed, 132 insertions, 19 deletions
diff --git a/rdflib/plugins/sparql/algebra.py b/rdflib/plugins/sparql/algebra.py
index fcaac02d..099594a3 100644
--- a/rdflib/plugins/sparql/algebra.py
+++ b/rdflib/plugins/sparql/algebra.py
@@ -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)
@@ -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):
diff --git a/rdflib/plugins/sparql/evaluate.py b/rdflib/plugins/sparql/evaluate.py
index 948077be..cec3451a 100644
--- a/rdflib/plugins/sparql/evaluate.py
+++ b/rdflib/plugins/sparql/evaluate.py
@@ -26,7 +26,7 @@ from rdflib.plugins.sparql.evalutils import (
_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):
@@ -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(
diff --git a/rdflib/plugins/sparql/parserutils.py b/rdflib/plugins/sparql/parserutils.py
index 233e88e8..b5c25600 100644
--- a/rdflib/plugins/sparql/parserutils.py
+++ b/rdflib/plugins/sparql/parserutils.py
@@ -147,6 +147,9 @@ class CompValue(OrderedDict):
self.name = name
self.update(values)
+ def clone(self):
+ return CompValue(self.name, **self)
+
def __str__(self):
return self.name + "_" + OrderedDict.__str__(self)
diff --git a/test/test_initbindings.py b/test/test_initbindings.py
index 75923858..f3228ecb 100644
--- a/test/test_initbindings.py
+++ b/test/test_initbindings.py
@@ -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)
@@ -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
@@ -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])