Skip to content

Commit

Permalink
Merge pull request #705 from ontop/feature/new-datetime-functions
Browse files Browse the repository at this point in the history
Added new DateTime functions
  • Loading branch information
bcogrel committed Jul 13, 2023
2 parents dba93d4 + 37a1e36 commit cc3747b
Show file tree
Hide file tree
Showing 44 changed files with 1,260 additions and 17 deletions.
Expand Up @@ -646,4 +646,17 @@ ImmutableFunctionalTerm getBinaryLatelyTypedFunctionalTerm(
ImmutableExpression getDBJsonIsNumber(DBTermType dbType, ImmutableTerm arg);
ImmutableExpression getDBJsonIsScalar(DBTermType dbType, ImmutableTerm arg);
ImmutableExpression getDBIsArray(DBTermType dbType, ImmutableTerm arg);


// Ontop-defined functions

ImmutableFunctionalTerm getDBWeek(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBQuarter(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBDecade(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBCentury(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBMillennium(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBMilliseconds(ImmutableTerm dbDatetimeTerm);
ImmutableFunctionalTerm getDBMicroseconds(ImmutableTerm dbDatetimeTerm);

ImmutableFunctionalTerm getDBDateTrunc(ImmutableTerm dbDatetimeTerm, ImmutableTerm datePartTerm, String datePart);
}
Expand Up @@ -5,7 +5,6 @@
import it.unibz.inf.ontop.model.term.functionsymbol.FunctionSymbol;
import it.unibz.inf.ontop.model.term.functionsymbol.InequalityLabel;
import it.unibz.inf.ontop.model.type.DBTermType;
import it.unibz.inf.ontop.model.type.GenericDBTermType;
import it.unibz.inf.ontop.model.type.RDFTermType;
import org.apache.commons.rdf.api.IRI;

Expand Down Expand Up @@ -394,4 +393,14 @@ public interface DBFunctionSymbolFactory {
DBFunctionSymbol checkAndConvertDateFromDatetime();
DBFunctionSymbol checkAndConvertDateFromString();


DBFunctionSymbol getDBWeek();
DBFunctionSymbol getDBQuarter();
DBFunctionSymbol getDBDecade();
DBFunctionSymbol getDBCentury();
DBFunctionSymbol getDBMillennium();
DBFunctionSymbol getDBMilliseconds();
DBFunctionSymbol getDBMicroseconds();

DBFunctionSymbol getDBDateTrunc(String datePart);
}
Expand Up @@ -85,6 +85,23 @@ public abstract class AbstractDBFunctionSymbolFactory implements DBFunctionSymbo
private DBFunctionSymbol minutesFunctionSymbol;
// Created in init()
private DBFunctionSymbol secondsFunctionSymbol;
//Created in init
private DBFunctionSymbol weekFunctionSymbol;
//Created in init
private DBFunctionSymbol quarterFunctionSymbol;
//Created in init
private DBFunctionSymbol decadeFunctionSymbol;
//Created in init
private DBFunctionSymbol centuryFunctionSymbol;
//Created in init
private DBFunctionSymbol millenniumFunctionSymbol;
//Created in init
private DBFunctionSymbol millisecondsFunctionSymbol;
//Created in init
private DBFunctionSymbol microsecondsFunctionSymbol;
//Created in init
private DBFunctionSymbol dateTruncFunctionSymbol;
//Created in init
// Created in init()
private DBFunctionSymbol tzFunctionSymbol;

Expand Down Expand Up @@ -433,6 +450,14 @@ protected void init() {
hoursFunctionSymbol = createHoursFunctionSymbol();
minutesFunctionSymbol = createMinutesFunctionSymbol();
secondsFunctionSymbol = createSecondsFunctionSymbol();
weekFunctionSymbol = createWeekFunctionSymbol();
quarterFunctionSymbol = createQuarterFunctionSymbol();
decadeFunctionSymbol = createDecadeFunctionSymbol();
centuryFunctionSymbol = createCenturyFunctionSymbol();
millenniumFunctionSymbol = createMillenniumFunctionSymbol();
millisecondsFunctionSymbol = createMillisecondsFunctionSymbol();
microsecondsFunctionSymbol = createMicrosecondsFunctionSymbol();
dateTruncFunctionSymbol = createDateTruncFunctionSymbol();
tzFunctionSymbol = createTzFunctionSymbol();

weeksBetweenFromDateTimeFunctionSymbol = createWeeksBetweenFromDateTimeFunctionSymbol();
Expand Down Expand Up @@ -995,6 +1020,46 @@ public DBFunctionSymbol getDBHours() {
return hoursFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBWeek() {
return weekFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBQuarter() {
return quarterFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBCentury() {
return centuryFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBDecade() {
return decadeFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBMillennium() {
return millenniumFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBMilliseconds() {
return millisecondsFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBMicroseconds() {
return microsecondsFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBDateTrunc(String datePart) {
return dateTruncFunctionSymbol;
}

@Override
public DBFunctionSymbol getDBMinutes() {
return minutesFunctionSymbol;
Expand Down Expand Up @@ -1414,6 +1479,51 @@ protected DBFunctionSymbol createMinutesFunctionSymbol() {
this::serializeMinutes);
}

protected DBFunctionSymbol createWeekFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_WEEK", rootDBType, dbIntegerType, false,
this::serializeWeek);
}

protected DBFunctionSymbol createQuarterFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_QUARTER", rootDBType, dbIntegerType, false,
this::serializeQuarter);
}

protected DBFunctionSymbol createDecadeFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_DECADE", rootDBType, dbIntegerType, false,
this::serializeDecade);
}

protected DBFunctionSymbol createCenturyFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_CENTURY", rootDBType, dbIntegerType, false,
this::serializeCentury);
}

protected DBFunctionSymbol createMillenniumFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_MILLENNIUM", rootDBType, dbIntegerType, false,
this::serializeMillennium);
}

protected DBFunctionSymbol createMillisecondsFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_MILLISECONDS", rootDBType, dbDecimalType, false,
this::serializeMilliseconds);
}

protected DBFunctionSymbol createMicrosecondsFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_MICROSECONDS", rootDBType, dbIntegerType, false,
this::serializeMicroseconds);
}

