-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement built-in function call/xsd:datatype() conversion to xsd:dat…
…eTime/date
- Loading branch information
1 parent
caaf76c
commit 87a1b72
Showing
9 changed files
with
209 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Copyright 2024, University of Freiburg, | ||
// Copyright 2024 - 2025, University of Freiburg, | ||
// Chair of Algorithms and Data Structures | ||
// Author: Hannes Baumann <[email protected]> | ||
|
||
|
@@ -7,7 +7,28 @@ | |
|
||
#include "engine/sparqlExpressions/NaryExpressionImpl.h" | ||
|
||
/* | ||
The SparqlExpressions specified in the following namespace sections enable | ||
xsd:datatype casting/mapping for XML-schema-datatype values. | ||
For more details regarding the casting/mapping definition see: | ||
https://www.w3.org/TR/sparql11-query/#FunctionMapping | ||
EXAMPLES | ||
(1) BIND(xsd:dateTime(?var) as ?dateTimeValue) will try to convert the | ||
date-time provided (bound to ?var) as an xsd:string value to an actual | ||
xsd:dateTime value and bind it to ?dateTimeValue under the condition the | ||
string was appropriately formatted. | ||
(2) BIND(xsd:integer(?var) to ?integerValue) attempts to convert ?var to an | ||
xsd:integer value and bind it to variable ?integerValue, given the datatype | ||
casting can be successfully performed. | ||
*/ | ||
|
||
namespace sparqlExpression { | ||
|
||
//______________________________________________________________________________ | ||
// CONVERT TO NUMERIC | ||
namespace detail::to_numeric { | ||
|
||
// class that converts an input `int64_t`, `double` or `std::string` | ||
|
@@ -16,7 +37,7 @@ CPP_template(typename T, bool AllowExponentialNotation = true)( | |
requires(concepts::same_as<int64_t, T> || | ||
concepts::same_as<double, T>)) class ToNumericImpl { | ||
private: | ||
Id getFromString(const std::string& input) const { | ||
ValueId getFromString(const std::string& input) const { | ||
auto str = absl::StripAsciiWhitespace(input); | ||
// Abseil and the standard library don't match leading + signs, so we skip | ||
// them. | ||
|
@@ -57,7 +78,7 @@ CPP_template(typename T, bool AllowExponentialNotation = true)( | |
}; | ||
|
||
public: | ||
Id operator()(IntDoubleStr value) const { | ||
ValueId operator()(IntDoubleStr value) const { | ||
if (std::holds_alternative<std::string>(value)) { | ||
return getFromString(std::get<std::string>(value)); | ||
} else if (std::holds_alternative<int64_t>(value)) { | ||
|
@@ -77,6 +98,8 @@ using ToDecimal = | |
NARY<1, FV<ToNumericImpl<double, false>, ToNumericValueGetter>>; | ||
} // namespace detail::to_numeric | ||
|
||
//______________________________________________________________________________ | ||
// CONVERT TO BOOLEAN | ||
namespace detail::to_boolean { | ||
class ToBooleanImpl { | ||
public: | ||
|
@@ -103,8 +126,55 @@ class ToBooleanImpl { | |
using ToBoolean = NARY<1, FV<ToBooleanImpl, ToNumericValueGetter>>; | ||
} // namespace detail::to_boolean | ||
|
||
//______________________________________________________________________________ | ||
// CONVERT TO DATE(TIME) | ||
namespace detail::to_datetime { | ||
|
||
// Cast to xsd:dateTime or xsd:date (ValueId) | ||
template <bool ToJustXsdDate> | ||
inline auto convertStringToDateTimeValueId = | ||
[](OptIdOrString input) -> ValueId { | ||
if (!input.has_value()) { | ||
return Id::makeUndefined(); | ||
} | ||
const auto& inputValue = input.value(); | ||
|
||
// Remark: If the parsing procedure for datetime / date string values with | ||
// parseXsdDatetimeGetOptDate / parseXsdDateGetOptDate fails, | ||
// Id::makeUndefined() is returned as well. | ||
const auto retrieveValueId = [](std::optional<DateYearOrDuration> optValue) { | ||
if (optValue.has_value()) { | ||
return Id::makeFromDate(optValue.value()); | ||
} | ||
return Id::makeUndefined(); | ||
}; | ||
|
||
if (auto* valueId = std::get_if<ValueId>(&inputValue)) { | ||
return valueId->getDate().isDate() ? *valueId : Id::makeUndefined(); | ||
} | ||
|
||
auto* str = std::get_if<std::string>(&inputValue); | ||
AD_CORRECTNESS_CHECK(str != nullptr); | ||
if constexpr (ToJustXsdDate) { | ||
return retrieveValueId(DateYearOrDuration::parseXsdDateGetOptDate(*str)); | ||
} else { | ||
return retrieveValueId( | ||
DateYearOrDuration::parseXsdDatetimeGetOptDate(*str)); | ||
} | ||
}; | ||
|
||
NARY_EXPRESSION(ToXsdDateTime, 1, | ||
FV<decltype(convertStringToDateTimeValueId<false>), | ||
DateIdOrLiteralValueGetter>); | ||
NARY_EXPRESSION(ToXsdDate, 1, | ||
FV<decltype(convertStringToDateTimeValueId<true>), | ||
DateIdOrLiteralValueGetter>); | ||
|
||
} // namespace detail::to_datetime | ||
|
||
using namespace detail::to_numeric; | ||
using namespace detail::to_boolean; | ||
using namespace detail::to_datetime; | ||
using Expr = SparqlExpression::Ptr; | ||
|
||
Expr makeConvertToIntExpression(Expr child) { | ||
|
@@ -122,4 +192,13 @@ Expr makeConvertToDecimalExpression(Expr child) { | |
Expr makeConvertToBooleanExpression(Expr child) { | ||
return std::make_unique<ToBoolean>(std::move(child)); | ||
} | ||
|
||
Expr makeConvertToDateTimeExpression(Expr child) { | ||
return std::make_unique<ToXsdDateTime>(std::move(child)); | ||
} | ||
|
||
Expr makeConvertToDateExpression(Expr child) { | ||
return std::make_unique<ToXsdDate>(std::move(child)); | ||
} | ||
|
||
} // namespace sparqlExpression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters