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/11/07 12:21:53 UTC

marmotta git commit: SPARQL: - bug fixes

Repository: marmotta
Updated Branches:
  refs/heads/develop bde0f5179 -> 9926a4e81


SPARQL:
- bug fixes


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

Branch: refs/heads/develop
Commit: 9926a4e81a2d1bb29fbc173457efc7932313911c
Parents: bde0f51
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Fri Nov 7 12:22:28 2014 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Fri Nov 7 12:22:28 2014 +0100

----------------------------------------------------------------------
 .../kiwi/sparql/builder/SQLBuilder.java         | 108 ++++++++++------
 .../sparql/builder/collect/ConditionFinder.java | 124 ++++++++++++-------
 .../builder/eval/ExpressionEvaluator.java       |  36 ++++--
 .../persistence/KiWiSparqlConnection.java       |  22 +++-
 .../kiwi/model/rdf/KiWiUriResource.java         |   4 +
 .../kiwi/persistence/KiWiConnection.java        |   2 +-
 6 files changed, 199 insertions(+), 97 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/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 b6d69c0..99a3537 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
@@ -97,10 +97,21 @@ public class SQLBuilder {
 
 
     /**
-     * The triple patterns collected from the query.
+     * The SQL fragments and triple patterns collected from the query. SQLFragments are LEFT JOINed with each other,
+     * so for each OPTIONAL found in the query, a new fragment is appended here. Inside a fragment, the patterns
+     * are CROSS JOINed with each other.
+     *
+     * @see org.apache.marmotta.kiwi.sparql.builder.collect.PatternCollector
      */
     private List<SQLFragment> fragments;
 
+    /**
+     * Contains the names  those variables for which the value is needed instead of the ID, because the value is used
+     * somewhere in a condition, function or other kind of value expression.
+     *
+     * @see org.apache.marmotta.kiwi.sparql.builder.collect.ConditionFinder
+     */
+    private Set<String> resolveVariables;
 
     private TupleExpr query;
 
@@ -205,8 +216,10 @@ public class SQLBuilder {
         // find extensions (BIND)
         extensions = new ExtensionFinder(query).elements;
 
-        int variableCount = 0;
+        // find variables that need to be resolved
+        resolveVariables = new ConditionFinder(query).neededVariables;
 
+        int variableCount = 0;
 
         // find all variables that have been bound already, even if they do not appear in a pattern
         for(Var v : new VariableFinder(query).variables) {
@@ -251,7 +264,7 @@ public class SQLBuilder {
                             String pName = p.getName();
                             String vName = sv.getName();
 
-                            if (sv.getAlias() == null && new ConditionFinder(v.getName(), query).found) {
+                            if (sv.getAlias() == null && resolveVariables.contains(v.getName())) {
                                 sv.setAlias(pName + "_" + positions[i] + "_" + vName);
                             }
 
@@ -277,7 +290,7 @@ public class SQLBuilder {
                         String sqName = sq.getAlias();
                         String vName = sv.getName();
 
-                        if (sv.getAlias() == null && new ConditionFinder(sq_v.getSparqlName(), query).found) {
+                        if (sv.getAlias() == null && resolveVariables.contains(sq_v.getSparqlName())) {
                             sv.setAlias(sqName + "_" + vName);
                         }
 
@@ -289,11 +302,55 @@ public class SQLBuilder {
         }
 
 
+        // add all extensions to the variable list so they are properly considered in projections and clauses
+        // TODO: order by variable dependency, or otherwise the evaluateExpression might fail
+        List<ExtensionElem> deferredExtensions = new ArrayList<>(); // some extension might need to be evaluated later because their expressions cannot be computed yet
+        for(ExtensionElem ext : extensions) {
+            Var v = new Var(ext.getName());
 
+            SQLVariable sv = variables.get(v.getName());
+            if(!variables.containsKey(v.getName())) {
+                sv = new SQLVariable("V" + (++variableCount), v.getName());
 
-        // calculate for each variable the SQL expressions representing them and any necessary JOIN conditions
+                // select those variables that are really projected and not only needed in a grouping construct
+                if(projectedVars.contains(sv.getSparqlName()) || new SQLProjectionFinder(query,v.getName()).found) {
+                    sv.setProjectionType(getProjectionType(ext.getExpr()));
+                }
 
-        for(SQLFragment f : fragments) {
+                // Functions that return a string literal do so with the string literal of the same kind as the first
+                // argument (simple literal, plain literal with same language tag, xsd:string).
+                ProjectionType type = getProjectionType(ext.getExpr());
+                if(type == ProjectionType.STRING) {
+                    sv.setLiteralTypeExpression(getLiteralTypeExpression(ext.getExpr()));
+                    sv.setLiteralLangExpression(getLiteralLangExpression(ext.getExpr()));
+                    // TODO: the following will produce invalid results for aggregation functions
+                /*
+                } else if(type == ProjectionType.INT || type == ProjectionType.DOUBLE || type == ProjectionType.BOOL) {
+                    sv.setLiteralTypeExpression(getLiteralTypeExpression(ext.getExpr()));
+                */
+                }
+
+                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 (resolveVariables.contains(v.getName())) {
+                //sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.VALUE));
+                sv.getBindings().add(ext.getExpr());
+            }
+
+            try {
+                sv.getExpressions().add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
+            } catch(IllegalStateException ex) {
+                deferredExtensions.add(ext);
+            }
+
+        }
+
+
+        // calculate for each variable the SQL expressions representing them and any necessary JOIN conditions
+        for (SQLFragment f : fragments) {
             for (SQLPattern p : f.getPatterns()) {
                 // build pattern
                 Var[] fields = p.getFields();
@@ -316,8 +373,8 @@ public class SQLBuilder {
             }
 
             // subqueries: look up which variables are bound in the subqueries and add proper aliases
-            for(SQLAbstractSubquery sq : f.getSubqueries()) {
-                for(SQLVariable sq_v : sq.getQueryVariables()) {
+            for (SQLAbstractSubquery sq : f.getSubqueries()) {
+                for (SQLVariable sq_v : sq.getQueryVariables()) {
                     SQLVariable sv = variables.get(sq_v.getSparqlName());
 
                     String sqName = sq.getAlias();
@@ -333,40 +390,13 @@ public class SQLBuilder {
             }
         }
 
-        // add all extensions to the variable list so they are properly considered in projections and clauses
-        // TODO: order by variable dependency, or otherwise the evaluateExpression might fail
-        for(ExtensionElem ext : extensions) {
+        for(ExtensionElem ext : deferredExtensions) {
             Var v = new Var(ext.getName());
 
             SQLVariable sv = variables.get(v.getName());
-            if(!variables.containsKey(v.getName())) {
-                sv = new SQLVariable("V" + (++variableCount), v.getName());
-
-                // select those variables that are really projected and not only needed in a grouping construct
-                if(projectedVars.contains(sv.getSparqlName()) || new SQLProjectionFinder(query,v.getName()).found) {
-                    sv.setProjectionType(getProjectionType(ext.getExpr()));
-                }
-
-                // Functions that return a string literal do so with the string literal of the same kind as the first
-                // argument (simple literal, plain literal with same language tag, xsd:string).
-                sv.setLiteralTypeExpression(getLiteralTypeExpression(ext.getExpr()));
-                sv.setLiteralLangExpression(getLiteralLangExpression(ext.getExpr()));
-
-                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 (new ConditionFinder(v.getName(), query).found) {
-                //sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.VALUE));
-                sv.getBindings().add(ext.getExpr());
-            }
-
             sv.getExpressions().add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
-
         }
 
-
         // find context restrictions of patterns and match them with potential restrictions given in the
         // dataset (MARMOTTA-340)
         for(SQLFragment f : fragments) {
@@ -531,7 +561,7 @@ public class SQLBuilder {
             for (SQLPattern p : f.getPatterns()) {
                 for(Map.Entry<SQLPattern.TripleColumns, Var> fieldEntry : p.getTripleFields().entrySet()) {
                     if(fieldEntry.getValue() != null && !fieldEntry.getValue().hasValue() && !joined.contains(fieldEntry.getValue().getName())
-                        && new ConditionFinder(fieldEntry.getValue().getName(),query).found) {
+                        && resolveVariables.contains(fieldEntry.getValue().getName())) {
                         p.setJoinField(fieldEntry.getKey(), variables.get(fieldEntry.getValue().getName()).getName());
                         joined.add(fieldEntry.getValue().getName());
                     }
@@ -540,11 +570,11 @@ public class SQLBuilder {
 
             for(SQLAbstractSubquery sq : f.getSubqueries()) {
                 for(SQLVariable sq_v : sq.getQueryVariables()) {
-                    if(!joined.contains(sq_v.getName()) && new ConditionFinder(sq_v.getSparqlName(),query).found && sq_v.getProjectionType() == ProjectionType.NODE) {
+                    if(!joined.contains(sq_v.getSparqlName()) && resolveVariables.contains(sq_v.getSparqlName()) && sq_v.getProjectionType() == ProjectionType.NODE) {
                         // this is needed in case we need to JOIN with the NODES table to retrieve values
                         SQLVariable sv = variables.get(sq_v.getSparqlName());  // fetch the name of the variable in the enclosing query
                         sq.getJoinFields().add(new SQLAbstractSubquery.VariableMapping(sv.getName(), sq_v.getName()));
-                        joined.add(sv.getName());
+                        joined.add(sq_v.getSparqlName());
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/collect/ConditionFinder.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/collect/ConditionFinder.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/collect/ConditionFinder.java
index 9f1f944..81519ca 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/collect/ConditionFinder.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/collect/ConditionFinder.java
@@ -20,6 +20,9 @@ package org.apache.marmotta.kiwi.sparql.builder.collect;
 import org.openrdf.query.algebra.*;
 import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Check if a variable is used as a condition somewhere and therefore needs to be resolved.
  *
@@ -27,31 +30,21 @@ import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
  */
 public class ConditionFinder extends QueryModelVisitorBase<RuntimeException> {
 
-    public boolean found = false;
-
-    private String varName;
-    private boolean valueNeeded = false; // indicate if the value of the node is actually needed or the id is sufficient
+    // indicate (if > 0) if the value of variables in recursive calls need to be retrieved because the
+    // enclosing construct operates on values instead of nodes
+    int valueNeeded = 0;
 
-    public ConditionFinder(String varName, TupleExpr expr) {
-        this.varName = varName;
+    // set of variables that need a value to be resolved (used by ExtensionElem resolution)
+    public Set<String> neededVariables = new HashSet<>();
 
+    public ConditionFinder(TupleExpr expr) {
         expr.visit(this);
     }
 
     @Override
     public void meet(Var node) throws RuntimeException {
-        if(valueNeeded && !found) {
-            found = node.getName().equals(varName);
-        }
-    }
-
-    @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);
+        if(valueNeeded > 0) {
+            neededVariables.add(node.getName());
         }
     }
 
@@ -76,158 +69,197 @@ public class ConditionFinder extends QueryModelVisitorBase<RuntimeException> {
 
     @Override
     public void meet(Avg node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(BNodeGenerator node) throws RuntimeException {
-        valueNeeded = true;
-        super.meet(node);
+        valueNeeded++;
+        if(node.getNodeIdExpr() != null) {
+            node.getNodeIdExpr().visit(this);
+        }
+        valueNeeded--;
     }
 
     @Override
     public void meet(Compare node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Datatype node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IRIFunction node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IsBNode node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IsLiteral node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IsNumeric node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IsResource node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(IsURI node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Label node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Lang node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(LangMatches node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Like node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(MathExpr node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(LocalName node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Max node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Min node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Namespace node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Regex node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(SameTerm node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Str node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(Sum node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(FunctionCall node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
     }
 
     @Override
     public void meet(OrderElem node) throws RuntimeException {
-        valueNeeded = true;
-        super.meet(node);
+        valueNeeded++;
+        node.getExpr().visit(this);
+        valueNeeded--;
     }
 
     @Override
     public void meet(GroupElem node) throws RuntimeException {
-        valueNeeded = true;
+        valueNeeded++;
         super.meet(node);
+        valueNeeded--;
+    }
+
+    @Override
+    public void meet(ExtensionElem node) throws RuntimeException {
+        if(neededVariables.contains(node.getName())) {
+            valueNeeded++;
+            super.meet(node);
+            valueNeeded--;
+        } else {
+            super.meet(node);
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/eval/ExpressionEvaluator.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/eval/ExpressionEvaluator.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/eval/ExpressionEvaluator.java
index 04f75ae..8518070 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/eval/ExpressionEvaluator.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/eval/ExpressionEvaluator.java
@@ -17,6 +17,7 @@
 
 package org.apache.marmotta.kiwi.sparql.builder.eval;
 
+import com.google.common.base.Preconditions;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.marmotta.commons.collections.CollectionUtils;
 import org.apache.marmotta.commons.util.DateUtils;
@@ -251,8 +252,9 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
             List<String> countVariables = new ArrayList<>();
             for(SQLVariable v : parent.getVariables().values()) {
                 if(v.getProjectionType() == ProjectionType.NONE) {
-                    //countVariables.add(v.getExpressions().get(0));
-                    countVariables.add(v.getAlias());
+                    Preconditions.checkState(v.getExpressions().size() > 0, "no expressions available for variable");
+
+                    countVariables.add(v.getExpressions().get(0));
                 }
             }
             builder.append("ARRAY[");
@@ -291,6 +293,8 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
         } else if(arg instanceof Var) {
             String var = getVariableAlias((Var) arg);
 
+            Preconditions.checkState(var != null, "no alias available for variable");
+
             builder.append("(")
                     .append(var)
                     .append(".ntype = 'string' OR ")
@@ -320,6 +324,8 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
         } else if(arg instanceof Var) {
             String var = getVariableAlias((Var) arg);
 
+            Preconditions.checkState(var != null, "no alias available for variable");
+
             builder.append("(")
                     .append(var)
                     .append(".ntype = 'int' OR ")
@@ -338,6 +344,8 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
         } else if(arg instanceof Var) {
             String var = getVariableAlias((Var) arg);
 
+            Preconditions.checkState(var != null, "no alias available for variable");
+
             builder .append("(")
                     .append(var)
                     .append(".ntype = 'uri' OR ")
@@ -356,6 +364,8 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
         } else if(arg instanceof Var) {
             String var = getVariableAlias((Var) arg);
 
+            Preconditions.checkState(var != null, "no alias available for variable");
+
             builder.append(var).append(".ntype = 'uri'");
         }
     }
@@ -388,7 +398,10 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
     @Override
     public void meet(Lang lang) throws RuntimeException {
         if(lang.getArg() instanceof Var) {
-            builder.append(getVariableAlias((Var) lang.getArg()));
+            String var = getVariableAlias((Var) lang.getArg());
+            Preconditions.checkState(var != null, "no alias available for variable");
+
+            builder.append(var);
             builder.append(".lang");
         }
     }
@@ -404,15 +417,15 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
             lm.getLeftArg().visit(this);
             builder.append(" IS NULL");
         } else {
-            builder.append("(lower(");
+            builder.append("(");
             lm.getLeftArg().visit(this);
-            builder.append(") = lower('");
+            builder.append(" = '");
             builder.append(pattern.getValue().stringValue().toLowerCase());
-            builder.append("') OR lower(");
+            builder.append("' OR ");
             lm.getLeftArg().visit(this);
-            builder.append(") LIKE lower('");
+            builder.append(" LIKE '");
             builder.append(pattern.getValue().stringValue().toLowerCase());
-            builder.append("-%') )");
+            builder.append("-%' )");
         }
     }
 
@@ -522,21 +535,27 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
                 // operator type
                 switch (optypes.peek()) {
                     case STRING:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".svalue");
                         break;
                     case INT:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".ivalue");
                         break;
                     case DOUBLE:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".dvalue");
                         break;
                     case DATE:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".tvalue");
                         break;
                     case VALUE:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".svalue");
                         break;
                     case URI:
+                        Preconditions.checkState(var != null, "no alias available for variable");
                         builder.append(var).append(".svalue");
                         break;
                     case TERM:
@@ -545,6 +564,7 @@ public class ExpressionEvaluator extends QueryModelVisitorBase<RuntimeException>
                             // this allows us to avoid joins with the nodes table for simple expressions that only need the ID
                             builder.append(sv.getExpressions().get(0));
                         } else {
+                            Preconditions.checkState(var != null, "no alias available for variable");
                             builder.append(var).append(".id");
                         }
                         break;

http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/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 65d3bb3..822f510 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
@@ -154,13 +154,29 @@ public class KiWiSparqlConnection {
                                     case INT:
                                         if(row.getObject(sv.getName()) != null) {
                                             svalue = Integer.toString(row.getInt(sv.getName()));
-                                            resultRow.addBinding(sv.getSparqlName(), new LiteralImpl(svalue, XSD.Integer));
+                                            URI type = XSD.Integer;
+                                            try {
+                                                long typeId = row.getLong(sv.getName() + "_TYPE");
+                                                if (typeId > 0)
+                                                    type = (URI) parent.loadNodeById(typeId);
+                                            } catch (SQLException ex) {
+                                            }
+
+                                            resultRow.addBinding(sv.getSparqlName(), new LiteralImpl(svalue, type));
                                         }
                                         break;
                                     case DOUBLE:
                                         if(row.getObject(sv.getName()) != null) {
                                             svalue = Double.toString(row.getDouble(sv.getName()));
-                                            resultRow.addBinding(sv.getSparqlName(), new LiteralImpl(svalue, XSD.Double));
+                                            URI type = XSD.Double;
+                                            try {
+                                                long typeId = row.getLong(sv.getName() + "_TYPE");
+                                                if (typeId > 0)
+                                                    type = (URI) parent.loadNodeById(typeId);
+                                            } catch (SQLException ex) {
+                                            }
+
+                                            resultRow.addBinding(sv.getSparqlName(), new LiteralImpl(svalue, type));
                                         }
                                         break;
                                     case BOOL:
@@ -178,12 +194,12 @@ public class KiWiSparqlConnection {
                                             // retrieve optional type and language information, because string functions
                                             // need to preserve this in certain cases, even when constructing new literals
                                             String lang = null;
-                                            URI type = null;
                                             try {
                                                 lang = row.getString(sv.getName() + "_LANG");
                                             } catch (SQLException ex) {
                                             }
 
+                                            URI type = null;
                                             try {
                                                 long typeId = row.getLong(sv.getName() + "_TYPE");
                                                 if (typeId > 0)

http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiUriResource.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiUriResource.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiUriResource.java
index 74bdfd3..6f3a901 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiUriResource.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiUriResource.java
@@ -17,6 +17,7 @@
  */
 package org.apache.marmotta.kiwi.model.rdf;
 
+import com.google.common.base.Preconditions;
 import org.apache.marmotta.commons.sesame.model.URICommons;
 import org.openrdf.model.URI;
 
@@ -47,11 +48,13 @@ public class KiWiUriResource extends KiWiResource implements URI {
 
     public KiWiUriResource(String uri) {
         super();
+        Preconditions.checkArgument(uri.indexOf(':') >= 0, "Not a valid (absolute) URI: " + uri);
         this.uri = uri;
     }
 
     public KiWiUriResource(String uri, Date created) {
         super(created);
+        Preconditions.checkArgument(uri.indexOf(':') >= 0, "Not a valid (absolute) URI: " + uri);
         this.uri = uri;
     }
 
@@ -66,6 +69,7 @@ public class KiWiUriResource extends KiWiResource implements URI {
 
     @Deprecated
     public void setUri(String uri) {
+        Preconditions.checkArgument(uri.indexOf(':') >= 0, "Not a valid (absolute) URI: " + uri);
         this.uri = uri;
     }
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/9926a4e8/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
index 3a0ec53..23231eb 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
@@ -1070,7 +1070,7 @@ public class KiWiConnection implements AutoCloseable {
             }
 
             if(stringLiteral.getLocale() != null) {
-                insertNode.setString(5, stringLiteral.getLocale().getLanguage());
+                insertNode.setString(5, stringLiteral.getLocale().getLanguage().toLowerCase());
             } else {
                 insertNode.setObject(5, null);
             }