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 2016/05/21 18:54:22 UTC

[02/23] jena git commit: Deal with marked "todo" items

Deal with marked "todo" items

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/663f0667
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/663f0667
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/663f0667

Branch: refs/heads/master
Commit: 663f066764fcda37ff71bcd47127f539a6247d9b
Parents: cebdc3b
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Apr 25 19:22:42 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat May 21 18:29:13 2016 +0100

----------------------------------------------------------------------
 .../algebra/walker/ApplyTransformVisitor.java   | 103 ++++---
 .../sparql/algebra/walker/OpVisitorByType.java  |   6 +-
 .../algebra/walker/OpVisitorByTypeAndExpr.java  |  20 +-
 .../jena/sparql/algebra/walker/Walker.java      |   6 +
 .../sparql/algebra/walker/WalkerVisitor0.java   | 308 +++++++++++++++++++
 .../jena/sparql/expr/ExprTransformer.java       |  11 +
 6 files changed, 398 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
index 126e985..499ab72 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
@@ -20,6 +20,7 @@ package org.apache.jena.sparql.algebra.walker;
 
 import java.util.* ;
 
+import org.apache.jena.atlas.lib.InternalErrorException ;
 import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.query.SortCondition ;
 import org.apache.jena.sparql.algebra.Op ;
@@ -64,34 +65,25 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
         return pop(exprStack) ;
     }
     
-    private static boolean ISOLATE = false ;
-
-    protected Op transform(Op op) {
-        // XXX XXX
-        //if ( ISOLATE ) { }
-        
-        int x1 = opStack.size() ;
-        int x2 = exprStack.size() ;
-        try {
-            // reuse this ApplyTransformVisitor? with stack checking?
-            return Walker.transform(op, this, beforeVisitor, afterVisitor) ;
-        } finally {
-            int y1 = opStack.size() ;
-            int y2 = exprStack.size() ;
-            if ( x1 != y1 )
-                System.err.println("Misaligned opStack") ;
-            if ( x2 != y2 )
-                System.err.println("Misaligned exprStack") ;
-        }
-    }
-    
+//    protected Op transform(Op op) {
+//        int x1 = opStack.size() ;
+//        int x2 = exprStack.size() ;
+//        try {
+//            return Walker.transform(op, this, beforeVisitor, afterVisitor) ;
+//        } finally {
+//            int y1 = opStack.size() ;
+//            int y2 = exprStack.size() ;
+//            if ( x1 != y1 )
+//                System.err.println("Misaligned opStack") ;
+//            if ( x2 != y2 )
+//                System.err.println("Misaligned exprStack") ;
+//        }
+//    }
+
+    // These three could be calls within WalkerVisitor followed by "collect".
     protected Expr transform(Expr expr) {
-        // XXX XXX
-        //if ( ISOLATE ) { }
-        
         int x1 = opStack.size() ;
         int x2 = exprStack.size() ;
-        // reuse this ApplyTransformVisitor? with stack checking?
         try {
             return Walker.transform(expr, this, beforeVisitor, afterVisitor) ;
         } finally {
@@ -112,6 +104,25 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
         return exprList2 ;
     }
 
+    protected List<SortCondition> transform(List<SortCondition> conditions) {
+        List<SortCondition> conditions2 = new ArrayList<>() ;
+        boolean changed = false ;
+
+        for ( SortCondition sc : conditions ) {
+            Expr e = sc.getExpression() ;
+            Expr e2 = transform(e) ;
+            conditions2.add(new SortCondition(e2, sc.getDirection())) ;
+            if ( e != e2 )
+                changed = true ;
+        }
+        if ( changed )
+            return conditions2 ;
+        else
+            return conditions ;
+  }
+
+    // Interact with WalkerVisitor.
+
     @Override
     public void visit(OpOrder opOrder) {
         List<SortCondition> conditions = opOrder.getConditions() ;
@@ -152,8 +163,8 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
     }
 
     // Special test cases for collectors.
-    
-    // XXX XXX Check order : Check for "same"/unchanged
+
+    // Careful about order.
     private VarExprList collect(VarExprList varExprList) {
         if ( varExprList == null )
             return varExprList ;
@@ -161,28 +172,41 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
       VarExprList varExpr2 = new VarExprList() ;
       
       List<Expr> x = collect(vars.size()) ;
+
+//      for ( int i = 0 ; i < vars.size() ; i++ ) {
+//          Var v = vars.get(i) ;
+//          Expr e2 = x.get(i) ;
+//          if ( e2 == null )
+//              varExpr2.add(v) ;
+//          else
+//              varExpr2.add(v, e2) ;
+//      }
+//      return varExpr2 ;
       
-      boolean changed = false ;     // XXX XXX
+      boolean changed = false ;
 
       for ( int i = 0 ; i < vars.size() ; i++ ) {
           Var v = vars.get(i) ;
           Expr e2 = x.get(i) ;
+          Expr e = varExpr2.getExpr(v) ;
+          if ( e != e2 )
+              changed = true ;
           if ( e2 == null )
               varExpr2.add(v) ;
-          else
+          else {
               varExpr2.add(v, e2) ;
+          }
       }
-      return varExpr2 ;
+      return changed ? varExpr2 : varExprList ;
+
     }  
         
-    // XXX XXX Check order : Check for "same"/unchanged
     private ExprList collect(ExprList exprList) {
         if ( exprList == null )
             return null ;
         return new ExprList(collect(exprList.size())) ;
     }
     
-    // XXX XXX Check order : Check for "same"/unchanged
     private ExprList collect(List<Expr> exprList) {
         if ( exprList == null )
             return null ;
@@ -338,7 +362,6 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
             push(opStack, op) ;
             return ;
         }
-        // op.getService()
         OpVisitorByTypeAndExpr.super.visit(op);
     }
 
