You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2013/09/20 17:01:48 UTC

svn commit: r1525025 - in /jena/trunk/jena-arq/src: main/java/com/hp/hpl/jena/sparql/algebra/ main/java/com/hp/hpl/jena/sparql/algebra/op/ test/java/com/hp/hpl/jena/sparql/algebra/

Author: andy
Date: Fri Sep 20 15:01:47 2013
New Revision: 1525025

URL: http://svn.apache.org/r1525025
Log:
JENA-535
Process the expression in a LeftJoin condition.

Modified:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/BeforeAfterVisitor.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByType.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByTypeBase.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpWalker.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/Transformer.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpFilter.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpProcedure.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TestTransformQuads.java

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/BeforeAfterVisitor.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/BeforeAfterVisitor.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/BeforeAfterVisitor.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/BeforeAfterVisitor.java Fri Sep 20 15:01:47 2013
@@ -71,6 +71,11 @@ public class BeforeAfterVisitor extends 
     }
 
     @Override
+    protected void visitLeftJoin(OpLeftJoin op) { 
+        before(op) ; op.visit(mainVisitor) ; after(op) ;
+    }
+
+    @Override
     protected void visitExt(OpExt op) { 
         before(op) ; op.visit(mainVisitor) ; after(op) ;
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByType.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByType.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByType.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByType.java Fri Sep 20 15:01:47 2013
@@ -38,6 +38,8 @@ public abstract class OpVisitorByType im
 
     protected abstract void visitFilter(OpFilter op) ;
     
+    protected abstract void visitLeftJoin(OpLeftJoin op) ;
+    
     protected void visitModifer(OpModifier opMod)
     { visit1(opMod) ; }
 
@@ -87,7 +89,7 @@ public abstract class OpVisitorByType im
     
     @Override
     public void visit(OpLeftJoin opLeftJoin)
-    { visit2(opLeftJoin) ; }
+    { visitLeftJoin(opLeftJoin) ; }
 
     @Override
     public void visit(OpDiff opDiff)

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByTypeBase.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByTypeBase.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByTypeBase.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpVisitorByTypeBase.java Fri Sep 20 15:01:47 2013
@@ -39,6 +39,9 @@ public class OpVisitorByTypeBase extends
 
     @Override
     protected void visitFilter(OpFilter op) {}    
+    
+    @Override
+    protected void visitLeftJoin(OpLeftJoin op) { } 
 
     @Override
     protected void visitModifer(OpModifier opMod) 

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpWalker.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpWalker.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpWalker.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpWalker.java Fri Sep 20 15:01:47 2013
@@ -43,84 +43,88 @@ public class OpWalker
         op.visit(walkerVisitor) ;
     }
     
