summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-19 20:25:28 +0100
committerGunnar Aastrand Grimnes <gromgull@gmail.com>2017-01-19 20:31:46 +0100
commitf017a829d999f2237a83b25221446a7d9de0cb90 (patch)
tree2540dafa6c2898828f348a9a8becf5e8f36e6149
parent89c49f673e87bbf63d024ddd39b5e04cda460a6a (diff)
downloadrdflib-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.py36
-rw-r--r--rdflib/plugins/sparql/sparql.py13
-rw-r--r--rdflib/plugins/sparql/update.py12
-rw-r--r--test/test_initbindings.py3
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__":