@@ -349,22 +372,12 @@ public class ApplyTransformVisitor implements OpVisitorByTypeAndExpr, ExprVisito
     
     @Override
     public void visitExpr(ExprList exprs) { 
-        // XXX XXX
-        // Not called?
-        System.err.println("visitExpr(ExprList)") ;
-        if ( exprs != null && exprTransform != null ) {
-            
-        }
+        throw new InternalErrorException("Didn't expect as call to ApplyTransformVisit.visitExpr") ;
     }
     
     @Override
     public void visitVarExpr(VarExprList exprVarExprList)  {
-        // XXX XXX
-        // Not called?
-        System.err.println("visitExpr(ExprList)") ;
-        if ( exprVarExprList != null && exprTransform != null ) {
-            
-        }
+        throw new InternalErrorException("Didn't expect as call to ApplyTransformVisit.visitVarExpr") ;
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByType.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByType.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByType.java
index 8116f13..3f37329 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByType.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByType.java
@@ -25,6 +25,8 @@ import org.apache.jena.sparql.algebra.op.* ;
  *  Does not visit expressions at all. */ 
 public interface OpVisitorByType extends OpVisitor
 {
+    public void DUMMY() ;
+
     public void visitN(OpN op) ;
 
     public void visit2(Op2 op) ;
@@ -163,8 +165,6 @@ public interface OpVisitorByType extends OpVisitor
 
     @Override
     public default void visit(OpOrder opOrder) {
-        // XXX XXX
-        //opOrder.getConditions() ;
         visitModifer(opOrder);
     }
 
@@ -175,8 +175,6 @@ public interface OpVisitorByType extends OpVisitor
 
     @Override
     public default void visit(OpTopN opTop) {
-        // XXX XXX
-        // opTop.getConditions() ;
         visit1(opTop);
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
index b1a93f5..17ccca4 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
@@ -18,13 +18,18 @@
 
 package org.apache.jena.sparql.algebra.walker;
 
+import java.util.List ;
+
+import org.apache.jena.query.SortCondition ;
 import org.apache.jena.sparql.algebra.OpVisitor ;
 import org.apache.jena.sparql.algebra.op.* ;
 import org.apache.jena.sparql.core.VarExprList ;
+import org.apache.jena.sparql.expr.ExprAggregator ;
 import org.apache.jena.sparql.expr.ExprList ;
 
 /** A visitor helper that maps all visits to a few general ones.
- *  Includes visitring expressions.  */ 
+ *  Includes visiting expressions, sort conditions etc
+ */
 public interface OpVisitorByTypeAndExpr extends OpVisitor
 {
     public void visit0(Op0 op) ;    
@@ -43,6 +48,10 @@ public interface OpVisitorByTypeAndExpr extends OpVisitor
     public void visitVarExpr(VarExprList exprs) ;
     //public void visitAssignVar(Var var) ;
     
+    // Currently, we assume these are handled by the visitor/transformer.
+    public default void visitSortConditions(List<SortCondition> list)       {}
+    public default void visitAggregators(List<ExprAggregator> aggregators)  {}
+
     public default void visitModifer(OpModifier opMod) {
         visit1(opMod);
     }
@@ -171,23 +180,20 @@ public interface OpVisitorByTypeAndExpr extends OpVisitor
 
     @Override
     public default void visit(OpOrder opOrder) {
-        // XXX XXX
-        //opOrder.getConditions() ;
+        visitSortConditions(opOrder.getConditions()) ;
         visitModifer(opOrder);
     }
 
     @Override
     public default void visit(OpGroup opGroup) {
         visitVarExpr(opGroup.getGroupVars()) ;
-        // XXX XXX
-        //opGroup.getAggregators() ;
+        visitAggregators(opGroup.getAggregators()) ;
         visit1(opGroup);
     }
 
     @Override
     public default void visit(OpTopN opTop) {
-        // XXX XXX
-        // opTop.getConditions() ;
+        visitSortConditions(opTop.getConditions()) ;
         visit1(opTop);
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/Walker.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/Walker.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/Walker.java
index 2a31b4e..3b122d5 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/Walker.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/Walker.java
@@ -201,6 +201,12 @@ public class Walker {
     }
 
     /** Transform an {@link Expr}. */
+    public static Expr transform(Expr expr, Transform opTransform, ExprTransform exprTransform, OpVisitor beforeVisitor, OpVisitor afterVisitor) {
+        ApplyTransformVisitor v = createTransformer(opTransform, exprTransform, beforeVisitor,afterVisitor) ;
+        return transform(expr, v, beforeVisitor, afterVisitor) ;
+    }
+
+    /** Transform an {@link Expr}. */
     public static Expr transform(Expr expr, ApplyTransformVisitor v) {
         walk(expr, v, v, null, null) ;
         return v.exprResult() ;

http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/WalkerVisitor0.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/WalkerVisitor0.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/WalkerVisitor0.java
new file mode 100644
index 0000000..df99488
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/WalkerVisitor0.java
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.algebra.walker;
+
+import java.util.Iterator ;
+
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.OpVisitor ;
+import org.apache.jena.sparql.algebra.OpVisitorBase ;
+import org.apache.jena.sparql.algebra.op.* ;
+import org.apache.jena.sparql.core.VarExprList ;
+import org.apache.jena.sparql.expr.* ;
+
+/** Walk algebra and expressions */
+public class WalkerVisitor0 implements OpVisitorByTypeAndExpr, ExprVisitorFunction {
+    protected final ExprVisitor exprVisitor ;
+    protected final OpVisitor   opVisitor ;
+    protected int               opDepthLimit      = Integer.MAX_VALUE ;
+    protected int               exprDepthLimit    = Integer.MAX_VALUE ;
+
+    protected int               opDepth      = 0 ;
+    protected int               exprDepth    = 0 ;
+    
+    private final OpVisitor     beforeVisitor ;
+    private final OpVisitor     afterVisitor ;
+
+    /**
+     * A walker. If a visitor is null, then don't walk in. For
+     * "no action but keep walking inwards", use {@link OpVisitorBase} and
+     * {@link ExprVisitorBase}.
+     * 
+     * @see OpVisitorBase
+     * @see ExprVisitorBase
+     */
+    public WalkerVisitor0(OpVisitor opVisitor, ExprVisitor exprVisitor, OpVisitor before, OpVisitor after) {
+        this.opVisitor = opVisitor ;
+        this.exprVisitor = exprVisitor ;
+        if ( opDepthLimit < 0 )
+            opDepthLimit = Integer.MAX_VALUE ;
+        if ( exprDepth < 0 )
+            exprDepthLimit = Integer.MAX_VALUE ;
+        opDepth = 0 ;
+        exprDepth = 0 ;
+        beforeVisitor = before ;
+        afterVisitor = after ;
+    }
+
+    protected final void before(Op op) {
+        if ( beforeVisitor != null )
+            op.visit(beforeVisitor) ;
+    }
+
+    protected final void after(Op op) {
+        if ( afterVisitor != null )
+            op.visit(afterVisitor) ;
+    }
+    
+    public void walk(Op op) {
+        if ( op == null )
+            return ;
+        if ( opDepth == opDepthLimit )
+            // No deeper.
+            return ;
+        opDepth++ ; 
+        try { op.visit(this); }
+        finally { opDepth-- ; }
+    }
+    
+    public void walk(Expr expr) {
+        if ( expr == null )
+            return ;
+        if ( exprDepth == exprDepthLimit )
+            return ;
+        exprDepth++ ;
+        try { expr.visit(this) ; }
+        finally { exprDepth-- ; }
+    }
+    
+    public void walk(ExprList exprList) {
+        if ( exprList == null )
+            return ;
+        exprList.forEach(e->walk(e));
+    }
+
+    public void walk(VarExprList varExprList) {
+        if ( varExprList == null )
+            return ;
+        // retains order.
+        varExprList.forEachVarExpr((v,e) -> {
+            Expr expr = (e!=null) ? e : ExprNone.NONE ; 
+            walk(expr) ;
+        });
+    }
+
+    // ---- Mode swapping between op and expr. visit=>?walk
+    @Override
+    public void visitExpr(ExprList exprList) {
+        if ( exprVisitor != null )
+            walk(exprList) ;
+    }
+
+    @Override
+    public void visitVarExpr(VarExprList varExprList) {
+        if ( exprVisitor != null )
+            walk(varExprList);
+    }
+    
+    // ----
+    
+    public void visitOp(Op op) {
+        before(op) ;
+        if ( opVisitor != null )
+            op.visit(this);
+        after(op) ;
+    }
+
+    @Override
+    public void visit0(Op0 op) {
+        before(op) ;
+        if ( opVisitor != null )
+            op.visit(opVisitor) ;
+        after(op) ;
+    }
+
+    @Override
+    public void visit1(Op1 op) {
+        before(op) ;
+        visit1$(op) ;
+        after(op) ;
+    }
+    
+    // Can be called via different routes. 
+    private void visit1$(Op1 op) {
+        if ( op.getSubOp() != null )
+            op.getSubOp().visit(this) ;
+        if ( opVisitor != null )
+            op.visit(opVisitor) ;
+    }
+
+    @Override
+    public void visit2(Op2 op) {
+        before(op) ;
+        if ( op.getLeft() != null )
+            op.getLeft().visit(this) ;
+        if ( op.getRight() != null )
+            op.getRight().visit(this) ;
+        if ( opVisitor != null )
+            op.visit(opVisitor) ;
+        after(op) ;
+    }
+
+    @Override
+    public void visitN(OpN op) {
+        before(op) ;
+        for (Iterator<Op> iter = op.iterator(); iter.hasNext();) {
+            Op sub = iter.next() ;
+            sub.visit(this) ;
+        }
+        if ( opVisitor != null )
+            op.visit(opVisitor) ;
+        after(op) ;
+    }
+    
+    @Override
+    public void visitExt(OpExt op) {
+        before(op) ;
+        if ( opVisitor != null )
+            op.visit(opVisitor) ;
+        after(op) ;
+    }
+
+    @Override
+    public void visit(OpOrder opOrder) {
+        // XXX XXX
+//        List<SortCondition> conditions = opOrder.getConditions() ;
+//        List<SortCondition> conditions2 = new ArrayList<>() ;
+//        boolean changed = false ;
+//
+//        for ( SortCondition sc : conditions ) {
+//            Expr e = sc.getExpression() ;
+//            Expr e2 = transform(e) ;
+//            conditions2.add(new SortCondition(e2, sc.getDirection())) ;
+//            if ( e != e2 )
+//                changed = true ;
+//        }
+//        OpOrder x = opOrder ;
+//        if ( changed )
+//            x = new OpOrder(opOrder.getSubOp(), conditions2) ;
+        visit1(opOrder) ;
+    }
+
+    @Override
+    public void visit(OpAssign opAssign) {
+        before(opAssign) ;
+        VarExprList varExpr = opAssign.getVarExprList() ;
+        visitVarExpr(varExpr); 
+        visit1$(opAssign) ;
+        after(opAssign) ;
+    }
+
+    @Override
+    public void visit(OpExtend opExtend) {
+        before(opExtend) ;
+        VarExprList varExpr = opExtend.getVarExprList() ;
+        visitVarExpr(varExpr); 
+        visit1$(opExtend) ;
+        after(opExtend) ;
+    }
+
+    
+    // Transforming to quads needs the graph node handled before doing the sub-algebra ops
+    // so it has to be done as before/after by the Walker. By the time visit(OpGraph) is called,
+    // the sub-tree has already been visited. 
+    
+    
+//    @Override
+//    public void visit(OpGraph op) {
+//        pushGraph(op.getNode()) ;
+//        OpVisitorByTypeAndExpr.super.visit(op) ;
+//        popGraph() ;
+//    }
+//    
+//    private Deque<Node> stack = new ArrayDeque<>() ;
+//    
+//    public Node getCurrentGraph() { return stack.peek() ; }
+//    
+//    private void pushGraph(Node node) {
+//        stack.push(node) ;   
+//    }
+//
+//    private void popGraph() {
+//        stack.pop() ;
+//    }
+
+    @Override
+    public void visit(ExprFunction0 func) { visitExprFunction(func) ; }
+    @Override
+    public void visit(ExprFunction1 func) { visitExprFunction(func) ; }
+    @Override
+    public void visit(ExprFunction2 func) { visitExprFunction(func) ; }
+    @Override
+    public void visit(ExprFunction3 func) { visitExprFunction(func) ; }
+    @Override
+    public void visit(ExprFunctionN func) { visitExprFunction(func) ; }
+    
+    @Override
+    public void visitExprFunction(ExprFunction func) {
+        for ( int i = 1 ; i <= func.numArgs() ; i++ ) {
+            Expr expr = func.getArg(i) ;
+            if ( expr == null )
+                // Put a dummy in, e.g. to keep the transform stack aligned.
+                NodeValue.nvNothing.visit(this) ;
+            else
+                expr.visit(this) ;
+        }
+        if ( exprVisitor != null )
+            func.visit(exprVisitor) ;
+    }
+    
+    @Override
+    public void visit(ExprFunctionOp funcOp) {
+        walk(funcOp.getGraphPattern());
+        if ( exprVisitor != null )
+            funcOp.visit(exprVisitor) ;
+    }
+    
+    @Override
+    public void visit(NodeValue nv) {
+        if ( exprVisitor != null )
+            nv.visit(exprVisitor) ;
+    }
+
+    @Override
+    public void visit(ExprVar v) {
+        if ( exprVisitor != null )
+            v.visit(exprVisitor) ;
+    }
+
+    @Override
+    public void visit(ExprAggregator eAgg) {
+        // This is the assignment variable of the aggregation
+        // not a normal variable of an expression.
+
+        // visitAssignVar(eAgg.getAggVar().asVar()) ;
+
+        // XXX XXX Hack for varsMentioned
+        if ( exprVisitor != null )
+            eAgg.visit(exprVisitor) ;
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/jena/blob/663f0667/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprTransformer.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprTransformer.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprTransformer.java
index 970412d..494c945 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprTransformer.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprTransformer.java
@@ -35,5 +35,16 @@ public class ExprTransformer
             exprList2.add(e2) ;
         }) ;
         return exprList2 ;
+//        boolean changed = false ;
+//        for ( Expr e : exprList ) {
+//            Expr e2 = transform(transform, e) ;
+//            exprList2.add(e2) ;
+//            if ( e != e2 )
+//                changed = true ;
+//        } ;
+//        if ( changed )
+//            return exprList2 ;
+//        else
+//            return exprList ;
     }
 }