-    static class WalkerVisitor extends OpVisitorByType
-    {
-        private final OpVisitor beforeVisitor ;
-        private final OpVisitor afterVisitor ;
+    static class WalkerVisitor extends OpVisitorByType {
+        private final OpVisitor   beforeVisitor ;
+        private final OpVisitor   afterVisitor ;
         protected final OpVisitor visitor ;
 
-        public WalkerVisitor(OpVisitor visitor, OpVisitor beforeVisitor, OpVisitor afterVisitor)
-        { 
+        public WalkerVisitor(OpVisitor visitor, OpVisitor beforeVisitor, OpVisitor afterVisitor) {
             this.visitor = visitor ;
             this.beforeVisitor = beforeVisitor ;
             this.afterVisitor = afterVisitor ;
         }
 
-        public WalkerVisitor(OpVisitor visitor) { this(visitor, null, null) ; }
-        
-        protected final void before(Op op)
-        { 
+        public WalkerVisitor(OpVisitor visitor) {
+            this(visitor, null, null) ;
+        }
+
+        protected final void before(Op op) {
             if ( beforeVisitor != null )
                 op.visit(beforeVisitor) ;
         }
 
-        protected final void after(Op op)
-        {
+        protected final void after(Op op) {
             if ( afterVisitor != null )
                 op.visit(afterVisitor) ;
         }
-        
+
         @Override
-        protected void visit0(Op0 op)         
-        {  
+        protected void visit0(Op0 op) {
             before(op) ;
-            if ( visitor != null ) op.visit(visitor) ;
+            if ( visitor != null )
+                op.visit(visitor) ;
             after(op) ;
         }
 
         @Override
-        protected void visit1(Op1 op)
-        {
+        protected void visit1(Op1 op) {
             before(op) ;
-            if ( op.getSubOp() != null ) op.getSubOp().visit(this) ;
-            if ( visitor != null ) op.visit(visitor) ; 
+            if ( op.getSubOp() != null )
+                op.getSubOp().visit(this) ;
+            if ( visitor != null )
+                op.visit(visitor) ;
             after(op) ;
         }
 
         @Override
-        protected void visitFilter(OpFilter op)
-        {
+        protected void visitFilter(OpFilter op) {
             visit1(op) ;
         }
-        
+
         @Override
-        protected void visit2(Op2 op)
-        {
+        protected void visitLeftJoin(OpLeftJoin op) {
+            visit2(op) ;
+        }
+
+        @Override
+        protected void visit2(Op2 op) {
             before(op) ;
-            if ( op.getLeft() != null ) op.getLeft().visit(this) ;
-            if ( op.getRight() != null ) op.getRight().visit(this) ;
-            if ( visitor != null ) op.visit(visitor) ;      
-            after(op) ; 
+            if ( op.getLeft() != null )
+                op.getLeft().visit(this) ;
+            if ( op.getRight() != null )
+                op.getRight().visit(this) ;
+            if ( visitor != null )
+                op.visit(visitor) ;
+            after(op) ;
         }
-        
+
         @Override
-        protected void visitN(OpN op)
-        {
+        protected void visitN(OpN op) {
             before(op) ;
-            for ( Iterator<Op> iter = op.iterator() ; iter.hasNext() ; )
-            {
+            for (Iterator<Op> iter = op.iterator(); iter.hasNext();) {
                 Op sub = iter.next() ;
                 sub.visit(this) ;
             }
-            if ( visitor != null ) op.visit(visitor) ;
+            if ( visitor != null )
+                op.visit(visitor) ;
             after(op) ;
         }
 
         @Override
-        protected void visitExt(OpExt op)
-        {
+        protected void visitExt(OpExt op) {
             before(op) ;
-            if ( visitor != null ) op.visit(visitor) ;
+            if ( visitor != null )
+                op.visit(visitor) ;
             after(op) ;
         }
     }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/Transformer.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/Transformer.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/Transformer.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/Transformer.java Fri Sep 20 15:01:47 2013
@@ -116,14 +116,6 @@ public class Transformer
         }
     }
 
-    /** Transform an Op - not recursively */ 
-    public static Op transformOne(Transform transform, Op op)
-    {
-        OpTransformApplyOne visitor = new OpTransformApplyOne(transform) ;
-        op.visit(visitor) ;
-        return visitor.result ;
-    }
-    
     // To allow subclassing this class, we use a singleton pattern 
     // and theses protected methods.
     protected Op transformation(Transform transform, Op op, OpVisitor beforeVisitor, OpVisitor afterVisitor)
@@ -157,7 +149,6 @@ public class Transformer
         Op r = transformApply.result() ;
         return r ;
     }
-
     
     protected Transformer() { }
     
@@ -190,14 +181,14 @@ public class Transformer
             return pop() ; 
         }
 
-        private ExprList transform(ExprList exprList, ExprTransform exprTransform)
+        private static ExprList transform(ExprList exprList, ExprTransform exprTransform)
         {
             if ( exprList == null || exprTransform == null )
                 return exprList ;
             return ExprTransformer.transform(exprTransform, exprList) ;
         }
 
-        private Expr transform(Expr expr, ExprTransform exprTransform)
+        private static Expr transform(Expr expr, ExprTransform exprTransform)
         {
             if ( expr == null || exprTransform == null )
                 return expr ;
@@ -232,7 +223,7 @@ public class Transformer
         public void visit(OpAssign opAssign)
         { 
             VarExprList varExpr = opAssign.getVarExprList() ;
-            VarExprList varExpr2 = process(varExpr) ;
+            VarExprList varExpr2 = process(varExpr, exprTransform) ;
             OpAssign opAssign2 = opAssign ;
             if ( varExpr != varExpr2 )
                 opAssign2 = OpAssign.assignDirect(opAssign.getSubOp(), varExpr2) ;
@@ -243,14 +234,14 @@ public class Transformer
         public void visit(OpExtend opExtend)
         { 
             VarExprList varExpr = opExtend.getVarExprList() ;
-            VarExprList varExpr2 = process(varExpr) ;
+            VarExprList varExpr2 = process(varExpr, exprTransform) ;
             OpExtend opExtend2 = opExtend ;
             if ( varExpr != varExpr2 )
                 opExtend2 = OpExtend.extendDirect(opExtend.getSubOp(), varExpr2) ;
             visit1(opExtend2) ;
         }
         
-        private VarExprList process(VarExprList varExpr)
+        private static VarExprList process(VarExprList varExpr, ExprTransform exprTransform)
         {
             List<Var> vars = varExpr.getVars() ;
             VarExprList varExpr2 = new VarExprList() ;
@@ -268,17 +259,47 @@ public class Transformer
                 if ( e != e2 )
                     changed = true ;
             }
-            if ( ! changed ) return varExpr ;
+            if ( ! changed ) 
+                return varExpr ;
             return varExpr2 ;
         }
 
+        private static ExprList process(ExprList exprList, ExprTransform exprTransform)
+        {
+            if ( exprList == null )
+                return null ;
+            ExprList exprList2 = new ExprList() ;
+            boolean changed = false ;
+            for ( Expr e : exprList )
+            {
+                Expr e2 = process(e, exprTransform) ;
+                exprList2.add(e2) ; 
+                if ( e != e2 )
+                    changed = true ;
+            }
+            if ( ! changed ) 
+                return exprList ;
+            return exprList2 ;
+        }
+        
+        private static Expr process(Expr expr, ExprTransform exprTransform)
+        {
+            Expr e = expr ;
+            Expr e2 =  e ;
+            if ( e != null )
+                e2 = transform(e, exprTransform) ;
+            if ( e == e2 ) 
+                return expr ;
+            return e2 ;
+        }
+
         @Override
         public void visit(OpGroup opGroup)
         {
             boolean changed = false ;
 
             VarExprList varExpr = opGroup.getGroupVars() ;
-            VarExprList varExpr2 = process(varExpr) ;
+            VarExprList varExpr2 = process(varExpr, exprTransform) ;
             if ( varExpr != varExpr2 )
                 changed = true ;
             
@@ -373,23 +394,36 @@ public class Transformer
             if ( opFilter.getSubOp() != null )
                 subOp = pop() ;
             boolean changed = ( opFilter.getSubOp() != subOp ) ;
-            
-            // Now any expressions.
-            ExprList ex = new ExprList() ;
-            for ( Expr e : opFilter.getExprs() )
-            {
-                Expr e2 = transform(e, exprTransform) ;
-                ex.add(e2) ;
-                if ( e != e2 )
-                    changed = true ;
-            }
+
+            ExprList ex = opFilter.getExprs() ;
+            ExprList ex2 = process(ex, exprTransform) ;
             OpFilter f = opFilter ;
-            if ( changed )
-                f = (OpFilter)OpFilter.filter(ex, subOp) ;
+            if ( ex != ex2 )
+                f = (OpFilter)OpFilter.filter(ex2, subOp) ;
             push(f.apply(transform, subOp)) ;
         }
         
         @Override
+        protected void visitLeftJoin(OpLeftJoin op) {
+            Op left = null ;
+            Op right = null ;
+        
+            // Must do right-left because the pushes onto the stack were left-right. 
+            if ( op.getRight() != null )
+                right = pop() ;
+            if ( op.getLeft() != null )
+                left = pop() ;
+            
+            ExprList exprs = op.getExprs() ;
+            ExprList exprs2 = process(exprs, exprTransform) ;
+            OpLeftJoin x = op ;
+            if ( exprs != exprs2 )
+                x = OpLeftJoin.createLeftJoin(left, right, exprs2) ;
+            Op opX = x.apply(transform, left, right) ; 
+            push(opX) ;
+        }
+
+        @Override
         protected void visitExt(OpExt op)
         {
             push(transform.transform(op)) ;
@@ -462,39 +496,4 @@ public class Transformer
         public Op transform(OpService opService, Op subOp)
         { return opService ; } 
     }
-    
-    static class OpTransformApplyOne extends OpVisitorByType
-    {
-        private final Transform transform ;
-        Op result ;
-
-        OpTransformApplyOne(Transform transform)
-        {
-            this.transform = transform ;
-        }
-
-        @Override
-        protected void visitN(OpN op)
-        { result = op.apply(transform, op.getElements()) ; }
-
-        @Override
-        protected void visit2(Op2 op)
-        { result = op.apply(transform, op.getLeft(), op.getRight()) ; }
-
-        @Override
-        protected void visit1(Op1 op)
-        { result = op.apply(transform, op.getSubOp()) ; }
-
-        @Override
-        protected void visit0(Op0 op)
-        { result = op.apply(transform) ; }
-
-        @Override
-        protected void visitFilter(OpFilter op)
-        { result = op.apply(transform, op.getSubOp()) ; }
-        
-        @Override
-        protected void visitExt(OpExt op)
-        { result = op.apply(transform) ; }
-    }
 }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpFilter.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpFilter.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpFilter.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpFilter.java Fri Sep 20 15:01:47 2013
@@ -28,7 +28,7 @@ import com.hp.hpl.jena.sparql.util.NodeI
 
 public class OpFilter extends Op1
 {
-    ExprList expressions ;
+    protected ExprList expressions ;
     
     public static Op filter(Expr expr, Op op)
     {
@@ -54,15 +54,6 @@ public class OpFilter extends Op1
         return f ;
     }
     
-    
-//    public static Op filterRaw(ExprList exprs, Op op)
-//    {
-//        if ( exprs.isEmpty() )
-//            return op ;
-//        OpFilter f = new OpFilter(exprs, op) ;
-//        return f ;
-//    }
-
     /** Make a OpFilter - guarantteed to return an OpFilter */
     public static OpFilter filterDirect(ExprList exprs, Op op)
     {

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpProcedure.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpProcedure.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpProcedure.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/op/OpProcedure.java Fri Sep 20 15:01:47 2013
@@ -30,7 +30,7 @@ import com.hp.hpl.jena.sparql.util.NodeI
 /** General procedure in algebra evaluation (a stored procedure facility)
  *  Syntax (ARQ extension): CALL <iri>(?x, ?y+3)
  *  
- *  See also the similary algebra form for property functions.  The difference is in argument handling.
+ *  See also the similar algebra form for property functions.  The difference is in argument handling.
  *  A property function has a URI and two argment lists, one for subject, one for objects.
  *  A procedure is a URI and a list of arguments. */
 public class OpProcedure extends Op1

Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TestTransformQuads.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TestTransformQuads.java?rev=1525025&r1=1525024&r2=1525025&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TestTransformQuads.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/TestTransformQuads.java Fri Sep 20 15:01:47 2013
@@ -117,12 +117,52 @@ public class TestTransformQuads extends 
     @Test public void quads33() { test ( "{ GRAPH ?g { { SELECT ?x WHERE { ?x ?p ?g } } } }",
                                           "(project (?x)",
                                           "  (quadpattern (quad ?g ?x ?/p ?/g)))") ; }
+
+    // JENA-535
+    @Test public void quads34() { test ( "{ ?s ?p ?o OPTIONAL { FILTER NOT EXISTS { ?x ?y ?z } } }",
+                                         "(conditional",
+                                         "  (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?s ?p ?o))",
+                                         "  (filter (notexists",
+                                         "             (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?x ?y ?z)))",
+                                         "    (table unit)))") ; }
+    
+    // NOT EXISTS in left join expression. 
+    @Test public void quads35() { test ( "{ ?s ?p ?o OPTIONAL { FILTER NOT EXISTS { ?x ?y ?z } } }",
+                                         false,
+                                         "(leftjoin",
+                                         "   (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?s ?p ?o))",
+                                         "   (table unit)",
+                                         "   (notexists",
+                                         "     (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?x ?y ?z))))") ; }
+        
+    // NOT EXISTS in left join expression. 
+    @Test public void quads36() { test ( "{ ?s ?p ?o OPTIONAL { FILTER NOT EXISTS { GRAPH ?g { ?x ?y ?z } } } }",
+                                         false,
+                                         "(leftjoin",
+                                         "   (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?s ?p ?o))",
+                                         "   (table unit)",
+                                         "   (notexists",
+                                         "     (quadpattern (?g ?x ?y ?z))))") ; }
+    
+    // NOT EXISTS in BIND 
+    @Test public void quads37() { test ( "{ BIND ( true && NOT EXISTS { GRAPH ?g { ?x ?y ?z } } AS ?X ) }",
+                                         "(extend ((?X (&& true (notexists",
+                                         "                         (quadpattern (quad ?g ?x ?y ?z))))))",
+                                         "    (table unit))") ; }
+
+        
+
+    private static void test(String patternString, String... strExpected) {
+        test(patternString, true, strExpected) ;
+    }
+    
     
-    private static void test(String patternString, String... strExpected)
+    private static void test(String patternString, boolean optimize, String... strExpected)
     {
         Query q = QueryFactory.create("SELECT * WHERE "+patternString) ;
         Op op = Algebra.compile(q) ;
-        op = Algebra.optimize(op) ;
+        if ( optimize )
+            op = Algebra.optimize(op) ;
         op = Algebra.toQuadForm(op) ;
         
         Op op2 = SSE.parseOp(StrUtils.strjoinNL(strExpected)) ;