diff options
| author | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2015-11-28 09:08:06 +0100 |
|---|---|---|
| committer | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2015-11-28 09:08:06 +0100 |
| commit | 6200934ace658ca05de693956b37623ce3a545eb (patch) | |
| tree | 3ab65e07cce1f308ed980280ce369865e08f9df8 | |
| parent | fa4172cc51a39b698ab7cb81240243ed6d62db1c (diff) | |
| download | rdflib-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.py | 4 | ||||
| -rw-r--r-- | rdflib/plugins/sparql/evaluate.py | 36 | ||||
| -rw-r--r-- | rdflib/plugins/sparql/parserutils.py | 3 | ||||
| -rw-r--r-- | test/test_initbindings.py | 108 |
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]) |