protected DBFunctionSymbol createDateTruncFunctionSymbol() {
return new DBFunctionSymbolWithSerializerImpl("DB_DATE_TRUNC", ImmutableList.of(dbStringType, dbDateType), dbDateType, false,
this::serializeDateTrunc) {
@Override
protected boolean mayReturnNullWithoutNullArguments() {
return false;
}
};
}

protected DBFunctionSymbol createSecondsFunctionSymbol() {
return new UnaryDBFunctionSymbolWithSerializerImpl("DB_SECONDS", rootDBType, dbDecimalType, false,
this::serializeSeconds);
Expand Down Expand Up @@ -1593,6 +1703,38 @@ protected abstract String serializeSeconds(ImmutableList<? extends ImmutableTerm
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeWeek(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeQuarter(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeDecade(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeCentury(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeMillennium(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeMilliseconds(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeMicroseconds(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeDateTrunc(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);

protected abstract String serializeTz(ImmutableList<? extends ImmutableTerm> terms,
Function<ImmutableTerm, String> termConverter,
TermFactory termFactory);
Expand Down
Expand Up @@ -8,9 +8,9 @@

import java.util.function.Function;

public class SQLServerDBIsTrueFunctionSymbolImpl extends DefaultDBIsTrueFunctionSymbol {
public class EqualsTrueDBIsTrueFunctionSymbolImpl extends DefaultDBIsTrueFunctionSymbol {

protected SQLServerDBIsTrueFunctionSymbolImpl(DBTermType dbBooleanTermType) {
protected EqualsTrueDBIsTrueFunctionSymbolImpl(DBTermType dbBooleanTermType) {
super(dbBooleanTermType);
}

Expand Down
Expand Up @@ -390,6 +390,46 @@ protected String serializeSeconds(ImmutableList<? extends ImmutableTerm> terms,
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeWeek(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeQuarter(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeDecade(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeCentury(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeMillennium(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeMilliseconds(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeMicroseconds(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeDateTrunc(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}

@Override
protected String serializeTz(ImmutableList<? extends ImmutableTerm> terms, Function<ImmutableTerm, String> termConverter, TermFactory termFactory) {
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
Expand Down Expand Up @@ -913,4 +953,6 @@ protected String serializeCheckAndConvertDateFromString(ImmutableList<? extends
throw new UnsupportedOperationException("Operation not supported by the MockupDBFunctionSymbolFactory");
}



}
@@ -0,0 +1,101 @@
package it.unibz.inf.ontop.model.term.functionsymbol.impl;

import com.google.common.collect.ImmutableList;
import it.unibz.inf.ontop.iq.node.VariableNullability;
import it.unibz.inf.ontop.model.term.*;
import it.unibz.inf.ontop.model.term.functionsymbol.RDFTermFunctionSymbol;
import it.unibz.inf.ontop.model.term.functionsymbol.db.DBFunctionSymbol;
import it.unibz.inf.ontop.model.term.functionsymbol.impl.ofn.OfnMultitypedInputBinarySPARQLFunctionSymbolImpl;
import it.unibz.inf.ontop.model.term.impl.RDFTermTypeConstantImpl;
import it.unibz.inf.ontop.model.type.DBTermType;
import it.unibz.inf.ontop.model.type.DBTypeFactory;
import it.unibz.inf.ontop.model.type.RDFTermType;
import it.unibz.inf.ontop.model.type.TermTypeInference;
import it.unibz.inf.ontop.model.vocabulary.Ontop;
import org.apache.commons.rdf.api.IRI;

import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;

public class DateTruncSPARQLFunctionSymbolImpl extends ReduciblePositiveAritySPARQLFunctionSymbolImpl {

private final static String[] supportedDateParts = new String[] {
"microsecond",
"millisecond",
"microseconds",
"milliseconds",
"second",
"minute",
"hour",
"day",
"week",
"month",
"quarter",
"year",
"decade",
"century",
"millennium"
};

private final Function<String, DBFunctionSymbol> dbFunctionSymbolFunction;
private final RDFTermType targetType;


public DateTruncSPARQLFunctionSymbolImpl(@Nonnull RDFTermType inputDateType,
@Nonnull RDFTermType inputSecondType,
@Nonnull Function<String, DBFunctionSymbol> dbFunctionSymbolFunction) {
super("SP_DATE_TRUNC", Ontop.DATE_TRUNC, ImmutableList.of(inputDateType, inputSecondType));
this.targetType = inputDateType;
this.dbFunctionSymbolFunction = dbFunctionSymbolFunction;
}

@Override
protected ImmutableTerm computeLexicalTerm(ImmutableList<ImmutableTerm> subLexicalTerms,
ImmutableList<ImmutableTerm> typeTerms, TermFactory termFactory,
ImmutableTerm returnedTypeTerm) {
if(!(subLexicalTerms.get(1) instanceof Constant)) {
//TODO - create more specialized exception to throw here.
throw new RuntimeException("Only constants are supported as Date-Part parameter.");
}
var constant = (Constant)subLexicalTerms.get(1);
var value = constant.getValue();
if(!Arrays.stream(supportedDateParts)
.anyMatch(part -> part.equalsIgnoreCase(value))) {
//TODO - create more specialized exception to throw here.
throw new RuntimeException(String.format("Date-Part %s is not supported.", value));
}

return termFactory.getConversion2RDFLexical(
termFactory.getImmutableFunctionalTerm(
dbFunctionSymbolFunction.apply(value),
termFactory.getConversionFromRDFLexical2DB(targetType.getClosestDBType(termFactory.getTypeFactory().getDBTypeFactory()), subLexicalTerms.get(0), targetType),
subLexicalTerms.get(1)
), targetType);
}

@Override
protected ImmutableTerm computeTypeTerm(ImmutableList<? extends ImmutableTerm> subLexicalTerms,
ImmutableList<ImmutableTerm> typeTerms, TermFactory termFactory,
VariableNullability variableNullability) {
return termFactory.getRDFTermTypeConstant(targetType);
}

@Override
public boolean isAlwaysInjectiveInTheAbsenceOfNonInjectiveFunctionalTerms() {
return false;
}

@Override
public Optional<TermTypeInference> inferType(ImmutableList<? extends ImmutableTerm> terms) {
return Optional.of(TermTypeInference.declareTermType(targetType));
}

@Override
public boolean canBePostProcessed(ImmutableList<? extends ImmutableTerm> arguments) {
return false;
}
}

0 comments on commit cc3747b

Please sign in to comment.