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/09/18 12:06:29 UTC
git commit: fix some bugs in special cases with BIND, UNION,
GROUP BY and ORDER BY
Repository: marmotta
Updated Branches:
refs/heads/develop f222bf4c5 -> 2cfd480ad
fix some bugs in special cases with BIND, UNION, GROUP BY and ORDER BY
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/2cfd480a
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/2cfd480a
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/2cfd480a
Branch: refs/heads/develop
Commit: 2cfd480add868814fb29ec3cd1c4501115b9b8f0
Parents: f222bf4
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Thu Sep 18 12:06:43 2014 +0200
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Thu Sep 18 12:06:43 2014 +0200
----------------------------------------------------------------------
.../kiwi/sparql/builder/ExtensionFinder.java | 15 ++++--
.../kiwi/sparql/builder/SQLBuilder.java | 53 +++++++++++++++-----
.../kiwi/sparql/builder/SQLVariable.java | 14 ++++++
.../kiwi/sparql/test/KiWiSparqlJoinTest.java | 16 ++++++
.../marmotta/kiwi/sparql/test/query29.sparql | 26 ++++++++++
.../marmotta/kiwi/sparql/test/query30.sparql | 25 +++++++++
6 files changed, 133 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ExtensionFinder.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ExtensionFinder.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ExtensionFinder.java
index e1c8f4d..2012f16 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ExtensionFinder.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ExtensionFinder.java
@@ -17,10 +17,7 @@
package org.apache.marmotta.kiwi.sparql.builder;
-import org.openrdf.query.algebra.Extension;
-import org.openrdf.query.algebra.ExtensionElem;
-import org.openrdf.query.algebra.TupleExpr;
-import org.openrdf.query.algebra.Var;
+import org.openrdf.query.algebra.*;
import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,4 +51,14 @@ public class ExtensionFinder extends QueryModelVisitorBase<RuntimeException> {
}
super.meet(node);
}
+
+ @Override
+ public void meet(Projection node) throws RuntimeException {
+ // stop here, this is a subquery in SQL
+ }
+
+ @Override
+ public void meet(Union node) throws RuntimeException {
+ // stop here, this is a subquery in SQL
+ }
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/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 c90b6da..cca14a3 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
@@ -323,8 +323,11 @@ public class SQLBuilder {
addVariable(sv);
}
+ // TODO: ANY as OPType here is dangerous, because the OPType should depends on projection and actual use
+ // of variables in conditions etc
if (hasNodeCondition(v.getName(), query)) {
- sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
+ //sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.VALUE));
+ sv.getBindings().add(ext.getExpr());
}
sv.getExpressions().add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
@@ -784,19 +787,45 @@ public class SQLBuilder {
return "(" + var + ".ntype = 'string' OR " + var + ".ntype = 'int' OR " + var + ".ntype = 'double' OR " + var + ".ntype = 'date' OR " + var + ".ntype = 'boolean')";
}
} else if(expr instanceof Var) {
- String var = variables.get(((Var) expr).getName()).getPrimaryAlias();
+ // distinguish between the case where the variable is plain and the variable is bound
+ SQLVariable sv = variables.get(((Var) expr).getName());
- if(optype == null) {
- return var + ".svalue";
+ if(sv.getBindings().size() > 0) {
+ // in case the variable is actually an alias for an expression, we evaluate that expression instead, effectively replacing the
+ // variable occurrence with its value
+ return evaluateExpression(sv.getBindings().get(0),optype);
} else {
- switch (optype) {
- case STRING: return var + ".svalue";
- case INT: return var + ".ivalue";
- case DOUBLE: return var + ".dvalue";
- case DATE: return var + ".tvalue";
- case VALUE: return var + ".svalue";
- case URI: return var + ".svalue";
- case ANY: return var + ".id";
+ String var = sv.getPrimaryAlias();
+
+ if(sv.getProjectionType() != ProjectionType.NODE && sv.getProjectionType() != ProjectionType.NONE) {
+ // in case the variable represents a constructed or bound value instead of a node, we need to
+ // use the SQL expression as value; SQL should take care of proper casting...
+ // TODO: explicit casting needed?
+ return sv.getExpressions().get(0);
+ } else {
+ // in case the variable represents an entry from the NODES table (i.e. has been bound to a node
+ // in the database, we take the NODES alias and resolve to the correct column according to the
+ // operator type
+ if (optype == null) {
+ return var + ".svalue";
+ } else {
+ switch (optype) {
+ case STRING:
+ return var + ".svalue";
+ case INT:
+ return var + ".ivalue";
+ case DOUBLE:
+ return var + ".dvalue";
+ case DATE:
+ return var + ".tvalue";
+ case VALUE:
+ return var + ".svalue";
+ case URI:
+ return var + ".svalue";
+ case ANY:
+ return var + ".id";
+ }
+ }
}
}
} else if(expr instanceof ValueConstant) {
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java
index a5dfb76..6fcd3d8 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLVariable.java
@@ -17,6 +17,8 @@
package org.apache.marmotta.kiwi.sparql.builder;
+import org.openrdf.query.algebra.ValueExpr;
+
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
@@ -54,6 +56,13 @@ public class SQLVariable {
private List<String> expressions;
/**
+ * A list of value expressions bound to this variable; this is needed in case the variable is used in a filter or
+ * ORDER BY, because then we need to determine the type.
+ */
+ private List<ValueExpr> bindings;
+
+
+ /**
* Set to something else than NONE when this variable is contained in the SELECT part of the query, i.e. needs to be projected.
* Decides on how the variable will be projected (as node -> ID, as value -> string or numeric field)
*/
@@ -64,6 +73,7 @@ public class SQLVariable {
this.sparqlName = sparqlName;
this.aliases = new ArrayList<>();
+ this.bindings = new ArrayList<>();
this.expressions = new ArrayList<>();
}
@@ -87,6 +97,10 @@ public class SQLVariable {
return aliases.get(0);
}
+ public List<ValueExpr> getBindings() {
+ return bindings;
+ }
+
public List<String> getExpressions() {
return expressions;
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/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 1ac3343..c1149e2 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
@@ -297,6 +297,22 @@ public class KiWiSparqlJoinTest {
}
+ // union with bind and order by
+ @Test
+ public void testQuery29() throws Exception {
+ testQuery("query29.sparql");
+ }
+
+
+
+ // bind with order by
+ @Test
+ public void testQuery30() throws Exception {
+ testQuery("query30.sparql");
+ }
+
+
+
// INSERT/UPDATE
@Test
public void testUpdate01() throws Exception {
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query29.sparql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query29.sparql b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query29.sparql
new file mode 100644
index 0000000..89eb239
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query29.sparql
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+
+SELECT ?p ?name ?likes ?fname ?isperson WHERE {
+ ?p foaf:name ?name .
+ { ?p foaf:knows ?likes . ?likes foaf:name ?fname bind(true as ?isperson) }
+ UNION
+ { ?p foaf:interest ?likes bind(false as ?isperson)}
+
+} ORDER BY ASC(?isperson)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/marmotta/blob/2cfd480a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query30.sparql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query30.sparql b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query30.sparql
new file mode 100644
index 0000000..c9b5743
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query30.sparql
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+
+SELECT ?p ?name ?likes WHERE {
+ ?p foaf:name ?name .
+ OPTIONAL { ?p foaf:knows ?knows }
+ OPTIONAL { ?p foaf:interest ?interest }
+ BIND (COALESCE(?knows,?interest) AS ?likes)
+} ORDER BY ASC(?likes)
\ No newline at end of file