finished MARMOTTA-543 (modular function support): code cleanups and simplifications in native SPARQL support
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/5d94ae2e Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/5d94ae2e Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/5d94ae2e Branch: refs/heads/develop Commit: 5d94ae2ef03ea97db630814eeb400dfe6c2bf36f Parents: dc4cddd Author: Sebastian Schaffert <[email protected]> Authored: Fri Sep 19 18:39:22 2014 +0200 Committer: Sebastian Schaffert <[email protected]> Committed: Fri Sep 19 18:39:22 2014 +0200 ---------------------------------------------------------------------- .../kiwi/sparql/builder/ConditionFinder.java | 62 +++++ .../kiwi/sparql/builder/SQLBuilder.java | 174 +++---------- .../kiwi/sparql/builder/SQLFunction.java | 85 ------ .../evaluation/KiWiEvaluationStrategyImpl.java | 6 +- .../sparql/function/AggregationFunction.java | 35 +++ .../sparql/function/NativeFunctionRegistry.java | 5 + .../kiwi/sparql/function/custom/Stddev.java | 114 ++++++++ .../kiwi/sparql/function/custom/Variance.java | 114 ++++++++ ...marmotta.kiwi.sparql.function.NativeFunction | 2 + .../kiwi/sparql/test/KiWiSparqlJoinTest.java | 5 +- .../marmotta/kiwi/persistence/KiWiDialect.java | 76 ------ .../marmotta/kiwi/persistence/h2/H2Dialect.java | 107 -------- .../kiwi/persistence/mysql/MySQLDialect.java | 120 --------- .../persistence/pgsql/PostgreSQLDialect.java | 259 ------------------- .../marmotta/kiwi/vocabulary/FN_MARMOTTA.java | 15 +- 15 files changed, 374 insertions(+), 805 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 new file mode 100644 index 0000000..16cbc00 --- /dev/null +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/ConditionFinder.java @@ -0,0 +1,62 @@ +/* + * 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; + +import org.openrdf.query.algebra.*; +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase; + +/** + * Check if a variable is used as a condition somewhere and therefore needs to be resolved. + * + * @author Sebastian Schaffert ([email protected]) + */ +public class ConditionFinder extends QueryModelVisitorBase<RuntimeException> { + + boolean found = false; + + private String varName; + + public ConditionFinder(String varName, TupleExpr expr) { + this.varName = varName; + + expr.visit(this); + } + + public ConditionFinder(String varName, ValueExpr expr) { + this.varName = varName; + + expr.visit(this); + } + + @Override + public void meet(Var node) throws RuntimeException { + if(!found) { + found = node.getName().equals(varName); + } + } + + @Override + public void meet(Union node) throws RuntimeException { + // stop, subquery + } + + @Override + public void meet(Projection node) throws RuntimeException { + // stop, subquery + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 8790edf..63b4661 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 @@ -26,8 +26,8 @@ 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.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.sparql.function.NativeFunctionRegistry; import org.openrdf.model.*; import org.openrdf.model.vocabulary.FN; import org.openrdf.model.vocabulary.SESAME; @@ -64,60 +64,9 @@ public class SQLBuilder { /** - * Type coercion for function parameters and return values, defines for each function the type used by its parameters + * Reference to the registry of natively supported functions with parameter and return types as well as SQL translation */ - private static Map<URI, SQLFunction> functions = new HashMap<>(); - - private static void addFunction(URI uri, OPTypes paramType, OPTypes returnType, SQLFunction.Arity arity) { - functions.put(uri, new SQLFunction(uri,paramType,returnType,arity)); - } - - static { - addFunction(FN.CONCAT, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.NARY); - addFunction(FN.CONTAINS, OPTypes.STRING, OPTypes.BOOL, SQLFunction.Arity.BINARY); - addFunction(FN.LOWER_CASE, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN.UPPER_CASE, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN.REPLACE, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.BINARY); - addFunction(FN.SUBSTRING_AFTER, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.BINARY); - addFunction(FN.SUBSTRING_BEFORE, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.BINARY); - addFunction(FN.STARTS_WITH, OPTypes.STRING, OPTypes.BOOL, SQLFunction.Arity.BINARY); - addFunction(FN.ENDS_WITH, OPTypes.STRING, OPTypes.BOOL, SQLFunction.Arity.BINARY); - addFunction(FN.STRING_LENGTH, OPTypes.STRING, OPTypes.INT, SQLFunction.Arity.BINARY); - addFunction(FN.SUBSTRING, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.BINARY); - - addFunction(FN.NUMERIC_ABS, OPTypes.DOUBLE, OPTypes.DOUBLE, SQLFunction.Arity.UNARY); - addFunction(FN.NUMERIC_CEIL, OPTypes.DOUBLE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN.NUMERIC_FLOOR, OPTypes.DOUBLE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN.NUMERIC_ROUND, OPTypes.DOUBLE, OPTypes.INT, SQLFunction.Arity.UNARY); - - - addFunction(FN_MARMOTTA.YEAR, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.MONTH, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.DAY, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.HOURS, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.MINUTES, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.SECONDS, OPTypes.DATE, OPTypes.INT, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.TIMEZONE, OPTypes.DATE, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.TZ, OPTypes.DATE, OPTypes.STRING, SQLFunction.Arity.UNARY); - - addFunction(FN_MARMOTTA.MD5, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.SHA1, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.SHA256, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.SHA384, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.SHA512, OPTypes.STRING, OPTypes.STRING, SQLFunction.Arity.UNARY); - - addFunction(FN_MARMOTTA.UUID, OPTypes.ANY, OPTypes.URI, SQLFunction.Arity.ZERO); - addFunction(FN_MARMOTTA.STRUUID, OPTypes.ANY, OPTypes.STRING, SQLFunction.Arity.ZERO); - addFunction(FN_MARMOTTA.RAND, OPTypes.ANY, OPTypes.DOUBLE, SQLFunction.Arity.ZERO); - - addFunction(FN_MARMOTTA.STDDEV, OPTypes.DOUBLE, OPTypes.DOUBLE, SQLFunction.Arity.UNARY); - addFunction(FN_MARMOTTA.VARIANCE, OPTypes.DOUBLE, OPTypes.DOUBLE, SQLFunction.Arity.UNARY); - - addFunction(FN_MARMOTTA.QUERY_FULLTEXT, OPTypes.STRING, OPTypes.BOOL, SQLFunction.Arity.NARY); - addFunction(FN_MARMOTTA.SEARCH_FULLTEXT, OPTypes.STRING, OPTypes.BOOL, SQLFunction.Arity.NARY); - - } - + private NativeFunctionRegistry functionRegistry = NativeFunctionRegistry.getInstance(); /** * Query results should be DISTINCT. @@ -275,7 +224,7 @@ public class SQLBuilder { String pName = p.getName(); String vName = sv.getName(); - if (hasNodeCondition(v.getName(), query)) { + if (new ConditionFinder(v.getName(), query).found) { sv.getAliases().add(pName + "_" + positions[i] + "_" + vName); } @@ -308,7 +257,7 @@ public class SQLBuilder { String sqName = sq.getAlias(); String vName = sv.getName(); - if (hasNodeCondition(sq_v.getSparqlName(), query)) { + if (new ConditionFinder(sq_v.getSparqlName(), query).found) { sv.getAliases().add(sqName + "_" + vName); } @@ -344,7 +293,7 @@ public class SQLBuilder { // 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)) { + if (new ConditionFinder(v.getName(), query).found) { //sv.getAliases().add(evaluateExpression(ext.getExpr(), OPTypes.VALUE)); sv.getBindings().add(ext.getExpr()); } @@ -515,7 +464,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() && hasNodeCondition(fieldEntry.getValue().getName(),query)) { + if(fieldEntry.getValue() != null && !fieldEntry.getValue().hasValue() && new ConditionFinder(fieldEntry.getValue().getName(),query).found) { p.setJoinField(fieldEntry.getKey(), variables.get(fieldEntry.getValue().getName()).getName()); } } @@ -523,7 +472,7 @@ public class SQLBuilder { for(SQLAbstractSubquery sq : f.getSubqueries()) { for(SQLVariable sq_v : sq.getQueryVariables()) { - if(hasNodeCondition(sq_v.getSparqlName(),query) && sq_v.getProjectionType() == ProjectionType.NODE) { + if(new ConditionFinder(sq_v.getSparqlName(),query).found && 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 VariableMapping(sv.getName(), sq_v.getName())); @@ -757,7 +706,7 @@ public class SQLBuilder { if(ot == OPTypes.STRING) { if(cmp.getOperator() == MathExpr.MathOp.PLUS) { - return dialect.getConcat(evaluateExpression(cmp.getLeftArg(), ot), evaluateExpression(cmp.getRightArg(), ot)); + return NativeFunctionRegistry.getInstance().get(FN.CONCAT.stringValue()).getNative(dialect,evaluateExpression(cmp.getLeftArg(), ot), evaluateExpression(cmp.getRightArg(), ot)); } else { throw new IllegalArgumentException("operation "+cmp.getOperator()+" is not supported on strings"); } @@ -942,20 +891,26 @@ public class SQLBuilder { return evaluateExpression(fc.getArgs().get(0), OPTypes.DATE); } - URI fnUri = FunctionUtil.getFunctionUri(fc.getURI());; + String fnUri = fc.getURI(); String[] args = new String[fc.getArgs().size()]; - OPTypes fOpType = functions.containsKey(fnUri) ? functions.get(fnUri).getParameterType() : OPTypes.STRING; + NativeFunction nf = functionRegistry.get(fnUri); - for(int i=0; i<args.length;i++) { - args[i] = evaluateExpression(fc.getArgs().get(i), fOpType); - } + if(nf != null && nf.isSupported(dialect)) { + OPTypes fOpType = nf.getArgumentType(0); - if(optype != null && (!functions.containsKey(fnUri) || optype != functions.get(fnUri).getReturnType())) { - return castExpression(dialect.getFunction(fnUri, args), optype); + for (int i = 0; i < args.length; i++) { + args[i] = evaluateExpression(fc.getArgs().get(i), fOpType); + } + + if (optype != null && optype != nf.getReturnType()) { + return castExpression(nf.getNative(dialect, args), optype); + } else { + return nf.getNative(dialect, args); + } } else { - return dialect.getFunction(fnUri, args); + throw new IllegalArgumentException("the function "+fnUri+" is not supported by the SQL translation"); } } @@ -989,13 +944,13 @@ public class SQLBuilder { switch (type) { case DOUBLE: - return dialect.getFunction(XMLSchema.DOUBLE, arg); + return functionRegistry.get(XMLSchema.DOUBLE).getNative(dialect, arg); case INT: - return dialect.getFunction(XMLSchema.INTEGER, arg); + return functionRegistry.get(XMLSchema.INTEGER).getNative(dialect, arg); case BOOL: - return dialect.getFunction(XMLSchema.BOOLEAN, arg); + return functionRegistry.get(XMLSchema.BOOLEAN).getNative(dialect, arg); case DATE: - return dialect.getFunction(XMLSchema.DATETIME, arg); + return functionRegistry.get(XMLSchema.DATETIME).getNative(dialect, arg); case VALUE: return arg; case ANY: @@ -1005,77 +960,6 @@ public class SQLBuilder { } } - /** - * Check if a variable selecting a node actually has any attached condition; if not return false. This is used to - * decide whether joining with the node itself is necessary. - * - * TODO: could be implemented as visitor instead - * - * @param varName - * @param expr - * @return - */ - private boolean hasNodeCondition(String varName, TupleExpr expr) { - if(expr instanceof Filter) { - return hasNodeCondition(varName, ((UnaryTupleOperator) expr).getArg()) || hasNodeCondition(varName, ((Filter) expr).getCondition()); - } else if(expr instanceof Extension) { - for(ExtensionElem elem : ((Extension) expr).getElements()) { - if(hasNodeCondition(varName, elem.getExpr())) { - return true; - } - } - return hasNodeCondition(varName,((Extension) expr).getArg()); - } else if(expr instanceof Order) { - for(OrderElem elem : ((Order) expr).getElements()) { - if(hasNodeCondition(varName, elem.getExpr())) { - return true; - } - } - return hasNodeCondition(varName,((Order) expr).getArg()); - } else if(expr instanceof Group) { - for(GroupElem elem : ((Group) expr).getGroupElements()) { - if(hasNodeCondition(varName, elem.getOperator())) { - return true; - } - } - return hasNodeCondition(varName,((Group) expr).getArg()); - } else if(expr instanceof Union) { - return false; // stop looking, this is a subquery - } else if(expr instanceof Projection) { - return false; // stop looking, this is a subquery - } else if(expr instanceof UnaryTupleOperator) { - return hasNodeCondition(varName, ((UnaryTupleOperator) expr).getArg()); - } else if(expr instanceof BinaryTupleOperator) { - return hasNodeCondition(varName, ((BinaryTupleOperator) expr).getLeftArg()) || hasNodeCondition(varName, ((BinaryTupleOperator) expr).getRightArg()); - } else { - return false; - } - - } - - private boolean hasNodeCondition(String varName, ValueExpr expr) { - if(expr instanceof Var) { - return varName.equals(((Var) expr).getName()); - } else if(expr instanceof UnaryValueOperator) { - return hasNodeCondition(varName, ((UnaryValueOperator) expr).getArg()); - } else if(expr instanceof BinaryValueOperator) { - return hasNodeCondition(varName, ((BinaryValueOperator) expr).getLeftArg()) || hasNodeCondition(varName, ((BinaryValueOperator) expr).getRightArg()); - } else if(expr instanceof NAryValueOperator) { - for(ValueExpr e : ((NAryValueOperator) expr).getArguments()) { - if(hasNodeCondition(varName,e)) { - return true; - } - } - } else if(expr instanceof FunctionCall) { - for(ValueExpr e : ((FunctionCall) expr).getArgs()) { - if(hasNodeCondition(varName,e)) { - return true; - } - } - } - return false; - } - private String getSQLOperator(Compare.CompareOp op) { switch (op) { case EQ: return " = "; @@ -1174,7 +1058,7 @@ public class SQLBuilder { protected ProjectionType getProjectionType(ValueExpr expr) { if(expr instanceof FunctionCall) { - return opTypeToProjection(functions.get(FunctionUtil.getFunctionUri(((FunctionCall) expr).getURI())).getReturnType()); + return opTypeToProjection(functionRegistry.get(((FunctionCall) expr).getURI()).getReturnType()); } else if(expr instanceof NAryValueOperator) { return getProjectionType(((NAryValueOperator) expr).getArguments().get(0)); } else if(expr instanceof ValueConstant) { http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFunction.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFunction.java deleted file mode 100644 index 527da72..0000000 --- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/builder/SQLFunction.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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; - -import org.openrdf.model.URI; - -/** - * Description of a SPARQL function to give details about various characteristics that we need when translating to - * SQL, most importantly the parameter and return types. - * - * @author Sebastian Schaffert ([email protected]) - */ -public class SQLFunction { - - public static enum Arity { ZERO, UNARY, BINARY, NARY }; - - private URI uri; - - private OPTypes parameterType, returnType; - - private Arity arity; - - public SQLFunction(URI uri, OPTypes parameterType, OPTypes returnType, Arity arity) { - this.uri = uri; - this.parameterType = parameterType; - this.returnType = returnType; - this.arity = arity; - } - - - public URI getUri() { - return uri; - } - - public OPTypes getParameterType() { - return parameterType; - } - - public OPTypes getReturnType() { - return returnType; - } - - public Arity getArity() { - return arity; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - SQLFunction that = (SQLFunction) o; - - if (arity != that.arity) return false; - if (parameterType != that.parameterType) return false; - if (returnType != that.returnType) return false; - if (!uri.equals(that.uri)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = uri.hashCode(); - result = 31 * result + parameterType.hashCode(); - result = 31 * result + returnType.hashCode(); - result = 31 * result + arity.hashCode(); - return result; - } -} http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 f8c7c1d..6fec050 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,8 @@ 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.function.NativeFunctionRegistry; import org.apache.marmotta.kiwi.sparql.persistence.KiWiSparqlConnection; -import org.openrdf.model.URI; import org.openrdf.query.BindingSet; import org.openrdf.query.Dataset; import org.openrdf.query.QueryEvaluationException; @@ -355,8 +354,7 @@ public class KiWiEvaluationStrategyImpl extends EvaluationStrategyImpl{ } private boolean isFunctionSupported(FunctionCall fc) { - URI fnUri = FunctionUtil.getFunctionUri(fc.getURI()); - return connection.getDialect().isFunctionSupported(fnUri); + return NativeFunctionRegistry.getInstance().get(fc.getURI()) != null && NativeFunctionRegistry.getInstance().get(fc.getURI()).isSupported(connection.getDialect()); } http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/AggregationFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/AggregationFunction.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/AggregationFunction.java new file mode 100644 index 0000000..c21dd83 --- /dev/null +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/AggregationFunction.java @@ -0,0 +1,35 @@ +/* + * 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.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.Function; + +/** + * This is a marker for aggregation functions. They cannot be evaluated as functions in Java. + * + * @author Sebastian Schaffert ([email protected]) + */ +public abstract class AggregationFunction implements Function { + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("custom aggregation functions cannot be evaluated in-memory"); + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/NativeFunctionRegistry.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/NativeFunctionRegistry.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/NativeFunctionRegistry.java index cb57f61..cdd00c5 100644 --- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/NativeFunctionRegistry.java +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/NativeFunctionRegistry.java @@ -18,6 +18,7 @@ package org.apache.marmotta.kiwi.sparql.function; import info.aduna.lang.service.ServiceRegistry; +import org.openrdf.model.URI; /** * Registry for natively supported functions @@ -50,4 +51,8 @@ public class NativeFunctionRegistry extends ServiceRegistry<String,NativeFunctio { return function.getURI(); } + + public NativeFunction get(URI uri) { + return get(uri.stringValue()); + } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Stddev.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Stddev.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Stddev.java new file mode 100644 index 0000000..24898de --- /dev/null +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Stddev.java @@ -0,0 +1,114 @@ +/* + * 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.custom; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.h2.H2Dialect; +import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.OPTypes; +import org.apache.marmotta.kiwi.sparql.function.AggregationFunction; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public class Stddev extends AggregationFunction implements NativeFunction { + + /** + * Return true if this function has available native support for the given dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect || dialect instanceof H2Dialect || dialect instanceof MySQLDialect; + } + + /** + * Return a string representing how this function is translated into SQL in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if(dialect instanceof PostgreSQLDialect) { + return String.format("stddev(%s)", args[0]); + } else if(dialect instanceof H2Dialect) { + return String.format("STDDEV_POP(%s)", args[0]); + } else if(dialect instanceof MySQLDialect) { + return String.format("STDDEV(%s)", args[0]); + + } + throw new UnsupportedOperationException("STDDEV not supported by dialect "+dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting inside KiWi. + * + * @return + */ + @Override + public OPTypes getReturnType() { + return OPTypes.DOUBLE; + } + + /** + * Get the argument type of the function for the arg'th argument (starting to count at 0). + * This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public OPTypes getArgumentType(int arg) { + return OPTypes.DOUBLE; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 1; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 1; + } + + @Override + public String getURI() { + return FN_MARMOTTA.STDDEV.stringValue(); + } + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Variance.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Variance.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Variance.java new file mode 100644 index 0000000..7d94ac6 --- /dev/null +++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/custom/Variance.java @@ -0,0 +1,114 @@ +/* + * 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.custom; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.h2.H2Dialect; +import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.OPTypes; +import org.apache.marmotta.kiwi.sparql.function.AggregationFunction; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public class Variance extends AggregationFunction implements NativeFunction { + + /** + * Return true if this function has available native support for the given dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect || dialect instanceof H2Dialect || dialect instanceof MySQLDialect; + } + + /** + * Return a string representing how this function is translated into SQL in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if(dialect instanceof PostgreSQLDialect) { + return String.format("variance(%s)", args[0]); + } else if(dialect instanceof H2Dialect) { + return String.format("VAR_POP(%s)", args[0]); + } else if(dialect instanceof MySQLDialect) { + return String.format("VARIANCE(%s)", args[0]); + + } + throw new UnsupportedOperationException("VARIANCE not supported by dialect "+dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting inside KiWi. + * + * @return + */ + @Override + public OPTypes getReturnType() { + return OPTypes.DOUBLE; + } + + /** + * Get the argument type of the function for the arg'th argument (starting to count at 0). + * This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public OPTypes getArgumentType(int arg) { + return OPTypes.DOUBLE; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 1; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 1; + } + + @Override + public String getURI() { + return FN_MARMOTTA.VARIANCE.stringValue(); + } + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.sparql.function.NativeFunction ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.sparql.function.NativeFunction b/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.sparql.function.NativeFunction index 94b3db8..2a1d428 100644 --- a/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.sparql.function.NativeFunction +++ b/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.sparql.function.NativeFunction @@ -25,6 +25,8 @@ org.apache.marmotta.kiwi.sparql.function.cast.NStringCast org.apache.marmotta.kiwi.sparql.function.custom.FulltextQueryFunction org.apache.marmotta.kiwi.sparql.function.custom.FulltextSearchFunction +org.apache.marmotta.kiwi.sparql.function.custom.Stddev +org.apache.marmotta.kiwi.sparql.function.custom.Variance org.apache.marmotta.kiwi.sparql.function.datetime.NDay org.apache.marmotta.kiwi.sparql.function.datetime.NHours http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 7fa9c6a..db78564 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 @@ -27,6 +27,7 @@ import org.apache.marmotta.commons.sesame.model.StatementCommons; import org.apache.marmotta.commons.vocabulary.FOAF; import org.apache.marmotta.kiwi.config.KiWiConfiguration; import org.apache.marmotta.kiwi.sail.KiWiStore; +import org.apache.marmotta.kiwi.sparql.function.NativeFunctionRegistry; import org.apache.marmotta.kiwi.sparql.sail.KiWiSparqlSail; import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner; import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA; @@ -341,7 +342,7 @@ public class KiWiSparqlJoinTest { // fulltext search filter @Test public void testQuery22() throws Exception { - Assume.assumeTrue(dbConfig.getDialect().isFunctionSupported(FN_MARMOTTA.SEARCH_FULLTEXT)); + Assume.assumeTrue(NativeFunctionRegistry.getInstance().get(FN_MARMOTTA.SEARCH_FULLTEXT).isSupported(dbConfig.getDialect())); String queryString = IOUtils.toString(this.getClass().getResourceAsStream("query22.sparql"), "UTF-8"); RepositoryConnection con1 = repository.getConnection(); @@ -370,7 +371,7 @@ public class KiWiSparqlJoinTest { // fulltext query filter @Test public void testQuery23() throws Exception { - Assume.assumeTrue(dbConfig.getDialect().isFunctionSupported(FN_MARMOTTA.SEARCH_FULLTEXT)); + Assume.assumeTrue(NativeFunctionRegistry.getInstance().get(FN_MARMOTTA.SEARCH_FULLTEXT).isSupported(dbConfig.getDialect())); String queryString = IOUtils.toString(this.getClass().getResourceAsStream("query23.sparql"), "UTF-8"); RepositoryConnection con1 = repository.getConnection(); http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiDialect.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiDialect.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiDialect.java index c8ede67..b87972a 100644 --- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiDialect.java +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiDialect.java @@ -17,18 +17,12 @@ */ package org.apache.marmotta.kiwi.persistence; -import com.google.common.collect.ImmutableSet; -import com.google.common.hash.BloomFilter; import org.apache.commons.io.IOUtils; -import org.apache.marmotta.commons.sesame.hashing.URIFunnel; import org.apache.marmotta.kiwi.exception.DriverNotFoundException; -import org.openrdf.model.URI; -import org.openrdf.model.vocabulary.FN; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URL; -import java.util.Collections; import java.util.Enumeration; import java.util.Properties; import java.util.Set; @@ -44,7 +38,6 @@ public abstract class KiWiDialect { private static Logger log = LoggerFactory.getLogger(KiWiDialect.class); private final static int VERSION = 2; - protected BloomFilter<URI> supportedFunctions; private Properties statements; @@ -62,7 +55,6 @@ public abstract class KiWiDialect { log.error("could not load statement definitions (statement.properties)",e); } - supportedFunctions = BloomFilter.create(URIFunnel.getInstance(), 1000); } public int getVersion() { @@ -178,38 +170,6 @@ public abstract class KiWiDialect { } /** - * Return the names of all sequences that have been configured in the system, i.e. all statements starting with "seq." - * @return - */ - public Set<String> listSequences(String scriptName) { - // quick hack for current modules, fix later! - if("base".equals(scriptName)) { - return ImmutableSet.of("seq.nodes", "seq.triples", "seq.namespaces"); - } else if("reasoner".equals(scriptName)) { - return ImmutableSet.of("seq.rules", "seq.justifications", "seq.programs"); - } else if("versioning".equals(scriptName)) { - return ImmutableSet.of("seq.versions"); - } else if("ldcache".equals(scriptName)) { - return ImmutableSet.of("seq.ldcache"); - } else { - return Collections.emptySet(); - } - - - /* - Set<String> names = new HashSet<String>(); - Enumeration e = statements.propertyNames(); - while(e.hasMoreElements()) { - String[] keys = e.nextElement().toString().split("\\."); - if(keys[0].equals("seq")) { - names.add(keys[0] + "." + keys[1]); - } - } - return names; - */ - } - - /** * Return the database specific operator for matching a text against a regular expression. * * @@ -239,17 +199,6 @@ public abstract class KiWiDialect { public abstract String getILike(String text, String pattern); - /** - * Get the database specific string concatenation function for the (variable number of) arguments. - * - * @param args - * @deprecated use {@link #getFunction(URI, String...)} instead - * @return - */ - @Deprecated - public String getConcat(String... args) { - return getFunction(FN.CONCAT, args); - } /** @@ -259,31 +208,6 @@ public abstract class KiWiDialect { */ public abstract String getValidationQuery(); - /** - * Return an SQL string for evaluating the function with the given URI on the arguments. All arguments are already - * properly substituted SQL expressions (e.g. field names or constants). - * <p/> - * Dialects should at least implement support for all functions defined in the SPARQL specification (http://www.w3.org/TR/sparql11-query/#SparqlOps) - * - * @param fnUri - * @param args - * @throws UnsupportedOperationException in case the function with the given URI is not supported - * @return - */ - public abstract String getFunction(URI fnUri, String... args); - - - /** - * Return true in case the database dialect offers direct support for the function with the URI given as argument. - * This method is used to determine whether a SPARQL query containing a function can be optimized or needs to be - * evaluated in-memory. - * - * @param fnUri - * @return - */ - public boolean isFunctionSupported(URI fnUri) { - return supportedFunctions.mightContain(fnUri); - } /** * Return true in case the database system supports using cursors for queries over large data tables. http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/h2/H2Dialect.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/h2/H2Dialect.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/h2/H2Dialect.java index 010ee5f..fdbbc63 100644 --- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/h2/H2Dialect.java +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/h2/H2Dialect.java @@ -17,13 +17,9 @@ */ package org.apache.marmotta.kiwi.persistence.h2; -import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; import org.apache.marmotta.kiwi.exception.DriverNotFoundException; import org.apache.marmotta.kiwi.persistence.KiWiDialect; -import org.openrdf.model.URI; -import org.openrdf.model.vocabulary.FN; -import org.openrdf.model.vocabulary.XMLSchema; /** * Add file description here! @@ -38,29 +34,6 @@ public class H2Dialect extends KiWiDialect { } catch (ClassNotFoundException e) { throw new DriverNotFoundException(getDriverClass()); } - - supportedFunctions.put(FN.CONCAT); - supportedFunctions.put(FN.CONTAINS); - supportedFunctions.put(FN.LOWER_CASE); - supportedFunctions.put(FN.UPPER_CASE); - supportedFunctions.put(FN.REPLACE); - supportedFunctions.put(FN.SUBSTRING_AFTER); - supportedFunctions.put(FN.SUBSTRING_BEFORE); - supportedFunctions.put(FN.STRING_LENGTH); - supportedFunctions.put(FN.STARTS_WITH); - supportedFunctions.put(FN.ENDS_WITH); - - supportedFunctions.put(XMLSchema.DOUBLE); - supportedFunctions.put(XMLSchema.FLOAT); - supportedFunctions.put(XMLSchema.INTEGER); - supportedFunctions.put(XMLSchema.DECIMAL); - supportedFunctions.put(XMLSchema.DATETIME); - supportedFunctions.put(XMLSchema.BOOLEAN); - - supportedFunctions.put(FN.NUMERIC_ABS); - supportedFunctions.put(FN.NUMERIC_CEIL); - supportedFunctions.put(FN.NUMERIC_FLOOR); - supportedFunctions.put(FN.NUMERIC_ROUND); } /** @@ -126,84 +99,4 @@ public class H2Dialect extends KiWiDialect { return "SELECT 1"; } - /** - * Return an SQL string for evaluating the function with the given URI on the arguments. All arguments are already - * properly substituted SQL expressions (e.g. field names or constants). - * <p/> - * Dialects should at least implement support for all functions defined in the SPARQL specification (http://www.w3.org/TR/sparql11-query/#SparqlOps) - * - * @param fnUri - * @param args - * @return - * @throws UnsupportedOperationException in case the function with the given URI is not supported - */ - @Override - public String getFunction(URI fnUri, String... args) { - if(FN.CONCAT.equals(fnUri)) { - return String.format("CONCAT(%s)", StringUtils.join(args, ",")); - } else if(FN.CONTAINS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(%s, %s) > 0)", args[1], args[0]); - } else if(FN.LOWER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("LOWER(%s)", args[0]); - } else if(FN.UPPER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("UPPER(%s)", args[0]); - } else if(FN.REPLACE.equals(fnUri)) { - if(args.length == 3) { - // no flags - return String.format("REGEXP_REPLACE(%s, %s, %s)", args[0], args[1], args[2]); - } else { - throw new IllegalArgumentException("invalid number of arguments"); - } - } else if(FN.SUBSTRING_AFTER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s, %1$s) > 0 THEN substring(%1$s, position(%2$s, %1$s) + CHAR_LENGTH(%2$s)) ELSE '' END)", args[0], args[1]); - } else if(FN.SUBSTRING_BEFORE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s, %1$s) > 0 THEN substring(%1$s, 1, position(%2$s, %1$s)-1) ELSE '' END)", args[0], args[1]); - } else if(FN.STRING_LENGTH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CHAR_LENGTH(%s)", args[0]); - - } else if(FN.STARTS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(%2$s, %1$s) = 1)", args[0], args[1]); - } else if(FN.ENDS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(SUBSTRING(%1$s, - CHAR_LENGTH(%2$s)) = %2$s)", args[0], args[1]); - } else if(FN.NUMERIC_ABS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("abs(%s)", args[0]); - } else if(FN.NUMERIC_CEIL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("ceil(%s)", args[0]); - } else if(FN.NUMERIC_FLOOR.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("floor(%s)", args[0]); - } else if(FN.NUMERIC_ROUND.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("round(%s)", args[0]); - } else if(XMLSchema.DOUBLE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS double precision)", args[0]); - } else if(XMLSchema.FLOAT.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS double precision)", args[0]); - } else if(XMLSchema.INTEGER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS bigint)", args[0]); - } else if(XMLSchema.DECIMAL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS decimal)", args[0]); - } else if(XMLSchema.DATETIME.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS timestamp)", args[0]); - } else if(XMLSchema.BOOLEAN.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS boolean)", args[0]); - } - throw new UnsupportedOperationException("operation "+fnUri+" not supported"); - } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java index d23b370..0a24b75 100644 --- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java @@ -17,13 +17,9 @@ */ package org.apache.marmotta.kiwi.persistence.mysql; -import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; import org.apache.marmotta.kiwi.exception.DriverNotFoundException; import org.apache.marmotta.kiwi.persistence.KiWiDialect; -import org.openrdf.model.URI; -import org.openrdf.model.vocabulary.FN; -import org.openrdf.model.vocabulary.XMLSchema; /** * A dialect for MySQL. When using MySQL, make sure the JDBC connection URL has the following arguments (workarounds @@ -49,32 +45,6 @@ public class MySQLDialect extends KiWiDialect { } catch (ClassNotFoundException e) { throw new DriverNotFoundException(getDriverClass()); } - - supportedFunctions.put(FN.CONCAT); - supportedFunctions.put(FN.CONTAINS); - supportedFunctions.put(FN.LOWER_CASE); - supportedFunctions.put(FN.UPPER_CASE); - supportedFunctions.put(FN.SUBSTRING_AFTER); - supportedFunctions.put(FN.SUBSTRING_BEFORE); - supportedFunctions.put(FN.STRING_LENGTH); - supportedFunctions.put(FN.STARTS_WITH); - supportedFunctions.put(FN.ENDS_WITH); - - supportedFunctions.put(FN.NUMERIC_ABS); - supportedFunctions.put(FN.NUMERIC_CEIL); - supportedFunctions.put(FN.NUMERIC_FLOOR); - supportedFunctions.put(FN.NUMERIC_ROUND); - - supportedFunctions.put(XMLSchema.DOUBLE); - supportedFunctions.put(XMLSchema.FLOAT); - supportedFunctions.put(XMLSchema.INTEGER); - supportedFunctions.put(XMLSchema.DECIMAL); - supportedFunctions.put(XMLSchema.DATETIME); - supportedFunctions.put(XMLSchema.BOOLEAN); - /* - supportedFunctions.put(FN_MARMOTTA.SEARCH_FULLTEXT); - supportedFunctions.put(FN_MARMOTTA.QUERY_FULLTEXT); - */ } /** @@ -141,94 +111,4 @@ public class MySQLDialect extends KiWiDialect { return "SELECT 1"; } - /** - * Return an SQL string for evaluating the function with the given URI on the arguments. All arguments are already - * properly substituted SQL expressions (e.g. field names or constants). - * <p/> - * Dialects should at least implement support for all functions defined in the SPARQL specification (http://www.w3.org/TR/sparql11-query/#SparqlOps) - * - * @param fnUri - * @param args - * @return - * @throws UnsupportedOperationException in case the function with the given URI is not supported - */ - @Override - public String getFunction(URI fnUri, String... args) { - if(FN.CONCAT.equals(fnUri)) { - return String.format("CONCAT(%s)", StringUtils.join(args, ",")); - } else if(FN.CONTAINS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(%s IN %s) > 0)", args[1], args[0]); - } else if(FN.LOWER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("LOWER(%s)", args[0]); - } else if(FN.UPPER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("UPPER(%s)", args[0]); - } else if(FN.SUBSTRING_AFTER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s IN %1$s) > 0 THEN substring(%1$s, position(%2$s IN %1$s) + CHAR_LENGTH(%2$s)) ELSE '' END)", args[0], args[1]); - } else if(FN.SUBSTRING_BEFORE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s IN %1$s) > 0 THEN substring(%1$s, 1, position(%2$s IN %1$s)-1) ELSE '' END)", args[0], args[1]); - } else if(FN.STRING_LENGTH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CHAR_LENGTH(%s)", args[0]); - } else if(FN.STARTS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(%2$s IN %1$s) = 1)", args[0], args[1]); - } else if(FN.ENDS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(reverse(%2$s) IN reverse(%1$s)) = 1)", args[0], args[1]); - } else if(FN.NUMERIC_ABS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("abs(%s)", args[0]); - } else if(FN.NUMERIC_CEIL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("ceil(%s)", args[0]); - } else if(FN.NUMERIC_FLOOR.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("floor(%s)", args[0]); - } else if(FN.NUMERIC_ROUND.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("round(%s)", args[0]); - } else if(XMLSchema.DOUBLE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS decimal)", args[0]); - } else if(XMLSchema.FLOAT.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS decimal)", args[0]); - } else if(XMLSchema.INTEGER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS signed)", args[0]); - } else if(XMLSchema.DECIMAL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS decimal)", args[0]); - } else if(XMLSchema.DATETIME.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS datetime)", args[0]); - } else if(XMLSchema.BOOLEAN.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("(lower(%s) = 'true' OR %s > 0)", args[0]); - /* - } else if(FN_MARMOTTA.SEARCH_FULLTEXT.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2 || args.length == 3); // no specific language support in MySQL - return String.format("(MATCH (%1$s) AGAINST (%2$s))", args[0], args[1]); - } else if(FN_MARMOTTA.QUERY_FULLTEXT.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2 || args.length == 3); // no specific language support in MySQL - - // basic transformation from postgres to mysql syntax, assuming the argument is a constant query - String query; - if(args[1].startsWith("'")) { - query = args[1].replaceAll("&","+").replaceAll("\\|", " ").replaceAll("!"," -"); - } else { - query = args[1]; - } - - return String.format("(MATCH (%1$s) AGAINST (%2$s IN BOOLEAN MODE))", args[0], query); - */ - } - throw new UnsupportedOperationException("operation "+fnUri+" not supported"); - } - } http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 972c704..bc369d1 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 @@ -17,14 +17,9 @@ */ package org.apache.marmotta.kiwi.persistence.pgsql; -import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; import org.apache.marmotta.kiwi.exception.DriverNotFoundException; import org.apache.marmotta.kiwi.persistence.KiWiDialect; -import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA; -import org.openrdf.model.URI; -import org.openrdf.model.vocabulary.FN; -import org.openrdf.model.vocabulary.XMLSchema; /** * Add file description here! @@ -39,53 +34,6 @@ public class PostgreSQLDialect extends KiWiDialect { } catch (ClassNotFoundException e) { throw new DriverNotFoundException(getDriverClass()); } - - supportedFunctions.put(FN.CONCAT); - supportedFunctions.put(FN.CONTAINS); - supportedFunctions.put(FN.LOWER_CASE); - supportedFunctions.put(FN.UPPER_CASE); - supportedFunctions.put(FN.REPLACE); - supportedFunctions.put(FN.SUBSTRING_AFTER); - supportedFunctions.put(FN.SUBSTRING_BEFORE); - supportedFunctions.put(FN.STRING_LENGTH); - supportedFunctions.put(FN.STARTS_WITH); - supportedFunctions.put(FN.ENDS_WITH); - - supportedFunctions.put(FN.NUMERIC_ABS); - supportedFunctions.put(FN.NUMERIC_CEIL); - supportedFunctions.put(FN.NUMERIC_FLOOR); - supportedFunctions.put(FN.NUMERIC_ROUND); - - supportedFunctions.put(XMLSchema.DOUBLE); - supportedFunctions.put(XMLSchema.FLOAT); - supportedFunctions.put(XMLSchema.INTEGER); - supportedFunctions.put(XMLSchema.DECIMAL); - supportedFunctions.put(XMLSchema.DATETIME); - supportedFunctions.put(XMLSchema.BOOLEAN); - - - supportedFunctions.put(FN_MARMOTTA.SEARCH_FULLTEXT); - supportedFunctions.put(FN_MARMOTTA.QUERY_FULLTEXT); - - supportedFunctions.put(FN_MARMOTTA.NOW); - supportedFunctions.put(FN_MARMOTTA.YEAR); - supportedFunctions.put(FN_MARMOTTA.MONTH); - supportedFunctions.put(FN_MARMOTTA.DAY); - supportedFunctions.put(FN_MARMOTTA.HOURS); - supportedFunctions.put(FN_MARMOTTA.MINUTES); - supportedFunctions.put(FN_MARMOTTA.SECONDS); - - 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); - - supportedFunctions.put(FN_MARMOTTA.STDDEV); - supportedFunctions.put(FN_MARMOTTA.VARIANCE); } /** @@ -175,212 +123,5 @@ public class PostgreSQLDialect extends KiWiDialect { return true; } - /** - * Return an SQL string for evaluating the function with the given URI on the arguments. All arguments are already - * properly substituted SQL expressions (e.g. field names or constants). - * <p/> - * Dialects should at least implement support for all functions defined in the SPARQL specification (http://www.w3.org/TR/sparql11-query/#SparqlOps) - * - * @param fnUri - * @param args - * @return - * @throws UnsupportedOperationException in case the function with the given URI is not supported - */ - @Override - public String getFunction(URI fnUri, String... args) { - if(FN.CONCAT.equals(fnUri)) { - return String.format("(%s)", StringUtils.join(args, "||")); - } else if(FN.CONTAINS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(position(%s in %s) > 0)", args[1], args[0]); - } else if(FN.LOWER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("lower(%s)", args[0]); - } else if(FN.UPPER_CASE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("upper(%s)", args[0]); - } else if(FN.REPLACE.equals(fnUri)) { - if(args.length == 3) { - // no flags - return String.format("regexp_replace(%s, %s, %s, 'g')", args[0], args[1], args[2]); - } else if(args.length == 4) { - // flags - StringBuilder psqlFlags = new StringBuilder(); - if(StringUtils.containsIgnoreCase(args[3],"i")) { - psqlFlags.append("i"); - } - - return String.format("regexp_replace(%s, %s, %s, 'g%s')", args[0], args[1], args[2], psqlFlags.toString()); - } else { - throw new IllegalArgumentException("invalid number of arguments"); - } - } else if(FN.SUBSTRING_AFTER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s in %1$s) > 0 THEN substring(%1$s from position(%2$s in %1$s) + char_length(%2$s) ) ELSE '' END)", args[0], args[1]); - } else if(FN.SUBSTRING_BEFORE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(CASE WHEN position(%2$s in %1$s) > 0 THEN substring(%1$s from 1 for position(%2$s in %1$s)-1) ELSE '' END)", args[0], args[1]); - - } else if(FN.STRING_LENGTH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("char_length(%s)", args[0]); - } else if(FN.STARTS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(%2$s IN %1$s) = 1)", args[0], args[1]); - } else if(FN.ENDS_WITH.equals(fnUri)) { - Preconditions.checkArgument(args.length == 2); - return String.format("(POSITION(reverse(%2$s) IN reverse(%1$s)) = 1)", args[0], args[1]); - } else if(FN.NUMERIC_ABS.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("abs(%s)", args[0]); - } else if(FN.NUMERIC_CEIL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("ceil(%s)", args[0]); - } else if(FN.NUMERIC_FLOOR.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("floor(%s)", args[0]); - } else if(FN.NUMERIC_ROUND.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("round(%s)", args[0]); - } else if(XMLSchema.DOUBLE.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS double precision)", args[0]); - } else if(XMLSchema.FLOAT.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS double precision)", args[0]); - } else if(XMLSchema.INTEGER.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS bigint)", args[0]); - } else if(XMLSchema.DECIMAL.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS decimal)", args[0]); - } else if(XMLSchema.DATETIME.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS timestamp)", args[0]); - } else if(XMLSchema.BOOLEAN.equals(fnUri)) { - Preconditions.checkArgument(args.length == 1); - return String.format("CAST(%s AS boolean)", args[0]); - } else if(FN_MARMOTTA.SEARCH_FULLTEXT.equals(fnUri)) { - if(args.length == 2) { - return String.format("(to_tsvector('simple' :: regconfig,%1$s) @@ plainto_tsquery('simple' :: regconfig,%2$s))", args[0], args[1]); - } else if(args.length == 3) { - return String.format("(to_tsvector(kiwi_ft_lang(%3$s) :: regconfig, %1$s) @@ plainto_tsquery(kiwi_ft_lang(%3$s) :: regconfig, %2$s))", args[0], args[1], args[2]); - } else { - throw new IllegalArgumentException("invalid number of arguments"); - } - } else if(FN_MARMOTTA.QUERY_FULLTEXT.equals(fnUri)) { - if(args.length == 2) { - return String.format("(to_tsvector('simple' :: regconfig,%1$s) @@ to_tsquery('simple' :: regconfig,%2$s))", args[0], args[1]); - } else if(args.length == 3) { - return String.format("(to_tsvector(kiwi_ft_lang(%3$s) :: regconfig, %1$s) @@ to_tsquery(kiwi_ft_lang(%3$s) :: regconfig, %2$s))", args[0], args[1], args[2]); - } 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"); - } - } else if(FN_MARMOTTA.YEAR.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(year from %s)", args[0]); - } else { - throw new IllegalArgumentException("YEAR() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.MONTH.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(month from %s)", args[0]); - } else { - throw new IllegalArgumentException("MONTH() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.DAY.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(day from %s)", args[0]); - } else { - throw new IllegalArgumentException("DAY() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.HOURS.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(hour from %s)", args[0]); - } else { - throw new IllegalArgumentException("HOURS() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.MINUTES.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(minute from %s)", args[0]); - } else { - throw new IllegalArgumentException("MINUTES() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.SECONDS.equals(fnUri)) { - if(args.length == 1) { - return String.format("extract(second from %s)", args[0]); - } else { - throw new IllegalArgumentException("SECONDS() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.STDDEV.equals(fnUri)) { - if(args.length == 1) { - return String.format("stddev(%s)", args[0]); - } else { - throw new IllegalArgumentException("STDDEV() takes exactly 1 argument"); - } - } else if(FN_MARMOTTA.VARIANCE.equals(fnUri)) { - if(args.length == 1) { - return String.format("variance(%s)", args[0]); - } else { - throw new IllegalArgumentException("VARIANCE() takes exactly 1 argument"); - } - } - throw new UnsupportedOperationException("operation "+fnUri+" not supported"); - } - } http://git-wip-us.apache.org/repos/asf/marmotta/blob/5d94ae2e/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 d8fd2da..8a68afb 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 @@ -21,6 +21,7 @@ import org.openrdf.model.URI; import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.NamespaceImpl; import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.model.vocabulary.FN; /** * Add file description here! @@ -83,13 +84,13 @@ public class FN_MARMOTTA { 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"); + YEAR = FN.YEAR_FROM_DATETIME; + MONTH = FN.MONTH_FROM_DATETIME; + DAY = FN.DAY_FROM_DATETIME; + HOURS = FN.HOURS_FROM_DATETIME; + MINUTES = FN.MINUTES_FROM_DATETIME; + SECONDS = FN.SECONDS_FROM_DATETIME; + TIMEZONE = FN.TIMEZONE_FROM_DATETIME; TZ = f.createURI(NAMESPACE,"tz"); MD5 = f.createURI(NAMESPACE,"md5"); SHA1 = f.createURI(NAMESPACE,"sha1");
