Repository: marmotta
Updated Branches:
  refs/heads/develop a37fc2f96 -> fa8ef614e


fix MARMOTTA-552 (complex UNION with subquery)


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

Branch: refs/heads/develop
Commit: fa8ef614e2029d2a3d1eb27d756a968199e2ce94
Parents: a37fc2f
Author: Sebastian Schaffert <[email protected]>
Authored: Thu Oct 16 11:23:03 2014 +0200
Committer: Sebastian Schaffert <[email protected]>
Committed: Thu Oct 16 11:23:03 2014 +0200

----------------------------------------------------------------------
 .../kiwi/sparql/builder/SQLBuilder.java         |  2 +-
 .../marmotta/kiwi/sparql/builder/SQLUnion.java  | 64 +++++++++++++++-----
 .../kiwi/sparql/test/KiWiSparqlJoinTest.java    |  8 +++
 .../marmotta/kiwi/sparql/test/query36.sparql    | 33 ++++++++++
 4 files changed, 91 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8ef614/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java
index 1d92cd8..199b922 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLBuilder.java
@@ -170,7 +170,7 @@ public class SQLBuilder {
     }
 
     private void prepareBuilder()  throws UnsatisfiableQueryException {
-        Preconditions.checkArgument(query instanceof Union || query instanceof 
Extension || query instanceof Order || query instanceof Group || query 
instanceof LeftJoin ||query instanceof Join || query instanceof Filter || query 
instanceof StatementPattern || query instanceof Distinct || query instanceof 
Slice || query instanceof Reduced);
+        Preconditions.checkArgument(query instanceof Projection || query 
instanceof Union || query instanceof Extension || query instanceof Order || 
query instanceof Group || query instanceof LeftJoin ||query instanceof Join || 
query instanceof Filter || query instanceof StatementPattern || query 
instanceof Distinct || query instanceof Slice || query instanceof Reduced);
 
 
         // collect all patterns in a list, using depth-first search over the 
join

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8ef614/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLUnion.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLUnion.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLUnion.java
index a87558a..26b7775 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLUnion.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLUnion.java
@@ -21,6 +21,9 @@ import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.sparql.exception.UnsatisfiableQueryException;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
+import org.openrdf.query.algebra.Projection;
+import org.openrdf.query.algebra.ProjectionElem;
+import org.openrdf.query.algebra.TupleExpr;
 import org.openrdf.query.algebra.Union;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,39 +52,50 @@ public class SQLUnion extends SQLAbstractSubquery {
     public SQLUnion(String alias, Union query, BindingSet bindings, Dataset 
dataset, ValueConverter converter, KiWiDialect dialect) throws 
UnsatisfiableQueryException {
         super(alias);
 
+        Set<String> leftProjected = getProjectedVariables(query.getLeftArg());
+        Set<String> rightProjected = 
getProjectedVariables(query.getRightArg());
+
         // we build a full subquery for each of the UNION's arguments
-        left  = new SQLBuilder(query.getLeftArg(), bindings, dataset, 
converter, dialect, Collections.EMPTY_SET);
-        right = new SQLBuilder(query.getRightArg(), bindings, dataset, 
converter, dialect, Collections.EMPTY_SET);
+        left  = new SQLBuilder(query.getLeftArg(), bindings, dataset, 
converter, dialect, leftProjected);
+        right = new SQLBuilder(query.getRightArg(), bindings, dataset, 
converter, dialect, rightProjected);
 
         // next we make sure that both subqueries share the same SQL variables 
so the SQL UNION succeeds by
         // adding NULL aliases for all variables present in one but not the 
other
         int c = 0;
         Map<String,SQLVariable> leftVars = new HashMap<>();
         for(SQLVariable svl : left.getVariables().values()) {
-            leftVars.put(svl.getSparqlName(), svl);
+            if(leftProjected.size() == 0 || 
leftProjected.contains(svl.getSparqlName())) {
+                leftVars.put(svl.getSparqlName(), svl);
+            }
         }
 
         Map<String,SQLVariable> rightVars = new HashMap<>();
         for(SQLVariable svr : right.getVariables().values()) {
-            rightVars.put(svr.getSparqlName(), svr);
+            if(rightProjected.size() == 0 || 
rightProjected.contains(svr.getSparqlName())) {
+                rightVars.put(svr.getSparqlName(), svr);
+            }
         }
 
         // we have to homogenize variable names in both subqueries and make 
sure they have the same number of columns
         Map<String,String> sparqlToSQL = new HashMap<>();
         for(SQLVariable svl : left.getVariables().values()) {
-            if(sparqlToSQL.containsKey(svl.getSparqlName())) {
-                svl.setName(sparqlToSQL.get(svl.getSparqlName()));
-            } else {
-                svl.setName("U"+ (++c));
-                sparqlToSQL.put(svl.getSparqlName(), svl.getName());
+            if(leftProjected.size() == 0 || 
leftProjected.contains(svl.getSparqlName())) {
+                if (sparqlToSQL.containsKey(svl.getSparqlName())) {
+                    svl.setName(sparqlToSQL.get(svl.getSparqlName()));
+                } else {
+                    svl.setName("U" + (++c));
+                    sparqlToSQL.put(svl.getSparqlName(), svl.getName());
+                }
             }
         }
-        for(SQLVariable svl : right.getVariables().values()) {
-            if(sparqlToSQL.containsKey(svl.getSparqlName())) {
-                svl.setName(sparqlToSQL.get(svl.getSparqlName()));
-            } else {
-                svl.setName("U"+ (++c));
-                sparqlToSQL.put(svl.getSparqlName(), svl.getName());
+        for(SQLVariable svr : right.getVariables().values()) {
+            if(rightProjected.size() == 0 || 
rightProjected.contains(svr.getSparqlName())) {
+                if (sparqlToSQL.containsKey(svr.getSparqlName())) {
+                    svr.setName(sparqlToSQL.get(svr.getSparqlName()));
+                } else {
+                    svr.setName("U" + (++c));
+                    sparqlToSQL.put(svr.getSparqlName(), svr.getName());
+                }
             }
         }
 
@@ -92,6 +106,10 @@ public class SQLUnion extends SQLAbstractSubquery {
                 svr.getExpressions().add("NULL");
                 svr.setProjectionType(ProjectionType.NODE);
                 right.getVariables().put(svl.getSparqlName(),svr);
+
+                if(rightProjected.size() > 0) {
+                    right.getProjectedVars().add(svl.getSparqlName());
+                }
             }
             variables.add(svl);
         }
@@ -102,6 +120,10 @@ public class SQLUnion extends SQLAbstractSubquery {
                 svl.getExpressions().add("NULL");
                 svl.setProjectionType(ProjectionType.NODE);
                 left.getVariables().put(svr.getSparqlName(),svl);
+
+                if(leftProjected.size() > 0) {
+                    left.getProjectedVars().add(svr.getSparqlName());
+                }
             }
             variables.add(svr);
         }
@@ -148,6 +170,18 @@ public class SQLUnion extends SQLAbstractSubquery {
     }
 
 
+    private Set<String> getProjectedVariables(TupleExpr expr) {
+        if(expr instanceof Projection) {
+            Projection projection = (Projection)expr;
+            Set<String> projectedVars = new HashSet<>();
+            for (ProjectionElem elem : 
projection.getProjectionElemList().getElements()) {
+                projectedVars.add(elem.getSourceName());
+            }
+            return projectedVars;
+        } else {
+            return Collections.EMPTY_SET;
+        }
+    }
 }
 
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8ef614/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
 
b/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
index b3b2e2e..a888658 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
@@ -345,6 +345,14 @@ public class KiWiSparqlJoinTest {
     }
 
 
+    // MARMOTTA-552
+    @Test
+    @Ignore("test skipped because of wrong evaluation in Sesame")
+    public void testQuery36() throws Exception {
+        testQuery("query36.sparql");
+    }
+
+
     // INSERT/UPDATE
     @Test
     public void testUpdate01() throws Exception {

http://git-wip-us.apache.org/repos/asf/marmotta/blob/fa8ef614/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query36.sparql
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query36.sparql
 
b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query36.sparql
new file mode 100644
index 0000000..dba866e
--- /dev/null
+++ 
b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query36.sparql
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+# MARMOTTA-552
+
+SELECT  ?class (count(?s) AS ?count)
+   WHERE
+     {   { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class }
+       UNION
+         { SELECT  ?s
+           WHERE
+             { ?s ?a ?b
+               FILTER NOT EXISTS {?s 
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class }
+             }
+          GROUP BY ?s
+        }
+    }
+  GROUP BY ?class
\ No newline at end of file

Reply via email to