Repository: marmotta
Updated Branches:
  refs/heads/develop 2a5a66163 -> ea7ed4a81


fix SPARQL queries that use HAVING


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

Branch: refs/heads/develop
Commit: caf9f419975c3402e20473751baf2ddd7ad349a2
Parents: 85e5ff3
Author: Sebastian Schaffert <[email protected]>
Authored: Thu Oct 30 10:51:37 2014 +0100
Committer: Sebastian Schaffert <[email protected]>
Committed: Thu Oct 30 10:51:37 2014 +0100

----------------------------------------------------------------------
 .../kiwi/sparql/builder/ConditionFinder.java    | 12 +++++++
 .../kiwi/sparql/builder/PatternCollector.java   |  4 +++
 .../kiwi/sparql/builder/SQLBuilder.java         | 36 +++++++++++++++++++-
 .../kiwi/sparql/builder/SQLFragment.java        |  4 +--
 4 files changed, 53 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/caf9f419/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java
index 16cbc00..f06baf7 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java
@@ -51,6 +51,18 @@ public class ConditionFinder extends 
QueryModelVisitorBase<RuntimeException> {
     }
 
     @Override
+    public void meet(Count node) throws RuntimeException {
+        if(!found && node.getArg() == null) {
+            // special case: count(*), we need the variable
+            found = true;
+        } else {
+            super.meet(node);
+        }
+    }
+
+
+
+    @Override
     public void meet(Union node) throws RuntimeException {
         // stop, subquery
     }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/caf9f419/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/PatternCollector.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/PatternCollector.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/PatternCollector.java
index 5e7a6ff..5c81f6d 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/PatternCollector.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/PatternCollector.java
@@ -80,6 +80,10 @@ public class PatternCollector extends 
QueryModelVisitorBase<RuntimeException> {
     public void meet(Filter node) throws RuntimeException {
         parts.getLast().getFilters().add(node.getCondition());
 
+        if(node.getArg() instanceof Group) {
+            
parts.getLast().setConditionPosition(SQLFragment.ConditionPosition.HAVING);
+        }
+
         super.meet(node);
     }
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/caf9f419/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 c1a01e7..41fc13e 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
@@ -483,7 +483,7 @@ public class SQLBuilder {
         // and we need to mark the pattern accordingly.
         boolean first = true;
         for(SQLFragment f : fragments) {
-            if(first) {
+            if(first && f.getConditionPosition() == 
SQLFragment.ConditionPosition.JOIN) {
                 // the conditions of the first fragment need to be placed in 
the WHERE part of the query, because
                 // there is not necessarily a JOIN ... ON where we can put it
                 f.setConditionPosition(SQLFragment.ConditionPosition.WHERE);
@@ -624,6 +624,35 @@ public class SQLBuilder {
         return whereClause;
     }
 
+    private StringBuilder buildHavingClause()  {
+
+        // list of where conditions that will later be connected by AND
+        List<String> havingConditions = new LinkedList<String>();
+
+        // 1. for the first pattern of the first fragment, we add the 
conditions to the WHERE clause
+
+        for(SQLFragment fragment : fragments) {
+            if(fragment.getConditionPosition() == 
SQLFragment.ConditionPosition.HAVING) {
+                havingConditions.add(fragment.buildConditionClause());
+            }
+        }
+
+        // construct the having clause
+        StringBuilder havingClause = new StringBuilder();
+        for(Iterator<String> it = havingConditions.iterator(); it.hasNext(); ) 
{
+            String condition = it.next();
+            if(condition.length() > 0) {
+                havingClause.append(condition);
+                havingClause.append("\n ");
+                if (it.hasNext()) {
+                    havingClause.append("AND ");
+                }
+            }
+        }
+        return havingClause;
+    }
+
+
     private StringBuilder buildOrderClause() {
         StringBuilder orderClause = new StringBuilder();
         if(orderby.size() > 0) {
@@ -1174,6 +1203,7 @@ public class SQLBuilder {
         StringBuilder whereClause  = buildWhereClause();
         StringBuilder orderClause  = buildOrderClause();
         StringBuilder groupClause  = buildGroupClause();
+        StringBuilder havingClause = buildHavingClause();
         StringBuilder limitClause  = buildLimitClause();
 
 
@@ -1190,6 +1220,10 @@ public class SQLBuilder {
             queryString.append("GROUP BY ").append(groupClause).append("\n ");
         }
 
+        if(havingClause.length() > 9) {
+            queryString.append("HAVING ").append(havingClause).append("\n ");
+        }
+
         if(orderClause.length() > 0) {
             queryString.append("ORDER BY ").append(orderClause).append("\n ");
         }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/caf9f419/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFragment.java
----------------------------------------------------------------------
diff --git 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFragment.java
 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFragment.java
index 11689e8..155339b 100644
--- 
a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFragment.java
+++ 
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFragment.java
@@ -38,7 +38,7 @@ public class SQLFragment extends SQLClause {
      * always place it in JOIN conditions, because the first pattern will not 
have a JOIN.
      */
     public static enum ConditionPosition {
-        JOIN, WHERE
+        JOIN, WHERE, HAVING
     };
 
 
@@ -154,7 +154,7 @@ public class SQLFragment extends SQLClause {
     public String buildConditionClause() {
         StringBuilder conditionClause = new StringBuilder();
 
-        if(conditionPosition == ConditionPosition.WHERE) {
+        if(conditionPosition == ConditionPosition.WHERE || conditionPosition 
== ConditionPosition.HAVING) {
             for (Iterator<SQLClause> it = 
Iterators.concat(patterns.iterator(), subqueries.iterator()); it.hasNext(); ) {
                 SQLClause p = it.next();
 

Reply via email to