diff --git a/rdflib/plugins/sparql/evaluate.py b/rdflib/plugins/sparql/evaluate.py index e558a8250..48abc9621 100644 --- a/rdflib/plugins/sparql/evaluate.py +++ b/rdflib/plugins/sparql/evaluate.py @@ -141,8 +141,10 @@ def evalLeftJoin(ctx, join): # before we yield a solution without the OPTIONAL part # check that we would have had no OPTIONAL matches # even without prior bindings... - if not any(_ebv(join.expr, b) for b in - evalPart(ctx.thaw(a.remember(join.p1._vars)), join.p2)): + p1_vars = join.p1._vars + if p1_vars is None \ + or not any(_ebv(join.expr, b) for b in + evalPart(ctx.thaw(a.remember(p1_vars)), join.p2)): yield a diff --git a/test-update.py b/test-update.py new file mode 100644 index 000000000..b324f5d8a --- /dev/null +++ b/test-update.py @@ -0,0 +1,71 @@ +from rdflib import * + +ex = Namespace('http://ex.co/') +g = Graph() +g.namespace_manager.bind('', ex) + +g.add((ex.s1, ex.p, ex.o1)) +g.add((ex.s1, ex.p, ex.o2)) +g.add((ex.s1, ex.p, ex.o3)) + +g.add((ex.s2, ex.p, ex.o2)) +g.add((ex.s2, ex.p, ex.o3)) +g.add((ex.s2, ex.p, ex.o4)) +g.add((ex.s2, ex.p, ex.o5)) + +g.add((ex.s3, ex.p, ex.o1)) +g.add((ex.s3, ex.p, ex.o3)) +g.add((ex.s3, ex.p, ex.o5)) + + +print(g.serialize(format="n3")) + +# should be +# :s1 :p :o1, :o2, :o3 . +# :s2 :p :o2, :o3, :o4, :o5 . +# :s3 :p :o1, :o3, :o5 . + +print '---' + +print(g.query(""" +PREFIX : + +SELECT ?o ?new +WHERE { + :s1 :p ?o . + :s2 :p ?o . + OPTIONAL { + :s3 :p ?o . + BIND(:s4 as ?new) + } +} +""").serialize(format="csv")) + +# should be +# :o2 , +# :o3 , :s4 + +print '---' + +g.update(""" +PREFIX : + +DELETE { :s1 :p ?o } +INSERT { ?new :p ?o } +WHERE { + :s1 :p ?o . + :s2 :p ?o . + OPTIONAL { + :s3 :p ?o . + BIND(:s4 as ?new) + } +} +""") + +print(g.serialize(format="n3")) + +# should now be +# :s1 :p :o1 . +# :s2 :p :o2, :o3, :o4, :o5 . +# :s3 :p :o1, :o3, :o5 . +# :s4 :p :o3 .