marmotta-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sschaff...@apache.org
Subject git commit: implementation of MARMOTTA-536 (BIND) and a large number of additional functions for postgres
Date Tue, 16 Sep 2014 13:45:16 GMT
Repository: marmotta
Updated Branches:
  refs/heads/develop 8429f690d -> 5be6ef2eb


implementation of MARMOTTA-536 (BIND) and a large number of additional functions for postgres


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

Branch: refs/heads/develop
Commit: 5be6ef2eb2ad43407a1d82b787e209fcb0af56c1
Parents: 8429f69
Author: Sebastian Schaffert <sschaffert@apache.org>
Authored: Tue Sep 16 15:45:35 2014 +0200
Committer: Sebastian Schaffert <sschaffert@apache.org>
Committed: Tue Sep 16 15:45:35 2014 +0200

----------------------------------------------------------------------
 .../marmotta/kiwi/sparql/builder/OPTypes.java   |   2 +-
 .../kiwi/sparql/builder/ProjectionType.java     |  27 ++++
 .../kiwi/sparql/builder/SQLBuilder.java         | 136 +++++++++++++++++--
 .../evaluation/KiWiEvaluationStrategyImpl.java  |   5 +-
 .../kiwi/sparql/function/FunctionUtil.java      |  85 ++++++++++++
 .../persistence/KiWiSparqlConnection.java       |  33 ++++-
 .../persistence/pgsql/PostgreSQLDialect.java    |  65 +++++++++
 .../marmotta/kiwi/vocabulary/FN_MARMOTTA.java   |  38 ++++++
 .../persistence/pgsql/create_base_tables.sql    |   2 +
 9 files changed, 374 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/OPTypes.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/OPTypes.java
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/OPTypes.java
index 9139e79..db307b2 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/OPTypes.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/OPTypes.java
@@ -23,5 +23,5 @@ package org.apache.marmotta.kiwi.sparql.builder;
 * @author Sebastian Schaffert (sschaffert@apache.org)
 */
 public enum OPTypes {
-    STRING, DOUBLE, INT, DATE, BOOL, VALUE, ANY
+    STRING, DOUBLE, INT, DATE, BOOL, VALUE, ANY, URI
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ProjectionType.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ProjectionType.java
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ProjectionType.java
new file mode 100644
index 0000000..0c6c9fa
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ProjectionType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.builder;
+
+/**
+ * Add file description here!
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public enum ProjectionType {
+    NODE, URI, STRING, INT, DOUBLE, DATE
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/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 8ed4781..cdee921 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
@@ -21,12 +21,14 @@ 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;
+import org.apache.marmotta.commons.vocabulary.XSD;
 import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
 import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.sail.KiWiValueFactory;
 import org.apache.marmotta.kiwi.sparql.exception.UnsatisfiableQueryException;
+import org.apache.marmotta.kiwi.sparql.function.FunctionUtil;
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
 import org.openrdf.model.*;
-import org.openrdf.model.impl.URIImpl;
 import org.openrdf.model.vocabulary.FN;
 import org.openrdf.model.vocabulary.SESAME;
 import org.openrdf.model.vocabulary.XMLSchema;
@@ -82,6 +84,22 @@ public class SQLBuilder {
         functionParameterTypes.put(FN.NUMERIC_FLOOR, OPTypes.DOUBLE);
         functionParameterTypes.put(FN.NUMERIC_ROUND, OPTypes.DOUBLE);
 
+
+        functionParameterTypes.put(FN_MARMOTTA.YEAR, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.MONTH, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.DAY, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.HOURS, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.MINUTES, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.SECONDS, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.TIMEZONE, OPTypes.DATE);
+        functionParameterTypes.put(FN_MARMOTTA.TZ, OPTypes.DATE);
+
+        functionParameterTypes.put(FN_MARMOTTA.MD5, OPTypes.STRING);
+        functionParameterTypes.put(FN_MARMOTTA.SHA1, OPTypes.STRING);
+        functionParameterTypes.put(FN_MARMOTTA.SHA256, OPTypes.STRING);
+        functionParameterTypes.put(FN_MARMOTTA.SHA384, OPTypes.STRING);
+        functionParameterTypes.put(FN_MARMOTTA.SHA512, OPTypes.STRING);
+
     }
 
     /**
@@ -106,6 +124,24 @@ public class SQLBuilder {
         functionReturnTypes.put(FN.NUMERIC_FLOOR, OPTypes.INT);
         functionReturnTypes.put(FN.NUMERIC_ROUND, OPTypes.INT);
 
+        functionReturnTypes.put(FN_MARMOTTA.UUID, OPTypes.URI);
+        functionReturnTypes.put(FN_MARMOTTA.STRUUID, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.RAND, OPTypes.DOUBLE);
+        functionReturnTypes.put(FN_MARMOTTA.NOW, OPTypes.DATE);
+        functionReturnTypes.put(FN_MARMOTTA.YEAR, OPTypes.INT);
+        functionReturnTypes.put(FN_MARMOTTA.MONTH, OPTypes.INT);
+        functionReturnTypes.put(FN_MARMOTTA.DAY, OPTypes.INT);
+        functionReturnTypes.put(FN_MARMOTTA.HOURS, OPTypes.INT);
+        functionReturnTypes.put(FN_MARMOTTA.MINUTES, OPTypes.INT);
+        functionReturnTypes.put(FN_MARMOTTA.SECONDS, OPTypes.DOUBLE);
+        functionReturnTypes.put(FN_MARMOTTA.TIMEZONE, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.TZ, OPTypes.STRING);
+
+        functionReturnTypes.put(FN_MARMOTTA.MD5, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.SHA1, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.SHA256, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.SHA384, OPTypes.STRING);
+        functionReturnTypes.put(FN_MARMOTTA.SHA512, OPTypes.STRING);
     }
 
 
@@ -138,7 +174,7 @@ public class SQLBuilder {
      * depending on the number of patterns it occurs in; will look like
      * { ?x -> ["P1_V1", "P2_V1"], ?y -> ["P2_V2"], ... }
      */
-    private Map<Var,List<String>> queryVariables = new HashMap<>();
+    private Map<String,List<String>> queryVariables = new HashMap<>();
 
 
     /**
@@ -148,6 +184,8 @@ public class SQLBuilder {
     private Map<Var,List<String>> queryVariableIds = new HashMap<>();
 
 
+    private Map<Var, ProjectionType> variableTypes = new HashMap<>();
+
 
     /**
      * The triple patterns collected from the query.
@@ -238,6 +276,17 @@ public class SQLBuilder {
         return variableNames.get(v);
     }
 
+
+    /**
+     * Return the type of a projected variable. Usually this is a node id to be resolved
in the next step, but some
+     * projections also create literal values of various types.
+     * @param v
+     * @return
+     */
+    public ProjectionType getVariableType(Var v) {
+        return variableTypes.get(v);
+    }
+
     private void prepareBuilder()  throws UnsatisfiableQueryException {
         Preconditions.checkArgument(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);
 
@@ -274,13 +323,14 @@ public class SQLBuilder {
                         Var v = fields[i];
                         if (variableNames.get(v) == null) {
                             variableNames.put(v, "V" + (++variableCount));
-                            queryVariables.put(v, new LinkedList<String>());
+                            variableTypes.put(v, ProjectionType.NODE);
+                            queryVariables.put(v.getName(), new LinkedList<String>());
                             queryVariableIds.put(v, new LinkedList<String>());
                         }
                         String pName = p.getName();
                         String vName = variableNames.get(v);
                         if (hasNodeCondition(fields[i], query)) {
-                            queryVariables.get(v).add(pName + "_" + positions[i] + "_" +
vName);
+                            queryVariables.get(v.getName()).add(pName + "_" + positions[i]
+ "_" + vName);
                         }
 
                         // if the variable has been used before, add a join condition to
the first occurrence
@@ -299,11 +349,14 @@ public class SQLBuilder {
             Var v = new Var(ext.getName());
             if (variableNames.get(v) == null) {
                 variableNames.put(v, "V" + (++variableCount));
-                queryVariables.put(v, new LinkedList<String>());
+
+                // set variable type according to expression; we need this later to decide
what kind of node to construct
+                variableTypes.put(v, getProjectionType(ext.getExpr()));
+                queryVariables.put(v.getName(), new LinkedList<String>());
                 queryVariableIds.put(v, new LinkedList<String>());
             }
             if (hasNodeCondition(v, query)) {
-                queryVariables.get(v).add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
+                queryVariables.get(v.getName()).add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
             }
             queryVariableIds.get(v).add(evaluateExpression(ext.getExpr(), OPTypes.ANY));
 
@@ -704,7 +757,7 @@ public class SQLBuilder {
             Lang lang = (Lang)expr;
 
             if(lang.getArg() instanceof Var) {
-                return queryVariables.get(lang.getArg()).get(0) + ".lang";
+                return queryVariables.get(((Var) lang.getArg()).getName()).get(0) + ".lang";
             }
         } else if(expr instanceof Compare) {
             Compare cmp = (Compare)expr;
@@ -749,7 +802,7 @@ public class SQLBuilder {
             if(arg instanceof ValueConstant) {
                 return Boolean.toString(((ValueConstant) arg).getValue() instanceof URI ||
((ValueConstant) arg).getValue() instanceof BNode);
             } else if(arg instanceof Var) {
-                String var = queryVariables.get(arg).get(0);
+                String var = queryVariables.get(((Var) arg).getName()).get(0);
 
                 return "(" + var + ".ntype = 'uri' OR " + var + ".ntype = 'bnode')";
             }
@@ -760,7 +813,7 @@ public class SQLBuilder {
             if(arg instanceof ValueConstant) {
                 return Boolean.toString(((ValueConstant) arg).getValue() instanceof URI);
             } else if(arg instanceof Var) {
-                String var = queryVariables.get(arg).get(0);
+                String var = queryVariables.get(((Var) arg).getName()).get(0);
 
                 return var + ".ntype = 'uri'";
             }
@@ -771,7 +824,7 @@ public class SQLBuilder {
             if(arg instanceof ValueConstant) {
                 return Boolean.toString(((ValueConstant) arg).getValue() instanceof BNode);
             } else if(arg instanceof Var) {
-                String var = queryVariables.get(arg).get(0);
+                String var = queryVariables.get(((Var) arg).getName()).get(0);
 
                 return var + ".ntype = 'bnode'";
             }
@@ -782,12 +835,12 @@ public class SQLBuilder {
             if(arg instanceof ValueConstant) {
                 return Boolean.toString(((ValueConstant) arg).getValue() instanceof Literal);
             } else if(arg instanceof Var) {
-                String var = queryVariables.get(arg).get(0);
+                String var = queryVariables.get(((Var) arg).getName()).get(0);
 
                 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 = queryVariables.get(expr).get(0);
+            String var = queryVariables.get(((Var) expr).getName()).get(0);
 
             if(optype == null) {
                 return var + ".svalue";
@@ -798,6 +851,7 @@ public class SQLBuilder {
                     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";
                 }
             }
@@ -810,9 +864,11 @@ public class SQLBuilder {
                 switch (optype) {
                     case STRING: return "'" + val + "'";
                     case VALUE:  return "'" + val + "'";
+                    case URI:    return "'" + val + "'";
                     case INT:    return ""  + Integer.parseInt(val);
                     case DOUBLE: return ""  + Double.parseDouble(val);
                     case DATE:   return "'" + sqlDateFormat.format(DateUtils.parseDate(val))
+ "'";
+                    case ANY:    return "'" + val + "'";
                     default: throw new IllegalArgumentException("unsupported value type:
" + optype);
                 }
             }
@@ -838,7 +894,7 @@ public class SQLBuilder {
                 return evaluateExpression(fc.getArgs().get(0), OPTypes.DATE);
             }
 
-            URI fnUri = new URIImpl(fc.getURI());
+            URI fnUri = FunctionUtil.getFunctionUri(fc.getURI());;
 
             String[] args = new String[fc.getArgs().size()];
 
@@ -928,7 +984,7 @@ public class SQLBuilder {
 
     private boolean hasNodeCondition(Var v, ValueExpr expr) {
         if(expr instanceof Var) {
-            return v.equals(expr);
+            return v.getName().equals(((Var) expr).getName());
         } else if(expr instanceof UnaryValueOperator) {
             return hasNodeCondition(v, ((UnaryValueOperator) expr).getArg());
         } else if(expr instanceof BinaryValueOperator) {
@@ -1045,6 +1101,58 @@ public class SQLBuilder {
     }
 
 
+    private ProjectionType getProjectionType(ValueExpr expr) {
+        if(expr instanceof FunctionCall) {
+            return opTypeToProjection(functionReturnTypes.get(FunctionUtil.getFunctionUri(((FunctionCall)
expr).getURI())));
+        } else if(expr instanceof NAryValueOperator) {
+            return getProjectionType(((NAryValueOperator) expr).getArguments().get(0));
+        } else if(expr instanceof ValueConstant) {
+            if (((ValueConstant) expr).getValue() instanceof URI) {
+                return ProjectionType.URI;
+            } else if (((ValueConstant) expr).getValue() instanceof Literal) {
+                Literal l = (Literal) ((ValueConstant) expr).getValue();
+                if (XSD.Integer.equals(l.getDatatype()) || XSD.Int.equals(l.getDatatype()))
{
+                    return ProjectionType.INT;
+                } else if (XSD.Double.equals(l.getDatatype()) || XSD.Float.equals(l.getDatatype()))
{
+                    return ProjectionType.DOUBLE;
+                } else {
+                    return ProjectionType.STRING;
+                }
+
+            } else {
+                return ProjectionType.STRING;
+            }
+        } else if(expr instanceof Var) {
+            return ProjectionType.NODE;
+        } else if(expr instanceof MathExpr) {
+            MathExpr cmp = (MathExpr)expr;
+
+            return opTypeToProjection(new OPTypeFinder(cmp).coerce());
+        } else {
+            return ProjectionType.STRING;
+        }
+
+    }
+
+    private ProjectionType opTypeToProjection(OPTypes t) {
+        switch (t) {
+            case ANY:
+                return ProjectionType.NODE;
+            case URI:
+                return ProjectionType.URI;
+            case DOUBLE:
+                return ProjectionType.DOUBLE;
+            case INT:
+                return ProjectionType.INT;
+            case DATE:
+                return ProjectionType.DATE;
+            case STRING:
+                return ProjectionType.STRING;
+            default:
+                log.warn("optype {} cannot be projected!",t);
+                return ProjectionType.STRING;
+        }
+    }
 
     /**
      * Construct the SQL query for the given SPARQL query part.

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/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 8cd1a15..201cccb 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
@@ -19,9 +19,9 @@ package org.apache.marmotta.kiwi.sparql.evaluation;
 
 import info.aduna.iteration.CloseableIteration;
 import info.aduna.iteration.ExceptionConvertingIteration;
+import org.apache.marmotta.kiwi.sparql.function.FunctionUtil;
 import org.apache.marmotta.kiwi.sparql.persistence.KiWiSparqlConnection;
 import org.openrdf.model.URI;
-import org.openrdf.model.impl.URIImpl;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
 import org.openrdf.query.QueryEvaluationException;
@@ -384,10 +384,11 @@ public class KiWiEvaluationStrategyImpl extends EvaluationStrategyImpl{
     }
 
     private boolean isFunctionSupported(FunctionCall fc) {
-        URI fnUri = new URIImpl(fc.getURI());
+        URI fnUri = FunctionUtil.getFunctionUri(fc.getURI());
         return connection.getDialect().isFunctionSupported(fnUri);
     }
 
+
     private static boolean isAtomic(ValueExpr expr) {
         return expr instanceof Var || expr instanceof ValueConstant;
     }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FunctionUtil.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FunctionUtil.java
b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FunctionUtil.java
new file mode 100644
index 0000000..b1cc900
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FunctionUtil.java
@@ -0,0 +1,85 @@
+/*
+ * 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.function;
+
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.vocabulary.FN;
+
+/**
+ * Add file description here!
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class FunctionUtil {
+
+    /**
+     * Map function call (internal or proper URI) to the proper SPARQL function URI
+     * @param uri
+     * @return
+     */
+    public static URI getFunctionUri(String uri) {
+        if(uri.equalsIgnoreCase("RAND")) {
+            return FN_MARMOTTA.RAND;
+        } else if(uri.equalsIgnoreCase("UUID")) {
+            return FN_MARMOTTA.UUID;
+        } else if(uri.equalsIgnoreCase("STRUUID")) {
+            return FN_MARMOTTA.STRUUID;
+        } else if(uri.equalsIgnoreCase("MD5")) {
+            return FN_MARMOTTA.MD5;
+        } else if(uri.equalsIgnoreCase("SHA1")) {
+            return FN_MARMOTTA.SHA1;
+        } else if(uri.equalsIgnoreCase("SHA256")) {
+            return FN_MARMOTTA.SHA256;
+        } else if(uri.equalsIgnoreCase("SHA384")) {
+            return FN_MARMOTTA.SHA384;
+        } else if(uri.equalsIgnoreCase("SHA512")) {
+            return FN_MARMOTTA.SHA512;
+        } else if(uri.equalsIgnoreCase("NOW")) {
+            return FN_MARMOTTA.NOW;
+        } else if(uri.equalsIgnoreCase("YEAR")) {
+            return FN_MARMOTTA.YEAR;
+        } else if(uri.equalsIgnoreCase("MONTH")) {
+            return FN_MARMOTTA.MONTH;
+        } else if(uri.equalsIgnoreCase("DAY")) {
+            return FN_MARMOTTA.DAY;
+        } else if(uri.equalsIgnoreCase("HOURS")) {
+            return FN_MARMOTTA.HOURS;
+        } else if(uri.equalsIgnoreCase("MINUTES")) {
+            return FN_MARMOTTA.MINUTES;
+        } else if(uri.equalsIgnoreCase("SECONDS")) {
+            return FN_MARMOTTA.SECONDS;
+        } else if(uri.equalsIgnoreCase("TIMEZONE")) {
+            return FN_MARMOTTA.TIMEZONE;
+        } else if(uri.equalsIgnoreCase("TZ")) {
+            return FN_MARMOTTA.TZ;
+        } else if(uri.equalsIgnoreCase("ABS")) {
+            return FN.NUMERIC_ABS;
+        } else if(uri.equalsIgnoreCase("CEIL")) {
+            return FN.NUMERIC_CEIL;
+        } else if(uri.equalsIgnoreCase("FLOOR")) {
+            return FN.NUMERIC_FLOOR;
+        } else if(uri.equalsIgnoreCase("ROUND")) {
+            return FN.NUMERIC_ROUND;
+        }
+
+        return new URIImpl(uri);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/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 3c9d288..a662e40 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
@@ -21,14 +21,18 @@ import info.aduna.iteration.CloseableIteration;
 import info.aduna.iteration.CloseableIteratorIteration;
 import info.aduna.iteration.EmptyIteration;
 import info.aduna.iteration.Iterations;
+import org.apache.marmotta.commons.vocabulary.XSD;
 import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
 import org.apache.marmotta.kiwi.persistence.KiWiConnection;
 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.apache.marmotta.kiwi.sparql.builder.ProjectionType;
 import org.apache.marmotta.kiwi.sparql.builder.SQLBuilder;
 import org.apache.marmotta.kiwi.sparql.exception.UnsatisfiableQueryException;
+import org.openrdf.model.impl.LiteralImpl;
+import org.openrdf.model.impl.URIImpl;
 import org.openrdf.query.Binding;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.Dataset;
@@ -118,14 +122,39 @@ public class KiWiSparqlConnection {
 
                         long[] nodeIds = new long[vars.size()];
                         for(int i=0; i<vars.size(); i++) {
-                            nodeIds[i] = row.getLong(builder.getVariableName(vars.get(i)));
+                            if(builder.getVariableType(vars.get(i)) == ProjectionType.NODE)
{
+                                nodeIds[i] = row.getLong(builder.getVariableName(vars.get(i)));
+                            }
                         }
                         KiWiNode[] nodes = parent.loadNodesByIds(nodeIds);
 
                         for (int i = 0; i < vars.size(); i++) {
+                            Var v = vars.get(i);
                             if(nodes[i] != null) {
-                                Var v = vars.get(i);
+                                // resolved node
                                 resultRow.addBinding(v.getName(), nodes[i]);
+                            } else {
+                                // literal value
+                                String value = row.getString(builder.getVariableName(v));
+                                if(value != null) {
+                                    switch (builder.getVariableType(v)) {
+                                        case URI:
+                                            resultRow.addBinding(v.getName(), new URIImpl(value));
+                                            break;
+                                        case INT:
+                                            resultRow.addBinding(v.getName(), new LiteralImpl(value,
XSD.Integer));
+                                            break;
+                                        case DOUBLE:
+                                            resultRow.addBinding(v.getName(), new LiteralImpl(value,
XSD.Double));
+                                            break;
+                                        case STRING:
+                                            resultRow.addBinding(v.getName(), new LiteralImpl(value));
+                                            break;
+                                        default:
+                                            resultRow.addBinding(v.getName(), new LiteralImpl(value));
+                                            break;
+                                    }
+                                }
                             }
                         }
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
index 556a5d5..42940ea 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
@@ -66,6 +66,17 @@ public class PostgreSQLDialect extends KiWiDialect {
 
         supportedFunctions.put(FN_MARMOTTA.SEARCH_FULLTEXT);
         supportedFunctions.put(FN_MARMOTTA.QUERY_FULLTEXT);
+
+        supportedFunctions.put(FN_MARMOTTA.NOW);
+
+        supportedFunctions.put(FN_MARMOTTA.RAND);
+        supportedFunctions.put(FN_MARMOTTA.UUID);
+        supportedFunctions.put(FN_MARMOTTA.STRUUID);
+        supportedFunctions.put(FN_MARMOTTA.MD5);
+        supportedFunctions.put(FN_MARMOTTA.SHA1);
+        supportedFunctions.put(FN_MARMOTTA.SHA256);
+        supportedFunctions.put(FN_MARMOTTA.SHA384);
+        supportedFunctions.put(FN_MARMOTTA.SHA512);
     }
 
     /**
@@ -246,6 +257,60 @@ public class PostgreSQLDialect extends KiWiDialect {
             } else {
                 throw new IllegalArgumentException("invalid number of arguments");
             }
+        } else if(FN_MARMOTTA.NOW.equals(fnUri)) {
+            if(args.length == 0) {
+                return "now()";
+            } else {
+                throw new IllegalArgumentException("NOW() does not take arguments");
+            }
+        } else if(FN_MARMOTTA.RAND.equals(fnUri)) {
+            if(args.length == 0) {
+                return "random()";
+            } else {
+                throw new IllegalArgumentException("RAND() does not take arguments");
+            }
+        } else if(FN_MARMOTTA.UUID.equals(fnUri)) {
+            if(args.length == 0) {
+                return "'urn:uuid:' || gen_random_uuid()";
+            } else {
+                throw new IllegalArgumentException("UUID() does not take arguments");
+            }
+        } else if(FN_MARMOTTA.STRUUID.equals(fnUri)) {
+            if(args.length == 0) {
+                return "CAST(gen_random_uuid() AS text)";
+            } else {
+                throw new IllegalArgumentException("STRUUID() does not take arguments");
+            }
+        } else if(FN_MARMOTTA.MD5.equals(fnUri)) {
+            if(args.length == 1) {
+                return String.format("encode(digest('%s', 'md5'), 'hex')", args[0]);
+            } else {
+                throw new IllegalArgumentException("MD5() takes exactly 1 argument");
+            }
+        } else if(FN_MARMOTTA.SHA1.equals(fnUri)) {
+            if(args.length == 1) {
+                return String.format("encode(digest('%s', 'sha1'), 'hex')", args[0]);
+            } else {
+                throw new IllegalArgumentException("SHA1() takes exactly 1 argument");
+            }
+        } else if(FN_MARMOTTA.SHA256.equals(fnUri)) {
+            if(args.length == 1) {
+                return String.format("encode(digest('%s', 'sha256'), 'hex')", args[0]);
+            } else {
+                throw new IllegalArgumentException("SHA256() takes exactly 1 argument");
+            }
+        } else if(FN_MARMOTTA.SHA384.equals(fnUri)) {
+            if(args.length == 1) {
+                return String.format("encode(digest('%s', 'sha384'), 'hex')", args[0]);
+            } else {
+                throw new IllegalArgumentException("SHA384() takes exactly 1 argument");
+            }
+        } else if(FN_MARMOTTA.SHA512.equals(fnUri)) {
+            if(args.length == 1) {
+                return String.format("encode(digest('%s', 'sha512'), 'hex')", args[0]);
+            } else {
+                throw new IllegalArgumentException("SHA512() takes exactly 1 argument");
+            }
         }
         throw new UnsupportedOperationException("operation "+fnUri+" not supported");
     }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
index 47c3b8a..89f2b41 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
@@ -48,10 +48,48 @@ public class FN_MARMOTTA {
 
     public static final URI QUERY_FULLTEXT;
 
+    // URIs for SPARQL built-in functions, used internally by marmotta
+    public static final URI RAND;
+    public static final URI UUID;
+    public static final URI STRUUID;
+    public static final URI NOW;
+    public static final URI YEAR;
+    public static final URI MONTH;
+    public static final URI DAY;
+    public static final URI HOURS;
+    public static final URI MINUTES;
+    public static final URI SECONDS;
+    public static final URI TIMEZONE;
+    public static final URI TZ;
+    public static final URI MD5;
+    public static final URI SHA1;
+    public static final URI SHA256;
+    public static final URI SHA384;
+    public static final URI SHA512;
+
+
     static {
         ValueFactory f = new ValueFactoryImpl();
 
         SEARCH_FULLTEXT = f.createURI(NAMESPACE,"fulltext-search");
         QUERY_FULLTEXT = f.createURI(NAMESPACE,"fulltext-query");
+
+        RAND      = f.createURI(NAMESPACE,"rand");
+        UUID      = f.createURI(NAMESPACE,"uuid");
+        STRUUID   = f.createURI(NAMESPACE,"struuid");
+        NOW       = f.createURI(NAMESPACE,"now");
+        YEAR      = f.createURI(NAMESPACE,"year");
+        MONTH     = f.createURI(NAMESPACE,"month");
+        DAY       = f.createURI(NAMESPACE,"day");
+        HOURS     = f.createURI(NAMESPACE,"hours");
+        MINUTES   = f.createURI(NAMESPACE,"minutes");
+        SECONDS   = f.createURI(NAMESPACE,"seconds");
+        TIMEZONE  = f.createURI(NAMESPACE,"timezone");
+        TZ        = f.createURI(NAMESPACE,"tz");
+        MD5       = f.createURI(NAMESPACE,"md5");
+        SHA1      = f.createURI(NAMESPACE,"sha1");
+        SHA256    = f.createURI(NAMESPACE,"sha256");
+        SHA384    = f.createURI(NAMESPACE,"sha384");
+        SHA512    = f.createURI(NAMESPACE,"sha512");
     }
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/5be6ef2e/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
index 1936a6b..844005f 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
@@ -14,6 +14,8 @@
 -- limitations under the License.
 CREATE TYPE nodetype AS ENUM ('uri','bnode','string','int','double','date','boolean');
 
+CREATE EXTENSION IF NOT EXISTS pgcrypto;
+
 CREATE TABLE nodes (
   id        bigint     NOT NULL,
   ntype     nodetype   NOT NULL,


Mime
View raw message