You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2014/01/13 19:59:20 UTC

[1/2] git commit: some more SPARQL query optimizations (limit, distinct, reduced)

Updated Branches:
  refs/heads/develop d8374a31a -> ab985cf15


some more SPARQL query optimizations (limit, distinct, reduced)


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

Branch: refs/heads/develop
Commit: fa8b3013595a0b041949ea5d7169ae7057fe0af7
Parents: d8374a3
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Mon Jan 13 19:46:25 2014 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Mon Jan 13 19:46:25 2014 +0100

----------------------------------------------------------------------
 .../evaluation/KiWiEvaluationStrategyImpl.java  |  78 ++++++-
 .../optimizer/DistinctLimitOptimizer.java       | 224 +++++++++++++++++++
 .../persistence/KiWiSparqlConnection.java       | 170 ++++++++------
 .../sparql/sail/KiWiSparqlSailConnection.java   |   5 +-
 4 files changed, 404 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8b3013/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/evaluation/KiWiEvaluationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/evaluation/KiWiEvaluationStrategyImpl.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/evaluation/KiWiEvaluationStrategyImpl.java
index 16c6707..c7bbcaf 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/evaluation/KiWiEvaluationStrategyImpl.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/evaluation/KiWiEvaluationStrategyImpl.java
@@ -120,10 +120,78 @@ public class KiWiEvaluationStrategyImpl extends EvaluationStrategyImpl{
     }
 
     @Override
-    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(LeftJoin leftJoin, BindingSet bindings) throws QueryEvaluationException {
-        return super.evaluate(leftJoin, bindings);
+    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Slice slice, BindingSet bindings) throws QueryEvaluationException {
+        if(isSupported(slice)) {
+            log.debug("applying KiWi SLICE optimizations on SPARQL query ...");
+
+            try {
+                return new ExceptionConvertingIteration<BindingSet, QueryEvaluationException>(connection.evaluateJoin(slice, bindings, dataset)) {
+                    @Override
+                    protected QueryEvaluationException convert(Exception e) {
+                        return new QueryEvaluationException(e);
+                    }
+                };
+            } catch (SQLException e) {
+                throw new QueryEvaluationException(e);
+            } catch (IllegalArgumentException e) {
+                throw new QueryEvaluationException(e);
+            } catch (InterruptedException e) {
+                throw new QueryInterruptedException(e);
+            }
+        } else {
+            return super.evaluate(slice, bindings);
+        }
     }
 
