Author: andy
Date: Tue Oct 29 13:41:00 2013
New Revision: 1536710

URL: http://svn.apache.org/r1536710
Log:
JENA-577 : Rewrite merging bindings when an OpProject is in the middel of an 
execution (sub-SELECT).

Added:
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProjectMerge.java
      - copied, changed from r1536659, 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProject2.java
Removed:
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProject2.java
Modified:
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProject.java
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectBase.java
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectNamed.java
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingUtils.java
    
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/main/OpExecutor.java

Modified: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProject.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProject.java?rev=1536710&r1=1536709&r2=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProject.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProject.java
 Tue Oct 29 13:41:00 2013
@@ -16,30 +16,23 @@
  * limitations under the License.
  */
 
-package com.hp.hpl.jena.sparql.engine.binding;
+package com.hp.hpl.jena.sparql.engine.binding ;
 
 import java.util.Collection ;
 
 import com.hp.hpl.jena.sparql.core.Var ;
 
-public class  BindingProject extends BindingProjectBase
-{
-    final Collection<Var> projectionVars ; 
-
-    public BindingProject(Collection<Var> vars, Binding bind)
-    { 
-        this(vars, bind, null) ;
-    }
+/** Project a binding, given a specific collection of visible variables */
+public class BindingProject extends BindingProjectBase {
+    final Collection<Var> projectionVars ;
 
-    public BindingProject(Collection<Var> vars, Binding bind, Binding parent)
-    { 
-        super(bind, parent) ;
+    public BindingProject(Collection<Var> vars, Binding bind) {
+        super(bind) ;
         this.projectionVars = vars ;
     }
 
     @Override
-    protected boolean accept(Var var)
-    {
+    protected boolean accept(Var var) {
         return projectionVars.contains(var) ;
     }
 }

Modified: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectBase.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectBase.java?rev=1536710&r1=1536709&r2=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectBase.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectBase.java
 Tue Oct 29 13:41:00 2013
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-package com.hp.hpl.jena.sparql.engine.binding;
+package com.hp.hpl.jena.sparql.engine.binding ;
 
 import java.util.ArrayList ;
 import java.util.Iterator ;
@@ -25,60 +25,43 @@ import java.util.List ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.sparql.core.Var ;
 
-public abstract class BindingProjectBase extends BindingBase
-{
-    private Binding binding ;
-    private List<Var> actualVars = null ;
-
-    public BindingProjectBase(Binding bind)
-    { 
-        this(bind, null) ;
-    }
-    
-    public BindingProjectBase(Binding bind, Binding parent)
-    { 
-        super(parent) ;
+/** Common framework for projection; 
+ * the projection policy is provided by
+ * abstract method {@linkplain #accept(Var)} 
+ */
+public abstract class BindingProjectBase extends BindingBase {
+    private List<Var>     actualVars = null ;
+    private final Binding binding ;
+
+    public BindingProjectBase(Binding bind) {
+        super(null) ;
         binding = bind ;
     }
 
-//    @Override
-//    protected void add1(Var var, Node node)
-//    { throw new UnsupportedOperationException("BindingProject.add1") ; }
-//
-//    @Override
-//    protected void checkAdd1(Var var, Node node)
-//    {}
+    protected abstract boolean accept(Var var) ;
 
-    protected abstract boolean accept(Var var) ; 
-    
     @Override
-    protected boolean contains1(Var var)
-    {
+    protected boolean contains1(Var var) {
         return accept(var) && binding.contains(var) ;
     }
 
     @Override
-    protected Node get1(Var var)
-    {
-        if ( ! accept(var) )
-            return null ; 
+    protected Node get1(Var var) {
+        if ( !accept(var) )
+            return null ;
         return binding.get(var) ;
     }
 
     @Override
-    protected Iterator<Var> vars1()
-    {
+    protected Iterator<Var> vars1() {
         return actualVars().iterator() ;
     }
 
-    private List<Var> actualVars()
-    {
-        if ( actualVars == null )
-        {
+    private List<Var> actualVars() {
+        if ( actualVars == null ) {
             actualVars = new ArrayList<Var>() ;
             Iterator<Var> iter = binding.vars() ;
-            for ( ; iter.hasNext() ; )
-            {
+            for ( ; iter.hasNext() ; ) {
                 Var v = iter.next() ;
                 if ( accept(v) )
                     actualVars.add(v) ;
@@ -86,27 +69,19 @@ public abstract class BindingProjectBase
         }
         return actualVars ;
     }
-    
+
     @Override
-    protected int size1()
-    {
+    protected int size1() {
         return actualVars().size() ;
     }
-    
-    
-    
-    // NB is the projection and the binding don't overlap it is also empty. 
+
+    // NB is the projection and the binding don't overlap it is also empty.
     @Override
-    protected boolean isEmpty1()
-    {
-        if ( binding.isEmpty() ) return true ;
-        if ( size1() == 0  ) return true ;
+    protected boolean isEmpty1() {
+        if ( binding.isEmpty() )
+            return true ;
+        if ( size1() == 0 )
+            return true ;
         return false ;
-//        for ( Var v : projectionVars )
-//        {
-//            if ( binding.contains(v))  
-//                return false ;
-//        }
-//        return true ;
     }
 }

Modified: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectNamed.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectNamed.java?rev=1536710&r1=1536709&r2=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectNamed.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingProjectNamed.java
 Tue Oct 29 13:41:00 2013
@@ -16,25 +16,21 @@
  * limitations under the License.
  */
 
-package com.hp.hpl.jena.sparql.engine.binding;
+package com.hp.hpl.jena.sparql.engine.binding ;
 
 import com.hp.hpl.jena.sparql.core.Var ;
 
-public class  BindingProjectNamed extends BindingProjectBase //extends 
BindingBase
-{
-    public BindingProjectNamed(Binding bind)
-    { 
-        this(bind, null) ;
-    }
-    
-    public BindingProjectNamed(Binding bind, Binding parent)
-    { 
-        super(bind, parent) ;
+/**
+ * Project only named variables (i.e. hide variables used because of
+ * bNodes or internally generated variables).
+ */
+public class BindingProjectNamed extends BindingProjectBase {
+    public BindingProjectNamed(Binding bind) {
+        super(bind) ;
     }
 
     @Override
-    protected boolean accept(Var var)
-    {
+    protected boolean accept(Var var) {
         return var.isNamedVar() ;
     }
 }

Modified: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingUtils.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingUtils.java?rev=1536710&r1=1536709&r2=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingUtils.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/binding/BindingUtils.java
 Tue Oct 29 13:41:00 2013
@@ -16,7 +16,8 @@
  * limitations under the License.
  */
 
-package com.hp.hpl.jena.sparql.engine.binding;
+package com.hp.hpl.jena.sparql.engine.binding ;
+
 import java.util.Iterator ;
 
 import org.apache.jena.atlas.logging.Log ;
@@ -28,56 +29,70 @@ import com.hp.hpl.jena.sparql.ARQInterna
 import com.hp.hpl.jena.sparql.core.ResultBinding ;
 import com.hp.hpl.jena.sparql.core.Var ;
 
-public class BindingUtils
-{
-    /** Convert a query solution to a binding */ 
-    public static Binding asBinding(QuerySolution qSolution)
-    {
+public class BindingUtils {
+    /** Convert a query solution to a binding */
+    public static Binding asBinding(QuerySolution qSolution) {
         if ( qSolution == null )
             return null ;
         if ( qSolution instanceof ResultBinding )
             // Only named variables.
-            return new BindingProjectNamed( 
((ResultBinding)qSolution).getBinding() ) ;
+            return new 
BindingProjectNamed(((ResultBinding)qSolution).getBinding()) ;
         BindingMap binding = BindingFactory.create() ;
         addToBinding(binding, qSolution) ;
         return binding ;
     }
-        
-    public static void addToBinding(BindingMap binding, QuerySolution 
qSolution)
-    {
+
+    public static void addToBinding(BindingMap binding, QuerySolution 
qSolution) {
         if ( qSolution == null )
             return ;
-        
-        for ( Iterator<String> iter = qSolution.varNames() ; iter.hasNext() ; )
-        {
+
+        for ( Iterator<String> iter = qSolution.varNames() ; iter.hasNext() ; 
) {
             String n = iter.next() ;
-            
+
             RDFNode x = qSolution.get(n) ;
             if ( Var.isBlankNodeVarName(n) )
                 continue ;
             try {
                 binding.add(Var.alloc(n), x.asNode()) ;
-            } catch (ARQInternalErrorException ex)
-            {
+            }
+            catch (ARQInternalErrorException ex) {
                 // bad binding attempt.
-                Log.warn(BindingUtils.class, "Attempt to bind "+n+" when 
already bound") ;
+                Log.warn(BindingUtils.class, "Attempt to bind " + n + " when 
already bound") ;
             }
         }
     }
-    
-    public static void addAll(BindingMap dest, Binding src)
-    {
+
+    public static void addAll(BindingMap dest, Binding src) {
         Iterator<Var> iter = src.vars() ;
-        for ( ; iter.hasNext() ; )
-        {
+        for ( ; iter.hasNext() ; ) {
             Var v = iter.next() ;
             Node n = src.get(v) ;
             dest.add(v, n) ;
         }
     }
-    
-    public static boolean equals(Binding b1, Binding b2)
-    {
-        return BindingBase.equals(b1, b2) ; 
+
+    /** Merge two bindings, assuming they are compatible. */
+    public static Binding merge(Binding bind1, Binding bind2) {
+        //Create binding from LHS
+        BindingMap b2 = BindingFactory.create(bind1) ;
+        Iterator<Var> vIter = bind2.vars() ;
+        // Add any variables from the RHS
+        for ( ; vIter.hasNext() ; ) {
+            Var v = vIter.next() ;
+            if ( ! b2.contains(v) )
+                b2.add(v, bind2.get(v)) ;
+            else {
+                // Checking!
+                Node n1 = bind1.get(v) ;
+                Node n2 = bind2.get(v) ;
+                if ( ! n1.equals(n2) )
+                    Log.warn(BindingUtils.class,  "merge: Mismatch : "+n1+" != 
"+n2);
+            }
+        }
+        return b2 ;
+    }
+
+    public static boolean equals(Binding b1, Binding b2) {
+        return BindingBase.equals(b1, b2) ;
     }
 }

Copied: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProjectMerge.java
 (from r1536659, 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProject2.java)
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProjectMerge.java?p2=jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProjectMerge.java&p1=jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProject2.java&r1=1536659&r2=1536710&rev=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProject2.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/iterator/QueryIterProjectMerge.java
 Tue Oct 29 13:41:00 2013
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-package com.hp.hpl.jena.sparql.engine.iterator;
+package com.hp.hpl.jena.sparql.engine.iterator ;
 
 import java.util.List ;
 
@@ -25,63 +25,50 @@ import com.hp.hpl.jena.sparql.core.Var ;
 import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
 import com.hp.hpl.jena.sparql.engine.QueryIterator ;
 import com.hp.hpl.jena.sparql.engine.binding.Binding ;
-import com.hp.hpl.jena.sparql.engine.binding.BindingProject ;
+import com.hp.hpl.jena.sparql.engine.binding.BindingUtils ;
 import com.hp.hpl.jena.sparql.engine.main.OpExecutor ;
 
-
-public class QueryIterProject2 extends QueryIterRepeatApply
-{
-    List<Var> projectionVars ;
-    private final OpProject opProject ;
+/**
+ * Execute a projection in the middle of an execution. This requires the 
outcome
+ * of each stage of execution (substituion evaluation assumed) to be merged 
with
+ * the input binding. Bindings should already be compatible, otherwise this 
code
+ * should not be used.
+ */
+public class QueryIterProjectMerge extends QueryIterRepeatApply {
+    // This is a merge/substitution join
+    private final OpProject  opProject ;
     private final OpExecutor engine ;
 
-    public QueryIterProject2(OpProject opProject, QueryIterator input, 
OpExecutor engine, ExecutionContext execCxt)
-    {
+    public QueryIterProjectMerge(OpProject opProject, QueryIterator input, 
OpExecutor engine, ExecutionContext execCxt) {
         super(input, execCxt) ;
         this.opProject = opProject ;
         this.engine = engine ;
     }
 
     @Override
-    protected QueryIterator nextStage(Binding binding)
-    {
-        QueryIterator qIter = engine.executeOp(opProject.getSubOp(), 
QueryIterSingleton.create(binding, getExecContext())) ;
-        
-        qIter = new ProjectEnsureBinding(qIter, 
-                                         new 
ProjectEnsureBindingConverter(binding, opProject.getVars()), 
-                                         getExecContext()) ;
-        // Project - ensure binding vars are visible. 
+    protected QueryIterator nextStage(Binding binding) {
+        QueryIterator qIter = engine.executeOp(opProject.getSubOp(),
+                                               
QueryIterSingleton.create(binding, getExecContext())) ;
+
+        qIter = new QueryIterConvert(qIter,
+                                     new 
ProjectEnsureBindingConverter(binding, opProject.getVars()),
+                                     getExecContext()) ;
         return qIter ;
     }
-    
-    static class ProjectEnsureBinding extends QueryIterConvert
-    {
-
-        public ProjectEnsureBinding(QueryIterator iter, Converter c, 
ExecutionContext context)
-        {
-            super(iter, c, context) ;
-        }
-    }
-    
-    static class ProjectEnsureBindingConverter implements 
QueryIterConvert.Converter
-    {
 
-        private final Binding outerBinding ;
+    static class ProjectEnsureBindingConverter implements 
QueryIterConvert.Converter {
+
+        private final Binding   outerBinding ;
         private final List<Var> projectionVars ;
 
-        public ProjectEnsureBindingConverter(Binding outerBinding, List<Var> 
vars)
-        {
+        public ProjectEnsureBindingConverter(Binding outerBinding, List<Var> 
vars) {
             this.outerBinding = outerBinding ;
             this.projectionVars = vars ;
         }
 
         @Override
-        public Binding convert(Binding bind)
-        {
-            Binding b = new BindingProject(projectionVars, bind, outerBinding) 
;
-            return b ;
+        public Binding convert(Binding bind) {
+            return BindingUtils.merge(outerBinding, bind) ;
         }
-        
     }
-
 }

Modified: 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/main/OpExecutor.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/main/OpExecutor.java?rev=1536710&r1=1536709&r2=1536710&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/main/OpExecutor.java
 (original)
+++ 
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/main/OpExecutor.java
 Tue Oct 29 13:41:00 2013
@@ -417,7 +417,7 @@ public class OpExecutor
         }
         // Nested projected : need to ensure the input is seen.
         // ROLL into QueryIterProject
-        QueryIterator qIter = new QueryIterProject2(opProject, input, this, 
execCxt) ;
+        QueryIterator qIter = new QueryIterProjectMerge(opProject, input, 
this, execCxt) ;
         return qIter ;
     }
 


Reply via email to