diff options
author | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2017-01-19 20:25:28 +0100 |
---|---|---|
committer | Gunnar Aastrand Grimnes <gromgull@gmail.com> | 2017-01-19 20:31:46 +0100 |
commit | f017a829d999f2237a83b25221446a7d9de0cb90 (patch) | |
tree | 2540dafa6c2898828f348a9a8becf5e8f36e6149 | |
parent | 89c49f673e87bbf63d024ddd39b5e04cda460a6a (diff) | |
download | rdflib-f017a829d999f2237a83b25221446a7d9de0cb90.tar.gz |
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)
-rw-r--r-- | rdflib/plugins/sparql/evaluate.py | 36 | ||||
-rw-r--r-- | rdflib/plugins/sparql/sparql.py | 13 | ||||
-rw-r--r-- | rdflib/plugins/sparql/update.py | 12 | ||||
-rw-r--r-- | test/test_initbindings.py | 3 |
4 files changed, 18 insertions, 46 deletions
diff --git a/rdflib/plugins/sparql/evaluate.py b/rdflib/plugins/sparql/evaluate.py index e79e5149..8d22c2d9 100644 --- a/rdflib/plugins/sparql/evaluate.py +++ b/rdflib/plugins/sparql/evaluate.py @@ -446,41 +446,13 @@ def evalConstructQuery(ctx, query): def evalQuery(graph, query, initBindings, base=None): - ctx = QueryContext(graph) - ctx.prologue = query.prologue + initBindings = dict( ( Variable(k),v ) for k,v in initBindings.iteritems() ) - main = query.algebra + ctx = QueryContext(graph, initBindings=initBindings) - if initBindings: - # 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) - 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? + ctx.prologue = query.prologue + main = query.algebra if main.datasetClause: if ctx.dataset is None: diff --git a/rdflib/plugins/sparql/sparql.py b/rdflib/plugins/sparql/sparql.py index 69505561..c012a8fc 100644 --- a/rdflib/plugins/sparql/sparql.py +++ b/rdflib/plugins/sparql/sparql.py @@ -197,8 +197,8 @@ class FrozenBindings(FrozenDict): since before """ if not _except : _except = [] - - return FrozenBindings(self.ctx, (x for x in self.iteritems() if x[0] in _except or before[x[0]] is None)) + # bindings from initBindings are newer forgotten + return FrozenBindings(self.ctx, (x for x in self.iteritems() if x[0] in _except or x[0] in self.ctx.initBindings or before[x[0]] is None)) def remember(self, these): """ @@ -213,8 +213,10 @@ class QueryContext(object): Query context - passed along when evaluating the query """ - def __init__(self, graph=None, bindings=None): - self.bindings = bindings or Bindings() + def __init__(self, graph=None, bindings=None, initBindings=None): + self.initBindings = initBindings + self.bindings = Bindings(d=bindings or []) + if initBindings: self.bindings.update(initBindings) if isinstance(graph, ConjunctiveGraph): self._dataset = graph @@ -233,9 +235,8 @@ class QueryContext(object): def clone(self, bindings=None): r = QueryContext( - self._dataset if self._dataset is not None else self.graph) + self._dataset if self._dataset is not None else self.graph, bindings or self.bindings, initBindings=self.initBindings) r.prologue = self.prologue - r.bindings.update(bindings or self.bindings) r.graph = self.graph r.bnodes = self.bnodes return r diff --git a/rdflib/plugins/sparql/update.py b/rdflib/plugins/sparql/update.py index 57c5bf46..f5a5f2eb 100644 --- a/rdflib/plugins/sparql/update.py +++ b/rdflib/plugins/sparql/update.py @@ -252,7 +252,7 @@ def evalCopy(ctx, u): dstg += srcg -def evalUpdate(graph, update, initBindings=None): +def evalUpdate(graph, update, initBindings={}): """ http://www.w3.org/TR/sparql11-update/#updateLanguage @@ -274,15 +274,11 @@ def evalUpdate(graph, update, initBindings=None): for u in update: - ctx = QueryContext(graph) + initBindings = dict( ( Variable(k),v ) for k,v in initBindings.iteritems() ) + + ctx = QueryContext(graph, initBindings=initBindings) ctx.prologue = u.prologue - if initBindings: - for k, v in initBindings.iteritems(): - if not isinstance(k, Variable): - k = Variable(k) - ctx[k] = v - # ctx.push() # nescessary? try: if u.name == 'Load': diff --git a/test/test_initbindings.py b/test/test_initbindings.py index ad94db4f..e44f9fff 100644 --- a/test/test_initbindings.py +++ b/test/test_initbindings.py @@ -150,6 +150,9 @@ def testVariableKeyWithQuestionMark(): results = list(g2.query("SELECT ?o WHERE { ?s :p ?o }", initBindings={Variable("?s"): EX['s1']})) assert len(results) == 1, results +def testFilter(): + results = list(g2.query("SELECT ?o WHERE { ?s :p ?o FILTER (?s = ?x)}", initBindings={Variable("?x"): EX['s1']})) + assert len(results) == 1, results if __name__ == "__main__": |