Repository: marmotta
Updated Branches:
  refs/heads/develop ff559ea4f -> c8f067f0f


prevents filter optimization if function is not implemented natively


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

Branch: refs/heads/develop
Commit: b79a16213a403ab2bd82b3da714a6a681d046083
Parents: c008f95
Author: Thomas Kurz <[email protected]>
Authored: Mon Nov 23 13:13:15 2015 +0100
Committer: Thomas Kurz <[email protected]>
Committed: Mon Nov 23 13:13:15 2015 +0100

----------------------------------------------------------------------
 .../sparql/optimizer/NativeFilterOptimizer.java | 198 +++++++++++++++++++
 .../sparql/sail/KiWiSparqlSailConnection.java   |   5 +-
 2 files changed, 201 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/b79a1621/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/NativeFilterOptimizer.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/NativeFilterOptimizer.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/NativeFilterOptimizer.java
new file mode 100644
index 0000000..5cde939
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/NativeFilterOptimizer.java
@@ -0,0 +1,198 @@
+package org.apache.marmotta.kiwi.sparql.optimizer;
+
+import org.apache.marmotta.kiwi.sparql.function.NativeFunctionRegistry;
+import org.openrdf.model.URI;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.Dataset;
+import org.openrdf.query.algebra.*;
+import org.openrdf.query.algebra.evaluation.QueryOptimizer;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.algebra.helpers.VarNameCollector;
+
+import java.util.Set;
+
+/**
+ * @author Thomas Kurz ([email protected])
+ * @since 23.11.15.
+ */
+public class NativeFilterOptimizer implements QueryOptimizer {
+
+    @Override
+    public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet 
bindings) {
+        FilterFinder f = new FilterFinder(tupleExpr);
+        tupleExpr.visit(f);
+    }
+
+       /*--------------------------*
+        * Inner class FilterFinder *
+        *--------------------------*/
+
+    protected static class FilterFinder extends 
QueryModelVisitorBase<RuntimeException> {
+
+        protected final TupleExpr tupleExpr;
+
+        public FilterFinder(TupleExpr tupleExpr) {
+            this.tupleExpr = tupleExpr;
+        }
+
+        @Override
+        public void meet(Filter filter) {
+            super.meet(filter);
+            if(filter.getCondition() instanceof FunctionCall) {
+                String uri = ((FunctionCall) filter.getCondition()).getURI();
+                if(NativeFunctionRegistry.getInstance().get(uri) != null) {
+                    FilterRelocator.relocate(filter);
+                }
+            } else {
+                FilterRelocator.relocate(filter);
+            }
+        }
+    }
+
+
+       /*-----------------------------*
+        * Inner class FilterRelocator *
+        *-----------------------------*/
+
+    protected static class FilterRelocator extends 
QueryModelVisitorBase<RuntimeException> {
+
+        public static void relocate(Filter filter) {
+            filter.visit(new FilterRelocator(filter));
+        }
+
+        protected final Filter filter;
+
+        protected final Set<String> filterVars;
+
+        public FilterRelocator(Filter filter) {
+            this.filter = filter;
+            filterVars = VarNameCollector.process(filter.getCondition());
+        }
+
+        @Override
+        protected void meetNode(QueryModelNode node) {
+            // By default, do not traverse
+            assert node instanceof TupleExpr;
+            relocate(filter, (TupleExpr) node);
+        }
+
+        @Override
+        public void meet(Join join) {
+            if (join.getLeftArg().getBindingNames().containsAll(filterVars)) {
+                // All required vars are bound by the left expr
+                join.getLeftArg().visit(this);
+            }
+            else if 
(join.getRightArg().getBindingNames().containsAll(filterVars)) {
+                // All required vars are bound by the right expr
+                join.getRightArg().visit(this);
+            }
+            else {
+                relocate(filter, join);
+            }
+        }
+
+        @Override
+        public void meet(LeftJoin leftJoin) {
+            if 
(leftJoin.getLeftArg().getBindingNames().containsAll(filterVars)) {
+                leftJoin.getLeftArg().visit(this);
+            }
+            else {
+                relocate(filter, leftJoin);
+            }
+        }
+
+        @Override
+        public void meet(Union union) {
+            Filter clone = new Filter();
+            clone.setCondition(filter.getCondition().clone());
+
+            relocate(filter, union.getLeftArg());
+            relocate(clone, union.getRightArg());
+
+            FilterRelocator.relocate(filter);
+            FilterRelocator.relocate(clone);
+        }
+
+        @Override
+        public void meet(Difference node) {
+            Filter clone = new Filter();
+            clone.setCondition(filter.getCondition().clone());
+
+            relocate(filter, node.getLeftArg());
+            relocate(clone, node.getRightArg());
+
+            FilterRelocator.relocate(filter);
+            FilterRelocator.relocate(clone);
+        }
+
+        @Override
+        public void meet(Intersection node) {
+            Filter clone = new Filter();
+            clone.setCondition(filter.getCondition().clone());
+
+            relocate(filter, node.getLeftArg());
+            relocate(clone, node.getRightArg());
+
+            FilterRelocator.relocate(filter);
+            FilterRelocator.relocate(clone);
+        }
+
+        @Override
+        public void meet(Extension node) {
+            if (node.getArg().getBindingNames().containsAll(filterVars)) {
+                node.getArg().visit(this);
+            }
+            else {
+                relocate(filter, node);
+            }
+        }
+
+        @Override
+        public void meet(EmptySet node) {
+            if (filter.getParentNode() != null) {
+                // Remove filter from its original location
+                filter.replaceWith(filter.getArg());
+            }
+        }
+
+        @Override
+        public void meet(Filter filter) {
+            // Filters are commutative
+            filter.getArg().visit(this);
+        }
+
+        @Override
+        public void meet(Distinct node) {
+            node.getArg().visit(this);
+        }
+
+        @Override
+        public void meet(Order node) {
+            node.getArg().visit(this);
+        }
+
+        @Override
+        public void meet(QueryRoot node) {
+            node.getArg().visit(this);
+        }
+
+        @Override
+        public void meet(Reduced node) {
+            node.getArg().visit(this);
+        }
+
+        protected void relocate(Filter filter, TupleExpr newFilterArg) {
+            if (filter.getArg() != newFilterArg) {
+                if (filter.getParentNode() != null) {
+                    // Remove filter from its original location
+                    filter.replaceWith(filter.getArg());
+                }
+
+                // Insert filter at the new location
+                newFilterArg.replaceWith(filter);
+                filter.setArg(newFilterArg);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/b79a1621/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSailConnection.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSailConnection.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSailConnection.java
index 09333e7..3c77ead 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSailConnection.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSailConnection.java
@@ -25,6 +25,7 @@ import 
org.apache.marmotta.kiwi.sparql.evaluation.KiWiEvaluationStrategy;
 import org.apache.marmotta.kiwi.sparql.evaluation.KiWiTripleSource;
 import org.apache.marmotta.kiwi.sparql.optimizer.DifferenceOptimizer;
 import org.apache.marmotta.kiwi.sparql.optimizer.DistinctLimitOptimizer;
+import org.apache.marmotta.kiwi.sparql.optimizer.NativeFilterOptimizer;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
 import org.openrdf.query.QueryEvaluationException;
@@ -81,11 +82,11 @@ public class KiWiSparqlSailConnection extends 
NotifyingSailConnectionWrapper {
             //new DisjunctiveConstraintOptimizer().optimize(tupleExpr, 
dataset, bindings);
             //new SameTermFilterOptimizer().optimize(tupleExpr, dataset, 
bindings);
 
-
             new QueryModelNormalizer().optimize(tupleExpr, dataset, bindings);
             new QueryJoinOptimizer(new 
KiWiEvaluationStatistics()).optimize(tupleExpr, dataset, bindings);
             new IterativeEvaluationOptimizer().optimize(tupleExpr, dataset, 
bindings);
-            new FilterOptimizer().optimize(tupleExpr, dataset, bindings);
+
+            new NativeFilterOptimizer().optimize(tupleExpr, dataset, bindings);
             //new OrderLimitOptimizer().optimize(tupleExpr, dataset, bindings);
             new DistinctLimitOptimizer().optimize(tupleExpr, dataset, 
bindings);
 

Reply via email to