+    @Override
+    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Reduced reduced, BindingSet bindings) throws QueryEvaluationException {
+        if(isSupported(reduced)) {
+            log.debug("applying KiWi REDUCED optimizations on SPARQL query ...");
+
+            try {
+                return new ExceptionConvertingIteration<BindingSet, QueryEvaluationException>(connection.evaluateJoin(reduced, bindings, dataset)) {
+                    @Override
+                    protected QueryEvaluationException convert(Exception e) {
+                        return new QueryEvaluationException(e);
+                    }
+                };
+            } catch (SQLException e) {
+                throw new QueryEvaluationException(e);
+            } catch (IllegalArgumentException e) {
+                throw new QueryEvaluationException(e);
+            } catch (InterruptedException e) {
+                throw new QueryInterruptedException(e);
+            }
+        } else {
+            return super.evaluate(reduced, bindings);
+        }
+    }
+
+    @Override
+    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Distinct distinct, BindingSet bindings) throws QueryEvaluationException {
+        if(isSupported(distinct)) {
+            log.debug("applying KiWi DISTINCT optimizations on SPARQL query ...");
+
+            try {
+                return new ExceptionConvertingIteration<BindingSet, QueryEvaluationException>(connection.evaluateJoin(distinct, bindings, dataset)) {
+                    @Override
+                    protected QueryEvaluationException convert(Exception e) {
+                        return new QueryEvaluationException(e);
+                    }
+                };
+            } catch (SQLException e) {
+                throw new QueryEvaluationException(e);
+            } catch (IllegalArgumentException e) {
+                throw new QueryEvaluationException(e);
+            } catch (InterruptedException e) {
+                throw new QueryInterruptedException(e);
+            }
+        } else {
+            return super.evaluate(distinct, bindings);
+        }
+    }
+
+
     /**
      * Test if a tuple expression is supported nby the optimized evaluation; in this case we can apply a specific optimization.
      * @param expr
@@ -136,6 +204,12 @@ public class KiWiEvaluationStrategyImpl extends EvaluationStrategyImpl{
             return isSupported(((Filter) expr).getArg()) && isSupported(((Filter) expr).getCondition());
         } else if(expr instanceof StatementPattern) {
             return true;
+        } else if(expr instanceof Slice) {
+            return isSupported(((Slice) expr).getArg());
+        } else if(expr instanceof Reduced) {
+            return isSupported(((Reduced) expr).getArg());
+        } else if(expr instanceof Distinct) {
+            return isSupported(((Distinct) expr).getArg());
         } else {
             return false;
         }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8b3013/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/DistinctLimitOptimizer.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/DistinctLimitOptimizer.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/DistinctLimitOptimizer.java
new file mode 100644
index 0000000..1449be1
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/optimizer/DistinctLimitOptimizer.java
@@ -0,0 +1,224 @@
+/*
+ * 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.marmotta.kiwi.sparql.optimizer;
+
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Push limits and distincts down to inside the projection, because then we can potentially translate them into a database
+ * LIMIT for more efficient querying
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class DistinctLimitOptimizer implements QueryOptimizer {
+
+    private static Logger log = LoggerFactory.getLogger(DistinctLimitOptimizer.class);
+
+    @Override
+    public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
+        if( new LimitPreconditions(tupleExpr).isAllowed() ) {
+            log.debug("applying distinct/limit optimizations ...");
+
+            tupleExpr.visit(new LimitRelocator());
+            tupleExpr.visit(new DistinctRelocator());
+            tupleExpr.visit(new ReducedRelocator());
+        }
+    }
+
+    /**
+     * We can only safely push down a distinct or limit to the outermost JOIN, Filter, or Statement Pattern in case the
+     * query does not contain an ORDER BY or one of the other constructs that affect the number of results
+     */
+    private static class LimitPreconditions extends QueryModelVisitorBase<RuntimeException> {
+
+        private boolean allowed = true;
+
+        private LimitPreconditions(TupleExpr expr) {
+            expr.visit(this);
+        }
+
+        @Override
+        public void meet(Order node) throws RuntimeException {
+            super.meet(node);
+
+            allowed = false;
+        }
+
+        @Override
+        public void meet(Group node) throws RuntimeException {
+            super.meet(node);
+
+            allowed = false;
+        }
+
+        @Override
+        public void meet(LeftJoin node) throws RuntimeException {
+            super.meet(node);
+
+            allowed = false;
+        }
+
+
+        @Override
+        public void meet(Filter node) throws RuntimeException {
+            // break traversal
+        }
+
+        @Override
+        public void meet(Join node) throws RuntimeException {
+            // break traversal
+        }
+
+        public boolean isAllowed() {
+            return allowed;
+        }
+    }
+
+    /**
+     * Move down the Slide node so its parent its children are the Join, Filter or Statement pattern nodes.
+     */
+    private static class LimitRelocator extends QueryModelVisitorBase<RuntimeException> {
+
+        private LimitRelocator() {
+        }
+
+        @Override
+        public void meet(Slice node) throws RuntimeException {
+            TupleExpr child = node.getArg();
+
+            if(!isSupported(child) && child instanceof UnaryTupleOperator) {
+                UnaryTupleOperator replacement = (UnaryTupleOperator)child.clone();
+
+                // switch positions of child and node
+                node.replaceWith(replacement);
+                node.setArg(((UnaryTupleOperator) child).getArg().clone());
+                replacement.setArg(node.clone());
+
+                // visit the newly inserted replacement node (i.e. the clone of child now containing the old "node" as
+                // child, so "node" can be bubbled down further if needed)
+                replacement.visit(this);
+            }
+
+        }
+
+        private static boolean isSupported(TupleExpr expr) {
+            if(expr instanceof Join) {
+                return true;
+            } else if(expr instanceof Filter) {
+                return true;
+            } else if(expr instanceof StatementPattern) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private static class DistinctRelocator extends QueryModelVisitorBase<RuntimeException> {
+
+        private DistinctRelocator() {
+        }
+
+        @Override
+        public void meet(Distinct node) throws RuntimeException {
+            TupleExpr child = node.getArg();
+
+            if(!isSupported(child) && child instanceof UnaryTupleOperator) {
+                UnaryTupleOperator replacement = (UnaryTupleOperator)child.clone();
+
+                // switch positions of child and node
+                node.replaceWith(replacement);
+                node.setArg(((UnaryTupleOperator) child).getArg().clone());
+                replacement.setArg(node.clone());
+
+                // visit the newly inserted replacement node (i.e. the clone of child now containing the old "node" as
+                // child, so "node" can be bubbled down further if needed)
+                replacement.visit(this);
+            }
+
+        }
+
+
+        private static boolean isSupported(TupleExpr expr) {
+            if(expr instanceof Join) {
+                return true;
+            } else if(expr instanceof Filter) {
+                return true;
+            } else if(expr instanceof StatementPattern) {
+                return true;
+            } else if(expr instanceof Slice) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private static class ReducedRelocator extends QueryModelVisitorBase<RuntimeException> {
+
+        private ReducedRelocator() {
+        }
+
+        @Override
+        public void meet(Reduced node) throws RuntimeException {
+            TupleExpr child = node.getArg();
+
+            if(!isSupported(child) && child instanceof UnaryTupleOperator) {
+                UnaryTupleOperator replacement = (UnaryTupleOperator)child.clone();
+
+                // switch positions of child and node
+                node.replaceWith(replacement);
+                node.setArg(((UnaryTupleOperator) child).getArg().clone());
+                replacement.setArg(node.clone());
+
+                // visit the newly inserted replacement node (i.e. the clone of child now containing the old "node" as
+                // child, so "node" can be bubbled down further if needed)
+                replacement.visit(this);
+            }
+
+        }
+
+
+        private static boolean isSupported(TupleExpr expr) {
+            if(expr instanceof Join) {
+                return true;
+            } else if(expr instanceof Filter) {
+                return true;
+            } else if(expr instanceof StatementPattern) {
+                return true;
+            } else if(expr instanceof Slice) {
+                return true;
+            } else if(expr instanceof Distinct) {
+                return true;
+            } else if(expr instanceof Reduced) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8b3013/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/persistence/KiWiSparqlConnection.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/persistence/KiWiSparqlConnection.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/persistence/KiWiSparqlConnection.java
index a4be68a..8b91ab4 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/persistence/KiWiSparqlConnection.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/persistence/KiWiSparqlConnection.java
@@ -31,11 +31,7 @@ import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.persistence.util.ResultSetIteration;
 import org.apache.marmotta.kiwi.persistence.util.ResultTransformerFunction;
 import org.apache.marmotta.kiwi.sail.KiWiValueFactory;
-import org.openrdf.model.BNode;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Resource;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
+import org.openrdf.model.*;
 import org.openrdf.model.impl.URIImpl;
 import org.openrdf.model.vocabulary.FN;
 import org.openrdf.model.vocabulary.SESAME;
@@ -44,6 +40,7 @@ import org.openrdf.query.Binding;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
 import org.openrdf.query.algebra.*;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
 import org.openrdf.query.impl.MapBindingSet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,20 +50,8 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.regex.Pattern;
 
 /**
@@ -105,14 +90,18 @@ public class KiWiSparqlConnection {
      * @return
      */
     public CloseableIteration<BindingSet, SQLException> evaluateJoin(TupleExpr join, final BindingSet bindings, final Dataset dataset) throws SQLException, InterruptedException {
-        Preconditions.checkArgument(join instanceof Join || join instanceof Filter || join instanceof StatementPattern);
+        Preconditions.checkArgument(join instanceof Join || join instanceof Filter || join instanceof StatementPattern || join instanceof Distinct || join instanceof Slice || join instanceof Reduced);
 
         // some definitions
         String[] positions = new String[] {"subject","predicate","object","context"};
 
         // collect all patterns in a list, using depth-first search over the join
-        List<StatementPattern> patterns = new ArrayList<StatementPattern>();
-        collectPatterns(join, patterns);
+        List<StatementPattern> patterns = new PatternCollector(join).patterns;
+
+        long offset = new LimitFinder(join).offset;
+        long limit  = new LimitFinder(join).limit;
+
+        boolean distinct = new DistinctFinder(join).distinct;
 
         // associate a name with each pattern; the names are used in the database query to refer to the triple
         // that matched this pattern and in the construction of variable names for the HQL query
@@ -221,6 +210,11 @@ public class KiWiSparqlConnection {
 
         // build the select clause by projecting for each query variable the first name
         StringBuilder selectClause = new StringBuilder();
+
+        if(distinct) {
+            selectClause.append("DISTINCT ");
+        }
+
         final List<Var> selectVariables = new LinkedList<Var>();
         for(Iterator<Var> it = queryVariableIds.keySet().iterator(); it.hasNext(); ) {
             Var v = it.next();
@@ -352,8 +346,7 @@ public class KiWiSparqlConnection {
 
 
         // 5. for each filter condition, add a statement to the where clause
-        List<ValueExpr> filters = new ArrayList<ValueExpr>();
-        collectFilters(join, filters);
+        List<ValueExpr> filters = new FilterCollector(join).filters;
         for(ValueExpr expr : filters) {
             whereConditions.add(evaluateExpression(expr,queryVariables, null));
         }
@@ -399,12 +392,26 @@ public class KiWiSparqlConnection {
             }
         }
 
+        // construct limit and offset
+        StringBuilder limitClause = new StringBuilder();
+        if(limit > 0) {
+            limitClause.append("LIMIT ");
+            limitClause.append(limit);
+            limitClause.append(" ");
+        }
+        if(offset >= 0) {
+            limitClause.append("OFFSET ");
+            limitClause.append(offset);
+            limitClause.append(" ");
+        }
+
 
         // build the query string
         String queryString =
                 "SELECT " + selectClause + "\n " +
                         "FROM " + fromClause + "\n " +
-                        "WHERE " + whereClause;
+                        "WHERE " + whereClause + "\n " +
+                        limitClause;
 
         log.debug("original SPARQL syntax tree:\n {}", join);
         log.debug("constructed SQL query string:\n {}",queryString);
@@ -669,49 +676,6 @@ public class KiWiSparqlConnection {
     }
 
     /**
-     * Collect all statement patterns in a tuple expression in depth-first order. The tuple expression may only
-     * contain Join or StatementPattern expressions, otherwise an IllegalArgumentException is thrown.
-     * @param expr
-     * @param patterns
-     */
-    private void collectPatterns(TupleExpr expr, List<StatementPattern> patterns) {
-        if(expr instanceof Join) {
-            collectPatterns(((Join) expr).getLeftArg(), patterns);
-            collectPatterns(((Join) expr).getRightArg(), patterns);
-        } else if(expr instanceof Filter) {
-            collectPatterns(((Filter) expr).getArg(), patterns);
-        } else if(expr instanceof StatementPattern) {
-            patterns.add((StatementPattern)expr);
-        } else {
-            throw new IllegalArgumentException("the tuple expression was neither a join nor a statement pattern: "+expr);
-        }
-
-    }
-
-
-    /**
-     * Collect all filter conditions in a tuple expression in depth-first order. The tuple expression may only
-     * contain Join or StatementPattern expressions, otherwise an IllegalArgumentException is thrown.
-     * @param expr
-     * @param filters
-     */
-    private void collectFilters(TupleExpr expr, List<ValueExpr> filters) {
-        if(expr instanceof Join) {
-            collectFilters(((Join) expr).getLeftArg(), filters);
-            collectFilters(((Join) expr).getRightArg(), filters);
-        } else if(expr instanceof Filter) {
-            filters.add(((Filter) expr).getCondition());
-            collectFilters(((Filter)expr).getArg(), filters);
-        } else if(expr instanceof StatementPattern) {
-            // do nothing
-        } else {
-            throw new IllegalArgumentException("the tuple expression was neither a join nor a statement pattern: "+expr);
-        }
-
-    }
-
-
-    /**
      * Check if a variable selecting a node actually has any attached condition; if not return false. This is used to
      * decide whether joining with the node itself is necessary.
      * @param v
@@ -995,4 +959,74 @@ public class KiWiSparqlConnection {
 
     }
 
+
+    private static class LimitFinder extends QueryModelVisitorBase<RuntimeException> {
+
+        long limit = -1, offset = -1;
+
+        private LimitFinder(TupleExpr expr) {
+            expr.visit(this);
+        }
+
+        @Override
+        public void meet(Slice node) throws RuntimeException {
+            if(node.hasLimit())
+                limit = node.getLimit();
+            if(node.hasOffset())
+                offset = node.getOffset();
+        }
+    }
+
+    private static class DistinctFinder extends QueryModelVisitorBase<RuntimeException> {
+
+        boolean distinct = false;
+
+        private DistinctFinder(TupleExpr expr) {
+            expr.visit(this);
+        }
+
+        @Override
+        public void meet(Distinct node) throws RuntimeException {
+            distinct = true;
+        }
+
+        @Override
+        public void meet(Reduced node) throws RuntimeException {
+            distinct = true;
+        }
+    }
+
+
+    private static class PatternCollector extends QueryModelVisitorBase<RuntimeException> {
+
+        List<StatementPattern> patterns = new ArrayList<>();
+
+        private PatternCollector(TupleExpr expr) {
+            expr.visit(this);
+        }
+
+        @Override
+        public void meet(StatementPattern node) throws RuntimeException {
+            patterns.add(node);
+
+            super.meet(node);
+        }
+    }
+
+
+    private static class FilterCollector extends QueryModelVisitorBase<RuntimeException> {
+
+        List<ValueExpr> filters = new ArrayList<>();
+
+        private FilterCollector(TupleExpr expr) {
+            expr.visit(this);
+        }
+
+        @Override
+        public void meet(Filter node) throws RuntimeException {
+            filters.add(node.getCondition());
+
+            super.meet(node);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8b3013/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 d92808f..662a8dc 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
@@ -18,13 +18,12 @@
 package org.apache.marmotta.kiwi.sparql.sail;
 
 import info.aduna.iteration.CloseableIteration;
-import org.apache.marmotta.kiwi.sail.KiWiSailConnection;
 import org.apache.marmotta.kiwi.sail.KiWiValueFactory;
 import org.apache.marmotta.kiwi.sparql.evaluation.KiWiEvaluationStatistics;
 import org.apache.marmotta.kiwi.sparql.evaluation.KiWiEvaluationStrategyImpl;
 import org.apache.marmotta.kiwi.sparql.evaluation.KiWiTripleSource;
+import org.apache.marmotta.kiwi.sparql.optimizer.DistinctLimitOptimizer;
 import org.apache.marmotta.kiwi.sparql.persistence.KiWiSparqlConnection;
-import org.openrdf.model.ValueFactory;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
 import org.openrdf.query.QueryEvaluationException;
@@ -34,7 +33,6 @@ import org.openrdf.query.algebra.evaluation.EvaluationStrategy;
 import org.openrdf.query.algebra.evaluation.impl.*;
 import org.openrdf.query.impl.EmptyBindingSet;
 import org.openrdf.sail.NotifyingSailConnection;
-import org.openrdf.sail.SailConnection;
 import org.openrdf.sail.SailException;
 import org.openrdf.sail.helpers.NotifyingSailConnectionWrapper;
 import org.slf4j.Logger;
@@ -84,6 +82,7 @@ public class KiWiSparqlSailConnection extends NotifyingSailConnectionWrapper {
             new IterativeEvaluationOptimizer().optimize(tupleExpr, dataset, bindings);
             new FilterOptimizer().optimize(tupleExpr, dataset, bindings);
             new OrderLimitOptimizer().optimize(tupleExpr, dataset, bindings);
+            new DistinctLimitOptimizer().optimize(tupleExpr, dataset, bindings);
 
             log.debug("evaluating SPARQL query:\n {}", tupleExpr);
 


[2/2] git commit: some SPARQL bug fixes for MySQL

Posted by ss...@apache.org.
some SPARQL bug fixes for MySQL


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

Branch: refs/heads/develop
Commit: ab985cf15b0a4c2d115b22cab68f8760b8994506
Parents: fa8b301
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Mon Jan 13 19:59:14 2014 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Mon Jan 13 19:59:14 2014 +0100

----------------------------------------------------------------------
 .../java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java  | 2 +-
 .../marmotta/kiwi/persistence/mysql/create_fulltext_index.sql      | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/ab985cf1/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
index 28877bc..4ce504e 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
@@ -20,7 +20,6 @@ package org.apache.marmotta.kiwi.sparql.sail;
 import org.apache.commons.io.IOUtils;
 import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.persistence.KiWiConnection;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
 import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
 import org.apache.marmotta.kiwi.persistence.util.ScriptRunner;
 import org.apache.marmotta.kiwi.sail.KiWiSailConnection;
@@ -151,6 +150,7 @@ public class KiWiSparqlSail extends NotifyingSailWrapper {
                             }
                         }
 
+                        /*
                     } else if(configuration.getDialect() instanceof MySQLDialect) {
 
                         // for MySQL, just create a fulltext index (no language support)

http://git-wip-us.apache.org/repos/asf/marmotta/blob/ab985cf1/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
index c764c08..56e80f4 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
@@ -13,7 +13,6 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-DROP INDEX kiwi_ft_idx ON nodes;
 CREATE FULLTEXT INDEX kiwi_ft_idx ON nodes(svalue);
 
 INSERT INTO metadata(mkey,mvalue) VALUES ('ft.idx','true');