diff options
author | vvvv <[email protected]> | 2025-10-06 13:26:25 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2025-10-06 14:06:25 +0300 |
commit | eca8ce9cb1613d5c983185c4e43c20651a9638aa (patch) | |
tree | 61ee5ae779948e61af9a7691d19eaa2c09869121 /yql/essentials/udfs/common/datetime2/datetime_udf.cpp | |
parent | 4adf7eecae16a9b228b28cc5f64c27ef69ad5ec2 (diff) |
YQL-20086 udfs
init
commit_hash:f9684778bf1ea956965f2360b80b91edb7d4ffbe
Diffstat (limited to 'yql/essentials/udfs/common/datetime2/datetime_udf.cpp')
-rw-r--r-- | yql/essentials/udfs/common/datetime2/datetime_udf.cpp | 3068 |
1 files changed, 1521 insertions, 1547 deletions
diff --git a/yql/essentials/udfs/common/datetime2/datetime_udf.cpp b/yql/essentials/udfs/common/datetime2/datetime_udf.cpp index acc42ad2cbe..f6ae912cb79 100644 --- a/yql/essentials/udfs/common/datetime2/datetime_udf.cpp +++ b/yql/essentials/udfs/common/datetime2/datetime_udf.cpp @@ -61,25 +61,25 @@ extern const char TM64ResourceName[] = "DateTime2.TM64"; namespace { -template<typename Type> +template <typename Type> static void PrintTypeAlternatives(NUdf::IFunctionTypeInfoBuilder& builder, - ITypeInfoHelper::TPtr typeInfoHelper, TStringBuilder& strBuilder) + ITypeInfoHelper::TPtr typeInfoHelper, TStringBuilder& strBuilder) { TTypePrinter(*typeInfoHelper, builder.SimpleType<Type>()).Out(strBuilder.Out); } -template<typename Type, typename Head, typename... Tail> +template <typename Type, typename Head, typename... Tail> static void PrintTypeAlternatives(NUdf::IFunctionTypeInfoBuilder& builder, - ITypeInfoHelper::TPtr typeInfoHelper, TStringBuilder& strBuilder) + ITypeInfoHelper::TPtr typeInfoHelper, TStringBuilder& strBuilder) { PrintTypeAlternatives<Type>(builder, typeInfoHelper, strBuilder); strBuilder << " or "; PrintTypeAlternatives<Head, Tail...>(builder, typeInfoHelper, strBuilder); } -template<typename... Types> +template <typename... Types> static void SetInvalidTypeError(NUdf::IFunctionTypeInfoBuilder& builder, - ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) + ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) { ::TStringBuilder sb; sb << "Invalid argument type: got "; @@ -91,26 +91,25 @@ static void SetInvalidTypeError(NUdf::IFunctionTypeInfoBuilder& builder, } static void SetResourceExpectedError(NUdf::IFunctionTypeInfoBuilder& builder, - ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) + ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) { SetInvalidTypeError< TResource<TMResourceName>, - TResource<TM64ResourceName> - >(builder, typeInfoHelper, argType); + TResource<TM64ResourceName>>(builder, typeInfoHelper, argType); } static void SetIntervalExpectedError(NUdf::IFunctionTypeInfoBuilder& builder, - ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) + ITypeInfoHelper::TPtr typeInfoHelper, const TType* argType) { SetInvalidTypeError<TInterval, TInterval64>(builder, typeInfoHelper, argType); } -template<const char* TResourceName> +template <const char* TResourceName> static void PrintTagAlternatives(TStringBuilder& strBuilder) { strBuilder << "'" << TResourceName << "'"; } -template<const char* TResourceName, const char* Head, const char*... Tail> +template <const char* TResourceName, const char* Head, const char*... Tail> static void PrintTagAlternatives(TStringBuilder& strBuilder) { PrintTagAlternatives<TResourceName>(strBuilder); strBuilder << " or "; @@ -118,7 +117,7 @@ static void PrintTagAlternatives(TStringBuilder& strBuilder) { } static void SetUnexpectedTagError(NUdf::IFunctionTypeInfoBuilder& builder, - TStringRef tag) + TStringRef tag) { ::TStringBuilder sb; sb << "Unexpected Resource tag: got '" << tag << "', but "; @@ -153,20 +152,20 @@ public: return value * i64(86400) * TWResult(ScaleAfterSeconds); } - template<typename TTzDate> + template <typename TTzDate> static TResult TzBlockCore(TBlockItem tzDate); - template<> + template <> static TResult TzBlockCore<TTzDate>(TBlockItem tzDate) { return DateCore(tzDate.Get<ui16>()); } - template<> + template <> static TResult TzBlockCore<TTzDatetime>(TBlockItem tzDate) { return DatetimeCore(tzDate.Get<ui32>()); } - template<> + template <> static TResult TzBlockCore<TTzTimestamp>(TBlockItem tzDate) { return TimestampCore(tzDate.Get<ui64>()); } @@ -200,7 +199,7 @@ public: return name; } - template<typename TTzDate, typename TOutput> + template <typename TTzDate, typename TOutput> static auto MakeTzBlockExec() { using TReader = TTzDateBlockReader<TTzDate, /*Nullable*/ false>; return UnaryPreallocatedReaderExecImpl<TReader, TOutput, TzBlockCore<TTzDate>>; @@ -253,7 +252,6 @@ public: isOptional = true; } - TDataTypeInspector data(*typeInfoHelper, argType); if (!data) { builder.SetError("Data type expected"); @@ -301,11 +299,11 @@ public: if (typeId == TDataType<TDate>::Id || typeId == TDataType<TTzDate>::Id) { if (block) { const auto exec = (typeId == TDataType<TTzDate>::Id) - ? MakeTzBlockExec<TTzDate, TResult>() - : UnaryPreallocatedExecImpl<ui16, TResult, DateCore>; + ? MakeTzBlockExec<TTzDate, TResult>() + : UnaryPreallocatedExecImpl<ui16, TResult, DateCore>; builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui16, TResult, DateCore>()); } @@ -315,11 +313,11 @@ public: if (typeId == TDataType<TDatetime>::Id || typeId == TDataType<TTzDatetime>::Id) { if (block) { const auto exec = (typeId == TDataType<TTzDatetime>::Id) - ? MakeTzBlockExec<TTzDatetime, TResult>() - : UnaryPreallocatedExecImpl<ui32, TResult, DatetimeCore>; + ? MakeTzBlockExec<TTzDatetime, TResult>() + : UnaryPreallocatedExecImpl<ui32, TResult, DatetimeCore>; builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui32, TResult, DatetimeCore>()); } @@ -329,11 +327,11 @@ public: if (typeId == TDataType<TTimestamp>::Id || typeId == TDataType<TTzTimestamp>::Id) { if (block) { const auto exec = (typeId == TDataType<TTzTimestamp>::Id) - ? MakeTzBlockExec<TTzTimestamp, TResult>() - : UnaryPreallocatedExecImpl<ui64, TResult, TimestampCore>; + ? MakeTzBlockExec<TTzTimestamp, TResult>() + : UnaryPreallocatedExecImpl<ui64, TResult, TimestampCore>; builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui64, TResult, TimestampCore>()); } @@ -343,7 +341,7 @@ public: if (typeId == TDataType<TInterval>::Id) { if (block) { builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - UnaryPreallocatedExecImpl<i64, TSignedResult, IntervalCore>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + UnaryPreallocatedExecImpl<i64, TSignedResult, IntervalCore>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<i64, TSignedResult, IntervalCore>()); } @@ -485,7 +483,7 @@ struct TGetTimeComponent { if (typeId == TDataType<TDate>::Id) { if (block) { builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - UnaryPreallocatedExecImpl<ui16, TFieldStorage, Core<ui16, true, false>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + UnaryPreallocatedExecImpl<ui16, TFieldStorage, Core<ui16, true, false>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui16, TFieldStorage, Core<ui16, true, false>>()); } @@ -494,7 +492,7 @@ struct TGetTimeComponent { if (typeId == TDataType<TDatetime>::Id) { if (block) { builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - UnaryPreallocatedExecImpl<ui32, TFieldStorage, Core<ui32, false, false>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + UnaryPreallocatedExecImpl<ui32, TFieldStorage, Core<ui32, false, false>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui32, TFieldStorage, Core<ui32, false, false>>()); } @@ -503,7 +501,7 @@ struct TGetTimeComponent { if (typeId == TDataType<TTimestamp>::Id) { if (block) { builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(), - UnaryPreallocatedExecImpl<ui64, TFieldStorage, Core<ui64, false, true>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); + UnaryPreallocatedExecImpl<ui64, TFieldStorage, Core<ui64, false, true>>, builder, TString(name), arrow::compute::NullHandling::INTERSECTION)); } else { builder.Implementation(new TUnaryOverOptionalImpl<ui64, TFieldStorage, Core<ui64, false, true>>()); } @@ -531,6 +529,7 @@ struct TGetTimeComponent { SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: template <typename TInput, bool AlwaysZero, bool InputFractional> static TFieldStorage Core(TInput val) { @@ -553,8 +552,8 @@ private: } } - template<typename TResult, TResult (*Func)(const TUnboxedValuePod&)> - class TImpl : public TBoxedValue { + template <typename TResult, TResult (*Func)(const TUnboxedValuePod&)> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { Y_UNUSED(valueBuilder); @@ -563,7 +562,7 @@ private: } }; - template<typename TResult, const char* TResourceName, TResult (*Func)(const TUnboxedValuePod&)> + template <typename TResult, const char* TResourceName, TResult (*Func)(const TUnboxedValuePod&)> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TResult>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>(); @@ -576,21 +575,21 @@ private: namespace { -template<const char* TResourceName, typename TValue, - typename TStorage = std::conditional_t<TResourceName == TMResourceName, - TTMStorage, TTM64Storage>> +template <const char* TResourceName, typename TValue, + typename TStorage = std::conditional_t<TResourceName == TMResourceName, + TTMStorage, TTM64Storage>> const TStorage& Reference(const TValue& value) { return *reinterpret_cast<const TStorage*>(value.GetRawPtr()); } -template<const char* TResourceName, typename TValue, - typename TStorage = std::conditional_t<TResourceName == TMResourceName, - TTMStorage, TTM64Storage>> +template <const char* TResourceName, typename TValue, + typename TStorage = std::conditional_t<TResourceName == TMResourceName, + TTMStorage, TTM64Storage>> TStorage& Reference(TValue& value) { return *reinterpret_cast<TStorage*>(value.GetRawPtr()); } -template<const char* TResourceName> +template <const char* TResourceName> TUnboxedValuePod DoAddMonths(const TUnboxedValuePod& date, i64 months, const NUdf::IDateBuilder& builder) { auto result = date; auto& storage = Reference<TResourceName>(result); @@ -600,12 +599,12 @@ TUnboxedValuePod DoAddMonths(const TUnboxedValuePod& date, i64 months, const NUd return result; } -template<const char* TResourceName> +template <const char* TResourceName> TUnboxedValuePod DoAddQuarters(const TUnboxedValuePod& date, i64 quarters, const NUdf::IDateBuilder& builder) { return DoAddMonths<TResourceName>(date, quarters * 3ll, builder); } -template<const char* TResourceName> +template <const char* TResourceName> TUnboxedValuePod DoAddYears(const TUnboxedValuePod& date, i64 years, const NUdf::IDateBuilder& builder) { auto result = date; auto& storage = Reference<TResourceName>(result); @@ -615,681 +614,671 @@ TUnboxedValuePod DoAddYears(const TUnboxedValuePod& date, i64 years, const NUdf: return result; } -#define ACCESSORS_POLY(field, type, wtype) \ - template<const char* TResourceName, typename TValue, typename TRetType \ - = std::conditional_t<TResourceName == TMResourceName, type, wtype>> \ - inline TRetType Get##field(const TValue& tm) { \ - return (TRetType)Reference<TResourceName>(tm).field; \ - } \ - template<const char* TResourceName, typename TValue, typename TArgType \ - = std::conditional_t<TResourceName == TMResourceName, type, wtype>> \ - inline void Set##field(TValue& tm, TArgType value) { \ - Reference<TResourceName>(tm).field = value; \ - } \ +#define ACCESSORS_POLY(field, type, wtype) \ + template <const char* TResourceName, typename TValue, typename TRetType = std::conditional_t<TResourceName == TMResourceName, type, wtype>> \ + inline TRetType Get##field(const TValue& tm) { \ + return (TRetType)Reference<TResourceName>(tm).field; \ + } \ + template <const char* TResourceName, typename TValue, typename TArgType = std::conditional_t<TResourceName == TMResourceName, type, wtype>> \ + inline void Set##field(TValue& tm, TArgType value) { \ + Reference<TResourceName>(tm).field = value; \ + } #define ACCESSORS(field, type) \ ACCESSORS_POLY(field, type, type) - ACCESSORS_POLY(Year, ui16, i32) - ACCESSORS(DayOfYear, ui16) - ACCESSORS(WeekOfYear, ui8) - ACCESSORS(WeekOfYearIso8601, ui8) - ACCESSORS(DayOfWeek, ui8) - ACCESSORS(Month, ui8) - ACCESSORS(Day, ui8) - ACCESSORS(Hour, ui8) - ACCESSORS(Minute, ui8) - ACCESSORS(Second, ui8) - ACCESSORS(Microsecond, ui32) - ACCESSORS(TimezoneId, ui16) +ACCESSORS_POLY(Year, ui16, i32) +ACCESSORS(DayOfYear, ui16) +ACCESSORS(WeekOfYear, ui8) +ACCESSORS(WeekOfYearIso8601, ui8) +ACCESSORS(DayOfWeek, ui8) +ACCESSORS(Month, ui8) +ACCESSORS(Day, ui8) +ACCESSORS(Hour, ui8) +ACCESSORS(Minute, ui8) +ACCESSORS(Second, ui8) +ACCESSORS(Microsecond, ui32) +ACCESSORS(TimezoneId, ui16) #undef ACCESSORS #undef ACCESSORS_POLY - template<const char* TResourceName> - inline bool ValidateYear(std::conditional_t<TResourceName == TMResourceName, ui16, i32> year) { - if constexpr (TResourceName == TMResourceName) { - return year >= NUdf::MIN_YEAR || year < NUdf::MAX_YEAR; - } else { - return year >= NUdf::MIN_YEAR32 || year < NUdf::MAX_YEAR32; - } +template <const char* TResourceName> +inline bool ValidateYear(std::conditional_t<TResourceName == TMResourceName, ui16, i32> year) { + if constexpr (TResourceName == TMResourceName) { + return year >= NUdf::MIN_YEAR || year < NUdf::MAX_YEAR; + } else { + return year >= NUdf::MIN_YEAR32 || year < NUdf::MAX_YEAR32; } +} - inline bool ValidateMonth(ui8 month) { - return month >= 1 && month <= 12; - } +inline bool ValidateMonth(ui8 month) { + return month >= 1 && month <= 12; +} - inline bool ValidateDay(ui8 day) { - return day >= 1 && day <= 31; - } +inline bool ValidateDay(ui8 day) { + return day >= 1 && day <= 31; +} - inline bool ValidateHour(ui8 hour) { - return hour < 24; - } +inline bool ValidateHour(ui8 hour) { + return hour < 24; +} - inline bool ValidateMinute(ui8 minute) { - return minute < 60; - } +inline bool ValidateMinute(ui8 minute) { + return minute < 60; +} - inline bool ValidateSecond(ui8 second) { - return second < 60; - } +inline bool ValidateSecond(ui8 second) { + return second < 60; +} - inline bool ValidateMicrosecond(ui32 microsecond) { - return microsecond < 1000000; - } +inline bool ValidateMicrosecond(ui32 microsecond) { + return microsecond < 1000000; +} - inline bool ValidateTimezoneId(ui16 timezoneId) { - const auto& zones = NTi::GetTimezones(); - return timezoneId < zones.size() && !zones[timezoneId].empty(); - } +inline bool ValidateTimezoneId(ui16 timezoneId) { + const auto& zones = NTi::GetTimezones(); + return timezoneId < zones.size() && !zones[timezoneId].empty(); +} - inline bool ValidateMonthShortName(const std::string_view& monthName, ui8& month) { - static constexpr auto cmp = [](const std::string_view& a, const std::string_view& b) { - int cmp = strnicmp(a.data(), b.data(), std::min(a.size(), b.size())); - if (cmp == 0) - return a.size() < b.size(); - return cmp < 0; - }; - static const std::map<std::string_view, ui8, decltype(cmp)> mp = { - {"jan", 1}, - {"feb", 2}, - {"mar", 3}, - {"apr", 4}, - {"may", 5}, - {"jun", 6}, - {"jul", 7}, - {"aug", 8}, - {"sep", 9}, - {"oct", 10}, - {"nov", 11}, - {"dec", 12} - }; - const auto& it = mp.find(monthName); - if (it != mp.end()) { - month = it -> second; - return true; +inline bool ValidateMonthShortName(const std::string_view& monthName, ui8& month) { + static constexpr auto cmp = [](const std::string_view& a, const std::string_view& b) { + int cmp = strnicmp(a.data(), b.data(), std::min(a.size(), b.size())); + if (cmp == 0) { + return a.size() < b.size(); } - return false; - } - - inline bool ValidateMonthFullName(const std::string_view& monthName, ui8& month) { - static constexpr auto cmp = [](const std::string_view& a, const std::string_view& b) { - int cmp = strnicmp(a.data(), b.data(), std::min(a.size(), b.size())); - if (cmp == 0) - return a.size() < b.size(); - return cmp < 0; - }; - static const std::map<std::string_view, ui8, decltype(cmp)> mp = { - {"january", 1}, - {"february", 2}, - {"march", 3}, - {"april", 4}, - {"may", 5}, - {"june", 6}, - {"july", 7}, - {"august", 8}, - {"september", 9}, - {"october", 10}, - {"november", 11}, - {"december", 12} - }; - const auto& it = mp.find(monthName); - if (it != mp.end()) { - month = it -> second; - return true; + return cmp < 0; + }; + static const std::map<std::string_view, ui8, decltype(cmp)> mp = { + {"jan", 1}, + {"feb", 2}, + {"mar", 3}, + {"apr", 4}, + {"may", 5}, + {"jun", 6}, + {"jul", 7}, + {"aug", 8}, + {"sep", 9}, + {"oct", 10}, + {"nov", 11}, + {"dec", 12}}; + const auto& it = mp.find(monthName); + if (it != mp.end()) { + month = it->second; + return true; + } + return false; +} + +inline bool ValidateMonthFullName(const std::string_view& monthName, ui8& month) { + static constexpr auto cmp = [](const std::string_view& a, const std::string_view& b) { + int cmp = strnicmp(a.data(), b.data(), std::min(a.size(), b.size())); + if (cmp == 0) { + return a.size() < b.size(); } - return false; + return cmp < 0; + }; + static const std::map<std::string_view, ui8, decltype(cmp)> mp = { + {"january", 1}, + {"february", 2}, + {"march", 3}, + {"april", 4}, + {"may", 5}, + {"june", 6}, + {"july", 7}, + {"august", 8}, + {"september", 9}, + {"october", 10}, + {"november", 11}, + {"december", 12}}; + const auto& it = mp.find(monthName); + if (it != mp.end()) { + month = it->second; + return true; } + return false; +} - template<typename TType> - inline bool Validate(typename TDataType<TType>::TLayout arg); +template <typename TType> +inline bool Validate(typename TDataType<TType>::TLayout arg); - template<> - inline bool Validate<TTimestamp>(ui64 timestamp) { - return timestamp < MAX_TIMESTAMP; - } +template <> +inline bool Validate<TTimestamp>(ui64 timestamp) { + return timestamp < MAX_TIMESTAMP; +} - template<> - inline bool Validate<TTimestamp64>(i64 timestamp) { - return timestamp >= MIN_TIMESTAMP64 && timestamp <= MAX_TIMESTAMP64; - } +template <> +inline bool Validate<TTimestamp64>(i64 timestamp) { + return timestamp >= MIN_TIMESTAMP64 && timestamp <= MAX_TIMESTAMP64; +} - template<> - inline bool Validate<TInterval>(i64 interval) { - return interval > -i64(MAX_TIMESTAMP) && interval < i64(MAX_TIMESTAMP); - } +template <> +inline bool Validate<TInterval>(i64 interval) { + return interval > -i64(MAX_TIMESTAMP) && interval < i64(MAX_TIMESTAMP); +} - template<> - inline bool Validate<TInterval64>(i64 interval) { - return interval >= -MAX_INTERVAL64 && interval <= MAX_INTERVAL64; - } +template <> +inline bool Validate<TInterval64>(i64 interval) { + return interval >= -MAX_INTERVAL64 && interval <= MAX_INTERVAL64; +} - // Split +// Split - template<typename TUserDataType, bool Nullable> - using TSplitArgReader = std::conditional_t<TTzDataType<TUserDataType>::Result, - TTzDateBlockReader<TUserDataType, Nullable>, - TFixedSizeBlockReader<typename TDataType<TUserDataType>::TLayout, Nullable>>; +template <typename TUserDataType, bool Nullable> +using TSplitArgReader = std::conditional_t<TTzDataType<TUserDataType>::Result, + TTzDateBlockReader<TUserDataType, Nullable>, + TFixedSizeBlockReader<typename TDataType<TUserDataType>::TLayout, Nullable>>; - template<typename TUserDataType> - struct TSplitKernelExec : TUnaryKernelExec<TSplitKernelExec<TUserDataType>, TSplitArgReader<TUserDataType, false>, TResourceArrayBuilder<false>> { - static void Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& valueBuilder); +template <typename TUserDataType> +struct TSplitKernelExec: TUnaryKernelExec<TSplitKernelExec<TUserDataType>, TSplitArgReader<TUserDataType, false>, TResourceArrayBuilder<false>> { + static void Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& valueBuilder); - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem arg, const TSink& sink) { - try { - TBlockItem res {0}; - Split(arg, Reference<TMResourceName>(res), *valueBuilder); - sink(res); - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << e.what()).c_str()); - } + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem arg, const TSink& sink) { + try { + TBlockItem res{0}; + Split(arg, Reference<TMResourceName>(res), *valueBuilder); + sink(res); + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << e.what()).c_str()); } - }; + } +}; - template <typename TUserDataType> - class TSplit : public TBoxedValue { - const TSourcePosition Pos_; +template <typename TUserDataType> +class TSplit: public TBoxedValue { + const TSourcePosition Pos_; - public: - explicit TSplit(TSourcePosition pos) - : Pos_(pos) - {} +public: + explicit TSplit(TSourcePosition pos) + : Pos_(pos) + { + } - TUnboxedValue Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override; + TUnboxedValue Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override; - static bool DeclareSignature( - TStringRef name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) - { - const auto typeInfoHelper = builder.TypeInfoHelper(); + static bool DeclareSignature( + TStringRef name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) + { + const auto typeInfoHelper = builder.TypeInfoHelper(); - TTupleTypeInspector tuple(*typeInfoHelper, userType); - Y_ENSURE(tuple); - Y_ENSURE(tuple.GetElementsCount() > 0); - TTupleTypeInspector argsTuple(*typeInfoHelper, tuple.GetElementType(0)); - Y_ENSURE(argsTuple); + TTupleTypeInspector tuple(*typeInfoHelper, userType); + Y_ENSURE(tuple); + Y_ENSURE(tuple.GetElementsCount() > 0); + TTupleTypeInspector argsTuple(*typeInfoHelper, tuple.GetElementType(0)); + Y_ENSURE(argsTuple); - if (argsTuple.GetElementsCount() != 1) { - builder.SetError("Expected one argument"); - return true; - } - auto argType = argsTuple.GetElementType(0); + if (argsTuple.GetElementsCount() != 1) { + builder.SetError("Expected one argument"); + return true; + } + auto argType = argsTuple.GetElementType(0); - builder.UserType(userType); - builder.SupportsBlocks(); - builder.IsStrict(); + builder.UserType(userType); + builder.SupportsBlocks(); + builder.IsStrict(); - TBlockTypeInspector block(*typeInfoHelper, argType); - if (block) { - const auto* blockArgType = builder.Block(false)->Item<TUserDataType>().Build(); - builder.Args()->Add(blockArgType).Flags(ICallablePayload::TArgumentFlags::AutoMap); - const auto* retType = builder.Resource(TMResourceName); - const auto* blockRetType = builder.Block(false)->Item(retType).Build(); - builder.Returns(blockRetType); + TBlockTypeInspector block(*typeInfoHelper, argType); + if (block) { + const auto* blockArgType = builder.Block(false)->Item<TUserDataType>().Build(); + builder.Args()->Add(blockArgType).Flags(ICallablePayload::TArgumentFlags::AutoMap); + const auto* retType = builder.Resource(TMResourceName); + const auto* blockRetType = builder.Block(false)->Item(retType).Build(); + builder.Returns(blockRetType); - if (!typesOnly) { - builder.Implementation(new TSimpleArrowUdfImpl({blockArgType}, retType, block.IsScalar(), - TSplitKernelExec<TUserDataType>::Do, builder, TString(name), arrow::compute::NullHandling::COMPUTED_NO_PREALLOCATE)); - } + if (!typesOnly) { + builder.Implementation(new TSimpleArrowUdfImpl({blockArgType}, retType, block.IsScalar(), + TSplitKernelExec<TUserDataType>::Do, builder, TString(name), arrow::compute::NullHandling::COMPUTED_NO_PREALLOCATE)); + } + } else { + builder.Args()->Add<TUserDataType>().Flags(ICallablePayload::TArgumentFlags::AutoMap); + if constexpr (NUdf::TDataType<TUserDataType>::Features & NYql::NUdf::ExtDateType) { + builder.Returns(builder.Resource(TM64ResourceName)); } else { - builder.Args()->Add<TUserDataType>().Flags(ICallablePayload::TArgumentFlags::AutoMap); - if constexpr (NUdf::TDataType<TUserDataType>::Features & NYql::NUdf::ExtDateType) { - builder.Returns(builder.Resource(TM64ResourceName)); - } else { - builder.Returns(builder.Resource(TMResourceName)); - } - - if (!typesOnly) { - builder.Implementation(new TSplit<TUserDataType>(builder.GetSourcePosition())); - } + builder.Returns(builder.Resource(TMResourceName)); } - return true; + if (!typesOnly) { + builder.Implementation(new TSplit<TUserDataType>(builder.GetSourcePosition())); + } } - }; - template <> - void TSplitKernelExec<TDate>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromDate(builder.GetDateBuilder(), arg.Get<ui16>()); - } - - template <> - void TSplitKernelExec<TDatetime>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromDatetime(builder.GetDateBuilder(), arg.Get<ui32>()); + return true; } +}; - template <> - void TSplitKernelExec<TTimestamp>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>()); - } +template <> +void TSplitKernelExec<TDate>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromDate(builder.GetDateBuilder(), arg.Get<ui16>()); +} - template <> - void TSplitKernelExec<TTzDate>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromDate(builder.GetDateBuilder(), arg.Get<ui16>(), arg.GetTimezoneId()); - } +template <> +void TSplitKernelExec<TDatetime>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromDatetime(builder.GetDateBuilder(), arg.Get<ui32>()); +} - template <> - void TSplitKernelExec<TTzDatetime>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromDatetime(builder.GetDateBuilder(), arg.Get<ui32>(), arg.GetTimezoneId()); - } +template <> +void TSplitKernelExec<TTimestamp>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>()); +} - template <> - void TSplitKernelExec<TTzTimestamp>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) { - storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>(), arg.GetTimezoneId()); - } +template <> +void TSplitKernelExec<TTzDate>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromDate(builder.GetDateBuilder(), arg.Get<ui16>(), arg.GetTimezoneId()); +} - template <> - void TSplitKernelExec<TDate32>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TTzDatetime>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromDatetime(builder.GetDateBuilder(), arg.Get<ui32>(), arg.GetTimezoneId()); +} - template <> - void TSplitKernelExec<TDatetime64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TTzTimestamp>::Split(TBlockItem arg, TTMStorage& storage, const IValueBuilder& builder) { + storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>(), arg.GetTimezoneId()); +} - template <> - void TSplitKernelExec<TTimestamp64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TDate32>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - template <> - void TSplitKernelExec<TTzDate32>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TDatetime64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - template <> - void TSplitKernelExec<TTzDatetime64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TTimestamp64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - template <> - void TSplitKernelExec<TTzTimestamp64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { - ythrow yexception() << "Not implemented"; - } +template <> +void TSplitKernelExec<TTzDate32>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - template <> - TUnboxedValue TSplit<TDate>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +void TSplitKernelExec<TTzDatetime64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromDate(builder, args[0].Get<ui16>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } - } +template <> +void TSplitKernelExec<TTzTimestamp64>::Split(TBlockItem, TTMStorage&, const IValueBuilder&) { + ythrow yexception() << "Not implemented"; +} - template <> - TUnboxedValue TSplit<TDate32>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TDate>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromDate32(valueBuilder->GetDateBuilder(), args[0].Get<i32>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromDate(builder, args[0].Get<ui16>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TDatetime>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TDate32>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromDatetime(builder, args[0].Get<ui32>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromDate32(valueBuilder->GetDateBuilder(), args[0].Get<i32>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TDatetime64>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TDatetime>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromDatetime64(valueBuilder->GetDateBuilder(), args[0].Get<i64>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromDatetime(builder, args[0].Get<ui32>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTimestamp>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TDatetime64>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromTimestamp(builder, args[0].Get<ui64>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromDatetime64(valueBuilder->GetDateBuilder(), args[0].Get<i64>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTimestamp64>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TTimestamp>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromTimestamp64(valueBuilder->GetDateBuilder(), args[0].Get<i64>()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromTimestamp(builder, args[0].Get<ui64>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTzDate>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TTimestamp64>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromDate(builder, args[0].Get<ui16>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromTimestamp64(valueBuilder->GetDateBuilder(), args[0].Get<i64>()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTzDate32>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TTzDate>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromDate32(builder, args[0].Get<i32>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromDate(builder, args[0].Get<ui16>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} +template <> +TUnboxedValue TSplit<TTzDate32>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - template <> - TUnboxedValue TSplit<TTzDatetime>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); - - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromDatetime(builder, args[0].Get<ui32>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromDate32(builder, args[0].Get<i32>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTzDatetime64>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TTzDatetime>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromDatetime64(builder, args[0].Get<i64>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromDatetime(builder, args[0].Get<ui32>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} +template <> +TUnboxedValue TSplit<TTzDatetime64>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - template <> - TUnboxedValue TSplit<TTzTimestamp>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); - - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TMResourceName>(result); - storage.FromTimestamp(builder, args[0].Get<ui64>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromDatetime64(builder, args[0].Get<i64>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - template <> - TUnboxedValue TSplit<TTzTimestamp64>::Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); +template <> +TUnboxedValue TSplit<TTzTimestamp>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - auto& builder = valueBuilder->GetDateBuilder(); - TUnboxedValuePod result(0); - auto& storage = Reference<TM64ResourceName>(result); - storage.FromTimestamp64(builder, args[0].Get<i64>(), args[0].GetTimezoneId()); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TMResourceName>(result); + storage.FromTimestamp(builder, args[0].Get<ui64>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } +} - // Make* +template <> +TUnboxedValue TSplit<TTzTimestamp64>::Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - template<typename TUserDataType, bool Nullable> - using TMakeResBuilder = std::conditional_t<TTzDataType<TUserDataType>::Result, - TTzDateArrayBuilder<TUserDataType, Nullable>, - TFixedSizeArrayBuilder<typename TDataType<TUserDataType>::TLayout, Nullable>>; + auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TM64ResourceName>(result); + storage.FromTimestamp64(builder, args[0].Get<i64>(), args[0].GetTimezoneId()); + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); + } +} - template<typename TUserDataType> - struct TMakeDateKernelExec : TUnaryKernelExec<TMakeDateKernelExec<TUserDataType>, TReaderTraits::TResource<false>, TMakeResBuilder<TUserDataType, false>> { - static TBlockItem Make(TTMStorage& storage, const IValueBuilder& valueBuilder); +// Make* - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - auto& storage = Reference<TMResourceName>(item); - sink(TBlockItem(Make(storage, *valueBuilder))); - } - }; +template <typename TUserDataType, bool Nullable> +using TMakeResBuilder = std::conditional_t<TTzDataType<TUserDataType>::Result, + TTzDateArrayBuilder<TUserDataType, Nullable>, + TFixedSizeArrayBuilder<typename TDataType<TUserDataType>::TLayout, Nullable>>; - template<> TBlockItem TMakeDateKernelExec<TDate>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToDate(valueBuilder.GetDateBuilder(), /*local*/ false)); - return res; - } +template <typename TUserDataType> +struct TMakeDateKernelExec: TUnaryKernelExec<TMakeDateKernelExec<TUserDataType>, TReaderTraits::TResource<false>, TMakeResBuilder<TUserDataType, false>> { + static TBlockItem Make(TTMStorage& storage, const IValueBuilder& valueBuilder); - template<> TBlockItem TMakeDateKernelExec<TDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder())); - return res; + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { + auto& storage = Reference<TMResourceName>(item); + sink(TBlockItem(Make(storage, *valueBuilder))); } +}; - template<> TBlockItem TMakeDateKernelExec<TTimestamp>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToTimestamp(valueBuilder.GetDateBuilder())); - return res; - } +template <> +TBlockItem TMakeDateKernelExec<TDate>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToDate(valueBuilder.GetDateBuilder(), /*local*/ false)); + return res; +} - template<> TBlockItem TMakeDateKernelExec<TTzDate>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToDate(valueBuilder.GetDateBuilder(), /*local*/ true)); - res.SetTimezoneId(storage.TimezoneId); - return res; - } +template <> +TBlockItem TMakeDateKernelExec<TDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder())); + return res; +} - template<> TBlockItem TMakeDateKernelExec<TTzDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder())); - res.SetTimezoneId(storage.TimezoneId); - return res; - } +template <> +TBlockItem TMakeDateKernelExec<TTimestamp>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToTimestamp(valueBuilder.GetDateBuilder())); + return res; +} - template<> TBlockItem TMakeDateKernelExec<TTzTimestamp>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { - TBlockItem res(storage.ToTimestamp(valueBuilder.GetDateBuilder())); - res.SetTimezoneId(storage.TimezoneId); - return res; - } +template <> +TBlockItem TMakeDateKernelExec<TTzDate>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToDate(valueBuilder.GetDateBuilder(), /*local*/ true)); + res.SetTimezoneId(storage.TimezoneId); + return res; +} - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeDate, TDate(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - return TUnboxedValuePod(storage.ToDate(builder, false)); - } - END_SIMPLE_ARROW_UDF(TMakeDate, TMakeDateKernelExec<TDate>::Do); +template <> +TBlockItem TMakeDateKernelExec<TTzDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder())); + res.SetTimezoneId(storage.TimezoneId); + return res; +} - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeDatetime, TDatetime(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - return TUnboxedValuePod(storage.ToDatetime(builder)); - } - END_SIMPLE_ARROW_UDF(TMakeDatetime, TMakeDateKernelExec<TDatetime>::Do); +template <> +TBlockItem TMakeDateKernelExec<TTzTimestamp>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) { + TBlockItem res(storage.ToTimestamp(valueBuilder.GetDateBuilder())); + res.SetTimezoneId(storage.TimezoneId); + return res; +} - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTimestamp, TTimestamp(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - return TUnboxedValuePod(storage.ToTimestamp(builder)); - } - END_SIMPLE_ARROW_UDF(TMakeTimestamp, TMakeDateKernelExec<TTimestamp>::Do); +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeDate, TDate(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + return TUnboxedValuePod(storage.ToDate(builder, false)); +} +END_SIMPLE_ARROW_UDF(TMakeDate, TMakeDateKernelExec<TDate>::Do); - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzDate, TTzDate(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - try { - TUnboxedValuePod result(storage.ToDate(builder, true)); - result.SetTimezoneId(storage.TimezoneId); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << "Timestamp " - << storage.ToString() - << " cannot be casted to TzDate" - ).c_str()); - } - } - END_SIMPLE_ARROW_UDF(TMakeTzDate, TMakeDateKernelExec<TTzDate>::Do); +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeDatetime, TDatetime(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + return TUnboxedValuePod(storage.ToDatetime(builder)); +} +END_SIMPLE_ARROW_UDF(TMakeDatetime, TMakeDateKernelExec<TDatetime>::Do); - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzDatetime, TTzDatetime(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - TUnboxedValuePod result(storage.ToDatetime(builder)); - result.SetTimezoneId(storage.TimezoneId); - return result; - } - END_SIMPLE_ARROW_UDF(TMakeTzDatetime, TMakeDateKernelExec<TTzDatetime>::Do); +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTimestamp, TTimestamp(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + return TUnboxedValuePod(storage.ToTimestamp(builder)); +} +END_SIMPLE_ARROW_UDF(TMakeTimestamp, TMakeDateKernelExec<TTimestamp>::Do); - BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzTimestamp, TTzTimestamp(TAutoMap<TResource<TMResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TMResourceName>(args[0]); - TUnboxedValuePod result(storage.ToTimestamp(builder)); +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzDate, TTzDate(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + try { + TUnboxedValuePod result(storage.ToDate(builder, true)); result.SetTimezoneId(storage.TimezoneId); return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << "Timestamp " + << storage.ToString() + << " cannot be casted to TzDate") + .c_str()); } - END_SIMPLE_ARROW_UDF(TMakeTzTimestamp, TMakeDateKernelExec<TTzTimestamp>::Do); +} +END_SIMPLE_ARROW_UDF(TMakeTzDate, TMakeDateKernelExec<TTzDate>::Do); +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzDatetime, TTzDatetime(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + TUnboxedValuePod result(storage.ToDatetime(builder)); + result.SetTimezoneId(storage.TimezoneId); + return result; +} +END_SIMPLE_ARROW_UDF(TMakeTzDatetime, TMakeDateKernelExec<TTzDatetime>::Do); - SIMPLE_STRICT_UDF(TConvert, TResource<TM64ResourceName>(TAutoMap<TResource<TMResourceName>>)) { - Y_UNUSED(valueBuilder); - TUnboxedValuePod result(0); - auto& arg = Reference<TMResourceName>(args[0]); - auto& storage = Reference<TM64ResourceName>(result); - storage.From(arg); - return result; - } +BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzTimestamp, TTzTimestamp(TAutoMap<TResource<TMResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TMResourceName>(args[0]); + TUnboxedValuePod result(storage.ToTimestamp(builder)); + result.SetTimezoneId(storage.TimezoneId); + return result; +} +END_SIMPLE_ARROW_UDF(TMakeTzTimestamp, TMakeDateKernelExec<TTzTimestamp>::Do); - SIMPLE_STRICT_UDF(TMakeDate32, TDate32(TAutoMap<TResource<TM64ResourceName>>)) { - auto& storage = Reference<TM64ResourceName>(args[0]); - return TUnboxedValuePod(storage.ToDate32(valueBuilder->GetDateBuilder(), false)); - } +SIMPLE_STRICT_UDF(TConvert, TResource<TM64ResourceName>(TAutoMap<TResource<TMResourceName>>)) { + Y_UNUSED(valueBuilder); + TUnboxedValuePod result(0); + auto& arg = Reference<TMResourceName>(args[0]); + auto& storage = Reference<TM64ResourceName>(result); + storage.From(arg); + return result; +} - SIMPLE_STRICT_UDF(TMakeDatetime64, TDatetime64(TAutoMap<TResource<TM64ResourceName>>)) { - auto& storage = Reference<TM64ResourceName>(args[0]); - return TUnboxedValuePod(storage.ToDatetime64(valueBuilder->GetDateBuilder())); - } +SIMPLE_STRICT_UDF(TMakeDate32, TDate32(TAutoMap<TResource<TM64ResourceName>>)) { + auto& storage = Reference<TM64ResourceName>(args[0]); + return TUnboxedValuePod(storage.ToDate32(valueBuilder->GetDateBuilder(), false)); +} - SIMPLE_STRICT_UDF(TMakeTimestamp64, TTimestamp64(TAutoMap<TResource<TM64ResourceName>>)) { - auto& storage = Reference<TM64ResourceName>(args[0]); - return TUnboxedValuePod(storage.ToTimestamp64(valueBuilder->GetDateBuilder())); - } +SIMPLE_STRICT_UDF(TMakeDatetime64, TDatetime64(TAutoMap<TResource<TM64ResourceName>>)) { + auto& storage = Reference<TM64ResourceName>(args[0]); + return TUnboxedValuePod(storage.ToDatetime64(valueBuilder->GetDateBuilder())); +} - SIMPLE_STRICT_UDF(TMakeTzDate32, TTzDate32(TAutoMap<TResource<TM64ResourceName>>)) { - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TM64ResourceName>(args[0]); - try { - TUnboxedValuePod result(storage.ToDate32(builder, true)); - result.SetTimezoneId(storage.TimezoneId); - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << "Timestamp " - << storage.ToString() - << " cannot be casted to TzDate32" - ).c_str()); - } - } +SIMPLE_STRICT_UDF(TMakeTimestamp64, TTimestamp64(TAutoMap<TResource<TM64ResourceName>>)) { + auto& storage = Reference<TM64ResourceName>(args[0]); + return TUnboxedValuePod(storage.ToTimestamp64(valueBuilder->GetDateBuilder())); +} - SIMPLE_STRICT_UDF(TMakeTzDatetime64, TTzDatetime64(TAutoMap<TResource<TM64ResourceName>>)) { - auto& storage = Reference<TM64ResourceName>(args[0]); - TUnboxedValuePod result(storage.ToDatetime64(valueBuilder->GetDateBuilder())); +SIMPLE_STRICT_UDF(TMakeTzDate32, TTzDate32(TAutoMap<TResource<TM64ResourceName>>)) { + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TM64ResourceName>(args[0]); + try { + TUnboxedValuePod result(storage.ToDate32(builder, true)); result.SetTimezoneId(storage.TimezoneId); return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << "Timestamp " + << storage.ToString() + << " cannot be casted to TzDate32") + .c_str()); } +} - SIMPLE_STRICT_UDF(TMakeTzTimestamp64, TTzTimestamp64(TAutoMap<TResource<TM64ResourceName>>)) { - auto& storage = Reference<TM64ResourceName>(args[0]); - TUnboxedValuePod result(storage.ToTimestamp64(valueBuilder->GetDateBuilder())); - result.SetTimezoneId(storage.TimezoneId); - return result; - } +SIMPLE_STRICT_UDF(TMakeTzDatetime64, TTzDatetime64(TAutoMap<TResource<TM64ResourceName>>)) { + auto& storage = Reference<TM64ResourceName>(args[0]); + TUnboxedValuePod result(storage.ToDatetime64(valueBuilder->GetDateBuilder())); + result.SetTimezoneId(storage.TimezoneId); + return result; +} + +SIMPLE_STRICT_UDF(TMakeTzTimestamp64, TTzTimestamp64(TAutoMap<TResource<TM64ResourceName>>)) { + auto& storage = Reference<TM64ResourceName>(args[0]); + TUnboxedValuePod result(storage.ToTimestamp64(valueBuilder->GetDateBuilder())); + result.SetTimezoneId(storage.TimezoneId); + return result; +} - // Get* +// Get* // #define GET_METHOD(field, type) \ // struct TGet##field##KernelExec : TUnaryKernelExec<TGet##field##KernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<type, false>> { \ @@ -1305,9 +1294,9 @@ TUnboxedValuePod DoAddYears(const TUnboxedValuePod& date, i64 years, const NUdf: // } \ // END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGet##field, TGet##field##KernelExec::Do, arrow::compute::NullHandling::INTERSECTION); -template<const char* TUdfName, - typename TResultType, TResultType (*Accessor)(const TUnboxedValuePod&), - typename TResultWType, TResultWType (*WAccessor)(const TUnboxedValuePod&)> +template <const char* TUdfName, + typename TResultType, TResultType (*Accessor)(const TUnboxedValuePod&), + typename TResultWType, TResultWType (*WAccessor)(const TUnboxedValuePod&)> class TGetDateComponent: public ::NYql::NUdf::TBoxedValue { public: typedef bool TTypeAwareMarker; @@ -1393,9 +1382,10 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<typename TResult, TResult (*Func)(const TUnboxedValuePod&)> - class TImpl : public TBoxedValue { + template <typename TResult, TResult (*Func)(const TUnboxedValuePod&)> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { Y_UNUSED(valueBuilder); @@ -1404,7 +1394,7 @@ private: } }; - template<typename TResult, const char* TResourceName, TResult (*Func)(const TUnboxedValuePod&)> + template <typename TResult, const char* TResourceName, TResult (*Func)(const TUnboxedValuePod&)> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TResult>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>(); @@ -1416,7 +1406,7 @@ private: }; // TODO: Merge this with <TGetDateComponent> class. -template<const char* TUdfName, auto Accessor, auto WAccessor> +template <const char* TUdfName, auto Accessor, auto WAccessor> class TGetDateComponentName: public ::NYql::NUdf::TBoxedValue { public: typedef bool TTypeAwareMarker; @@ -1502,9 +1492,10 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<auto Func> - class TImpl : public TBoxedValue { + template <auto Func> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { EMPTY_RESULT_ON_EMPTY_ARG(0); @@ -1512,7 +1503,7 @@ private: } }; - template<const char* TResourceName, auto Func> + template <const char* TResourceName, auto Func> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<char*>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>(); @@ -1523,115 +1514,111 @@ private: } }; - // template<typename TValue> - // TValue GetMonthNameValue(size_t idx) { - // static const std::array<TValue, 12U> monthNames = {{ - // TValue::Embedded(TStringRef::Of("January")), - // TValue::Embedded(TStringRef::Of("February")), - // TValue::Embedded(TStringRef::Of("March")), - // TValue::Embedded(TStringRef::Of("April")), - // TValue::Embedded(TStringRef::Of("May")), - // TValue::Embedded(TStringRef::Of("June")), - // TValue::Embedded(TStringRef::Of("July")), - // TValue::Embedded(TStringRef::Of("August")), - // TValue::Embedded(TStringRef::Of("September")), - // TValue::Embedded(TStringRef::Of("October")), - // TValue::Embedded(TStringRef::Of("November")), - // TValue::Embedded(TStringRef::Of("December")) - // }}; - // return monthNames.at(idx); - // } - - // struct TGetMonthNameKernelExec : TUnaryKernelExec<TGetMonthNameKernelExec, TReaderTraits::TResource<true>, TStringArrayBuilder<arrow::StringType, false>> { - // template<typename TSink> - // static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - // Y_UNUSED(valueBuilder); - // sink(GetMonthNameValue<TBlockItem>(GetMonth(item) - 1U)); - // } - // }; - - // BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetMonthName, char*(TAutoMap<TResource<TMResourceName>>)) { - // Y_UNUSED(valueBuilder); - // return GetMonthNameValue<TUnboxedValue>(GetMonth(*args) - 1U); - // } - // END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetMonthName, TGetMonthNameKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); - -template<const char* TResourceName> +// template<typename TValue> +// TValue GetMonthNameValue(size_t idx) { +// static const std::array<TValue, 12U> monthNames = {{ +// TValue::Embedded(TStringRef::Of("January")), +// TValue::Embedded(TStringRef::Of("February")), +// TValue::Embedded(TStringRef::Of("March")), +// TValue::Embedded(TStringRef::Of("April")), +// TValue::Embedded(TStringRef::Of("May")), +// TValue::Embedded(TStringRef::Of("June")), +// TValue::Embedded(TStringRef::Of("July")), +// TValue::Embedded(TStringRef::Of("August")), +// TValue::Embedded(TStringRef::Of("September")), +// TValue::Embedded(TStringRef::Of("October")), +// TValue::Embedded(TStringRef::Of("November")), +// TValue::Embedded(TStringRef::Of("December")) +// }}; +// return monthNames.at(idx); +// } + +// struct TGetMonthNameKernelExec : TUnaryKernelExec<TGetMonthNameKernelExec, TReaderTraits::TResource<true>, TStringArrayBuilder<arrow::StringType, false>> { +// template<typename TSink> +// static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { +// Y_UNUSED(valueBuilder); +// sink(GetMonthNameValue<TBlockItem>(GetMonth(item) - 1U)); +// } +// }; + +// BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetMonthName, char*(TAutoMap<TResource<TMResourceName>>)) { +// Y_UNUSED(valueBuilder); +// return GetMonthNameValue<TUnboxedValue>(GetMonth(*args) - 1U); +// } +// END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetMonthName, TGetMonthNameKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); + +template <const char* TResourceName> TUnboxedValue GetMonthName(const IValueBuilder* valueBuilder, const TUnboxedValuePod& arg) { Y_UNUSED(valueBuilder); - static const std::array<TUnboxedValue, 12U> monthNames = {{ - TUnboxedValuePod::Embedded(TStringRef::Of("January")), - TUnboxedValuePod::Embedded(TStringRef::Of("February")), - TUnboxedValuePod::Embedded(TStringRef::Of("March")), - TUnboxedValuePod::Embedded(TStringRef::Of("April")), - TUnboxedValuePod::Embedded(TStringRef::Of("May")), - TUnboxedValuePod::Embedded(TStringRef::Of("June")), - TUnboxedValuePod::Embedded(TStringRef::Of("July")), - TUnboxedValuePod::Embedded(TStringRef::Of("August")), - TUnboxedValuePod::Embedded(TStringRef::Of("September")), - TUnboxedValuePod::Embedded(TStringRef::Of("October")), - TUnboxedValuePod::Embedded(TStringRef::Of("November")), - TUnboxedValuePod::Embedded(TStringRef::Of("December")) - }}; + static const std::array<TUnboxedValue, 12U> monthNames = {{TUnboxedValuePod::Embedded(TStringRef::Of("January")), + TUnboxedValuePod::Embedded(TStringRef::Of("February")), + TUnboxedValuePod::Embedded(TStringRef::Of("March")), + TUnboxedValuePod::Embedded(TStringRef::Of("April")), + TUnboxedValuePod::Embedded(TStringRef::Of("May")), + TUnboxedValuePod::Embedded(TStringRef::Of("June")), + TUnboxedValuePod::Embedded(TStringRef::Of("July")), + TUnboxedValuePod::Embedded(TStringRef::Of("August")), + TUnboxedValuePod::Embedded(TStringRef::Of("September")), + TUnboxedValuePod::Embedded(TStringRef::Of("October")), + TUnboxedValuePod::Embedded(TStringRef::Of("November")), + TUnboxedValuePod::Embedded(TStringRef::Of("December"))}}; return monthNames.at(GetMonth<TResourceName>(arg) - 1U); } - // struct TGetDayOfMonthKernelExec : TUnaryKernelExec<TGetMonthNameKernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<ui8, false>> { - // template<typename TSink> - // static void Process(TBlockItem item, const TSink& sink) { - // sink(GetDay(item)); - // } - // }; +// struct TGetDayOfMonthKernelExec : TUnaryKernelExec<TGetMonthNameKernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<ui8, false>> { +// template<typename TSink> +// static void Process(TBlockItem item, const TSink& sink) { +// sink(GetDay(item)); +// } +// }; - // BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetDayOfMonth, ui8(TAutoMap<TResource<TMResourceName>>)) { - // Y_UNUSED(valueBuilder); - // return TUnboxedValuePod(GetDay(args[0])); - // } - // END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetDayOfMonth, TGetDayOfMonthKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); +// BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetDayOfMonth, ui8(TAutoMap<TResource<TMResourceName>>)) { +// Y_UNUSED(valueBuilder); +// return TUnboxedValuePod(GetDay(args[0])); +// } +// END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetDayOfMonth, TGetDayOfMonthKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); -template<const char* TResourceName> +template <const char* TResourceName> TUnboxedValue GetDayOfWeekName(const IValueBuilder* valueBuilder, const TUnboxedValuePod& arg) { Y_UNUSED(valueBuilder); - static const std::array<TUnboxedValue, 7U> dayNames = {{ - TUnboxedValuePod::Embedded(TStringRef::Of("Monday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Tuesday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Wednesday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Thursday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Friday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Saturday")), - TUnboxedValuePod::Embedded(TStringRef::Of("Sunday")) - }}; + static const std::array<TUnboxedValue, 7U> dayNames = {{TUnboxedValuePod::Embedded(TStringRef::Of("Monday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Tuesday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Wednesday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Thursday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Friday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Saturday")), + TUnboxedValuePod::Embedded(TStringRef::Of("Sunday"))}}; return dayNames.at(GetDayOfWeek<TResourceName>(arg) - 1U); } - // struct TGetDayOfWeekNameKernelExec : TUnaryKernelExec<TGetDayOfWeekNameKernelExec, TReaderTraits::TResource<true>, TStringArrayBuilder<arrow::StringType, false>> { - // template<typename TSink> - // static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - // Y_UNUSED(valueBuilder); - // sink(GetDayNameValue<TBlockItem>(GetDayOfWeek(item) - 1U)); - // } - // }; - - // BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetDayOfWeekName, char*(TAutoMap<TResource<TMResourceName>>)) { - // Y_UNUSED(valueBuilder); - // return GetDayNameValue<TUnboxedValuePod>(GetDayOfWeek(*args) - 1U); - // } - // END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetDayOfWeekName, TGetDayOfWeekNameKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); - - struct TTGetTimezoneNameKernelExec : TUnaryKernelExec<TTGetTimezoneNameKernelExec, TReaderTraits::TResource<false>, TStringArrayBuilder<arrow::BinaryType, false>> { - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - Y_UNUSED(valueBuilder); - auto timezoneId = GetTimezoneId<TMResourceName>(item); - if (timezoneId >= NTi::GetTimezones().size()) { - sink(TBlockItem{}); - } else { - sink(TBlockItem{NTi::GetTimezones()[timezoneId]}); - } +// struct TGetDayOfWeekNameKernelExec : TUnaryKernelExec<TGetDayOfWeekNameKernelExec, TReaderTraits::TResource<true>, TStringArrayBuilder<arrow::StringType, false>> { +// template<typename TSink> +// static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { +// Y_UNUSED(valueBuilder); +// sink(GetDayNameValue<TBlockItem>(GetDayOfWeek(item) - 1U)); +// } +// }; + +// BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetDayOfWeekName, char*(TAutoMap<TResource<TMResourceName>>)) { +// Y_UNUSED(valueBuilder); +// return GetDayNameValue<TUnboxedValuePod>(GetDayOfWeek(*args) - 1U); +// } +// END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGetDayOfWeekName, TGetDayOfWeekNameKernelExec::Do, arrow::compute::NullHandling::INTERSECTION); + +struct TTGetTimezoneNameKernelExec: TUnaryKernelExec<TTGetTimezoneNameKernelExec, TReaderTraits::TResource<false>, TStringArrayBuilder<arrow::BinaryType, false>> { + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { + Y_UNUSED(valueBuilder); + auto timezoneId = GetTimezoneId<TMResourceName>(item); + if (timezoneId >= NTi::GetTimezones().size()) { + sink(TBlockItem{}); + } else { + sink(TBlockItem{NTi::GetTimezones()[timezoneId]}); } - }; + } +}; -template<const char* TResourceName> +template <const char* TResourceName> TUnboxedValue GetTimezoneName(const IValueBuilder* valueBuilder, const TUnboxedValuePod& arg) { const ui16 tzId = GetTimezoneId<TResourceName>(arg); const auto& tzNames = NTi::GetTimezones(); @@ -1641,212 +1628,202 @@ TUnboxedValue GetTimezoneName(const IValueBuilder* valueBuilder, const TUnboxedV return valueBuilder->NewString(tzNames[tzId]); } - // Update +// Update - class TUpdate : public TBoxedValue { - public: - typedef bool TTypeAwareMarker; - static const TStringRef& Name() { - static auto name = TStringRef::Of("Update"); - return name; - } - - static bool DeclareSignature( - const TStringRef& name, - TType* userType, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) - { - if (Name() != name) { - return false; - } - - if (!userType) { - // XXX: Function became polymorphic when overload for - // wide resources was implemented. Hence, to make it - // backward compatible with previous versions, the - // absence of the userType is considered as using the - // old version (i.e. without type awareness) that - // provides implementation only for narrow dates. - BuildSignature<TMResourceName>(builder, typesOnly); - return true; - } +class TUpdate: public TBoxedValue { +public: + typedef bool TTypeAwareMarker; + static const TStringRef& Name() { + static auto name = TStringRef::Of("Update"); + return name; + } - builder.UserType(userType); + static bool DeclareSignature( + const TStringRef& name, + TType* userType, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) + { + if (Name() != name) { + return false; + } - const auto typeInfoHelper = builder.TypeInfoHelper(); - TTupleTypeInspector tuple(*typeInfoHelper, userType); - Y_ENSURE(tuple, "Tuple with args and options tuples expected"); - Y_ENSURE(tuple.GetElementsCount() > 0, - "Tuple has to contain positional arguments"); + if (!userType) { + // XXX: Function became polymorphic when overload for + // wide resources was implemented. Hence, to make it + // backward compatible with previous versions, the + // absence of the userType is considered as using the + // old version (i.e. without type awareness) that + // provides implementation only for narrow dates. + BuildSignature<TMResourceName>(builder, typesOnly); + return true; + } - TTupleTypeInspector argsTuple(*typeInfoHelper, tuple.GetElementType(0)); - Y_ENSURE(argsTuple, "Tuple with args expected"); - if (argsTuple.GetElementsCount() == 0) { - builder.SetError("At least one argument expected"); - return true; - } + builder.UserType(userType); - auto argType = argsTuple.GetElementType(0); + const auto typeInfoHelper = builder.TypeInfoHelper(); + TTupleTypeInspector tuple(*typeInfoHelper, userType); + Y_ENSURE(tuple, "Tuple with args and options tuples expected"); + Y_ENSURE(tuple.GetElementsCount() > 0, + "Tuple has to contain positional arguments"); - if (const auto optType = TOptionalTypeInspector(*typeInfoHelper, argType)) { - argType = optType.GetItemType(); - } + TTupleTypeInspector argsTuple(*typeInfoHelper, tuple.GetElementType(0)); + Y_ENSURE(argsTuple, "Tuple with args expected"); + if (argsTuple.GetElementsCount() == 0) { + builder.SetError("At least one argument expected"); + return true; + } - TResourceTypeInspector resource(*typeInfoHelper, argType); - if (!resource) { - TDataTypeInspector data(*typeInfoHelper, argType); - if (!data) { - SetResourceExpectedError(builder, typeInfoHelper, argType); - return true; - } + auto argType = argsTuple.GetElementType(0); - const auto features = NUdf::GetDataTypeInfo(NUdf::GetDataSlot(data.GetTypeId())).Features; - if (features & NUdf::ExtDateType) { - BuildSignature<TM64ResourceName>(builder, typesOnly); - return true; - } - if (features & (NUdf::DateType | NUdf::TzDateType)) { - BuildSignature<TMResourceName>(builder, typesOnly); - return true; - } + if (const auto optType = TOptionalTypeInspector(*typeInfoHelper, argType)) { + argType = optType.GetItemType(); + } + TResourceTypeInspector resource(*typeInfoHelper, argType); + if (!resource) { + TDataTypeInspector data(*typeInfoHelper, argType); + if (!data) { SetResourceExpectedError(builder, typeInfoHelper, argType); return true; } - if (resource.GetTag() == TStringRef::Of(TM64ResourceName)) { + const auto features = NUdf::GetDataTypeInfo(NUdf::GetDataSlot(data.GetTypeId())).Features; + if (features & NUdf::ExtDateType) { BuildSignature<TM64ResourceName>(builder, typesOnly); return true; } - - if (resource.GetTag() == TStringRef::Of(TMResourceName)) { + if (features & (NUdf::DateType | NUdf::TzDateType)) { BuildSignature<TMResourceName>(builder, typesOnly); return true; } - SetUnexpectedTagError(builder, resource.GetTag()); + SetResourceExpectedError(builder, typeInfoHelper, argType); return true; } - private: - template<const char* TResourceName> - class TImpl : public TBoxedValue { - public: - TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); - auto result = args[0]; - - if (args[1]) { - auto year = args[1].Get<std::conditional_t<TResourceName == TMResourceName, ui16, i32>>(); - if (!ValidateYear<TResourceName>(year)) { - return TUnboxedValuePod(); - } - SetYear<TResourceName>(result, year); - } - if (args[2]) { - auto month = args[2].Get<ui8>(); - if (!ValidateMonth(month)) { - return TUnboxedValuePod(); - } - SetMonth<TResourceName>(result, month); + + if (resource.GetTag() == TStringRef::Of(TM64ResourceName)) { + BuildSignature<TM64ResourceName>(builder, typesOnly); + return true; + } + + if (resource.GetTag() == TStringRef::Of(TMResourceName)) { + BuildSignature<TMResourceName>(builder, typesOnly); + return true; + } + + SetUnexpectedTagError(builder, resource.GetTag()); + return true; + } + +private: + template <const char* TResourceName> + class TImpl: public TBoxedValue { + public: + TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); + auto result = args[0]; + + if (args[1]) { + auto year = args[1].Get<std::conditional_t<TResourceName == TMResourceName, ui16, i32>>(); + if (!ValidateYear<TResourceName>(year)) { + return TUnboxedValuePod(); } - if (args[3]) { - auto day = args[3].Get<ui8>(); - if (!ValidateDay(day)) { - return TUnboxedValuePod(); - } - SetDay<TResourceName>(result, day); + SetYear<TResourceName>(result, year); + } + if (args[2]) { + auto month = args[2].Get<ui8>(); + if (!ValidateMonth(month)) { + return TUnboxedValuePod(); } - if (args[4]) { - auto hour = args[4].Get<ui8>(); - if (!ValidateHour(hour)) { - return TUnboxedValuePod(); - } - SetHour<TResourceName>(result, hour); + SetMonth<TResourceName>(result, month); + } + if (args[3]) { + auto day = args[3].Get<ui8>(); + if (!ValidateDay(day)) { + return TUnboxedValuePod(); } - if (args[5]) { - auto minute = args[5].Get<ui8>(); - if (!ValidateMinute(minute)) { - return TUnboxedValuePod(); - } - SetMinute<TResourceName>(result, minute); + SetDay<TResourceName>(result, day); + } + if (args[4]) { + auto hour = args[4].Get<ui8>(); + if (!ValidateHour(hour)) { + return TUnboxedValuePod(); } - if (args[6]) { - auto second = args[6].Get<ui8>(); - if (!ValidateSecond(second)) { - return TUnboxedValuePod(); - } - SetSecond<TResourceName>(result, second); + SetHour<TResourceName>(result, hour); + } + if (args[5]) { + auto minute = args[5].Get<ui8>(); + if (!ValidateMinute(minute)) { + return TUnboxedValuePod(); } - if (args[7]) { - auto microsecond = args[7].Get<ui32>(); - if (!ValidateMicrosecond(microsecond)) { - return TUnboxedValuePod(); - } - SetMicrosecond<TResourceName>(result, microsecond); + SetMinute<TResourceName>(result, minute); + } + if (args[6]) { + auto second = args[6].Get<ui8>(); + if (!ValidateSecond(second)) { + return TUnboxedValuePod(); } - if (args[8]) { - auto timezoneId = args[8].Get<ui16>(); - if (!ValidateTimezoneId(timezoneId)) { - return TUnboxedValuePod(); - } - SetTimezoneId<TResourceName>(result, timezoneId); + SetSecond<TResourceName>(result, second); + } + if (args[7]) { + auto microsecond = args[7].Get<ui32>(); + if (!ValidateMicrosecond(microsecond)) { + return TUnboxedValuePod(); } - - auto& builder = valueBuilder->GetDateBuilder(); - auto& storage = Reference<TResourceName>(result); - if (!storage.Validate(builder)) { + SetMicrosecond<TResourceName>(result, microsecond); + } + if (args[8]) { + auto timezoneId = args[8].Get<ui16>(); + if (!ValidateTimezoneId(timezoneId)) { return TUnboxedValuePod(); } - return result; - } catch (const std::exception& e) { - TStringBuilder sb; - sb << CurrentExceptionMessage(); - sb << Endl << "[" << TStringBuf(Name()) << "]" ; - UdfTerminate(sb.c_str()); + SetTimezoneId<TResourceName>(result, timezoneId); } - } - }; - - template<const char* TResourceName> - static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { - builder.Returns<TOptional<TResource<TResourceName>>>(); - builder.OptionalArgs(8).Args()->Add<TAutoMap<TResource<TResourceName>>>() - .template Add<TOptional<std::conditional_t<TResourceName == TMResourceName, ui16, i32>>>().Name("Year") - .template Add<TOptional<ui8>>().Name("Month") - .template Add<TOptional<ui8>>().Name("Day") - .template Add<TOptional<ui8>>().Name("Hour") - .template Add<TOptional<ui8>>().Name("Minute") - .template Add<TOptional<ui8>>().Name("Second") - .template Add<TOptional<ui32>>().Name("Microsecond") - .template Add<TOptional<ui16>>().Name("TimezoneId"); - builder.IsStrict(); - if (!typesOnly) { - builder.Implementation(new TImpl<TResourceName>()); + auto& builder = valueBuilder->GetDateBuilder(); + auto& storage = Reference<TResourceName>(result); + if (!storage.Validate(builder)) { + return TUnboxedValuePod(); + } + return result; + } catch (const std::exception& e) { + TStringBuilder sb; + sb << CurrentExceptionMessage(); + sb << Endl << "[" << TStringBuf(Name()) << "]"; + UdfTerminate(sb.c_str()); } - } + } }; - // From* - - template<typename TInput, typename TOutput, i64 UsecMultiplier> - inline TUnboxedValuePod TFromConverter(TInput arg) { - using TLayout = TDataType<TOutput>::TLayout; - const TLayout usec = TLayout(arg) * UsecMultiplier; - return Validate<TOutput>(usec) ? TUnboxedValuePod(usec) : TUnboxedValuePod(); + template <const char* TResourceName> + static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { + builder.Returns<TOptional<TResource<TResourceName>>>(); + builder.OptionalArgs(8).Args()->Add<TAutoMap<TResource<TResourceName>>>().template Add<TOptional<std::conditional_t<TResourceName == TMResourceName, ui16, i32>>>().Name("Year").template Add<TOptional<ui8>>().Name("Month").template Add<TOptional<ui8>>().Name("Day").template Add<TOptional<ui8>>().Name("Hour").template Add<TOptional<ui8>>().Name("Minute").template Add<TOptional<ui8>>().Name("Second").template Add<TOptional<ui32>>().Name("Microsecond").template Add<TOptional<ui16>>().Name("TimezoneId"); + builder.IsStrict(); + if (!typesOnly) { + builder.Implementation(new TImpl<TResourceName>()); + } } +}; +// From* - template<typename TInput, typename TOutput, i64 UsecMultiplier> - using TFromConverterKernel = TUnaryUnsafeFixedSizeFilterKernel<TInput, - typename TDataType<TOutput>::TLayout, [] (TInput arg) { - using TLayout = TDataType<TOutput>::TLayout; - const TLayout usec = TLayout(arg) * UsecMultiplier; - return std::make_pair(usec, Validate<TOutput>(usec)); - }>; +template <typename TInput, typename TOutput, i64 UsecMultiplier> +inline TUnboxedValuePod TFromConverter(TInput arg) { + using TLayout = TDataType<TOutput>::TLayout; + const TLayout usec = TLayout(arg) * UsecMultiplier; + return Validate<TOutput>(usec) ? TUnboxedValuePod(usec) : TUnboxedValuePod(); +} +template <typename TInput, typename TOutput, i64 UsecMultiplier> +using TFromConverterKernel = TUnaryUnsafeFixedSizeFilterKernel<TInput, + typename TDataType<TOutput>::TLayout, [](TInput arg) { + using TLayout = TDataType<TOutput>::TLayout; + const TLayout usec = TLayout(arg) * UsecMultiplier; + return std::make_pair(usec, Validate<TOutput>(usec)); + }>; #define DATETIME_FROM_CONVERTER_UDF(name, retType, argType, usecMultiplier) \ BEGIN_SIMPLE_STRICT_ARROW_UDF(T##name, TOptional<retType>(TAutoMap<argType>)) { \ @@ -1856,38 +1833,38 @@ TUnboxedValue GetTimezoneName(const IValueBuilder* valueBuilder, const TUnboxedV \ END_SIMPLE_ARROW_UDF(T##name, (TFromConverterKernel<argType, retType, usecMultiplier>::Do)) -#define DATETIME_FROM_CONVERTER_UDF_N(space, name, retType, argType, usecMultiplier) \ - namespace N##space { \ - DATETIME_FROM_CONVERTER_UDF(name, retType, argType, usecMultiplier); \ +#define DATETIME_FROM_CONVERTER_UDF_N(space, name, retType, argType, usecMultiplier) \ + namespace N##space { \ + DATETIME_FROM_CONVERTER_UDF(name, retType, argType, usecMultiplier); \ } - DATETIME_FROM_CONVERTER_UDF(FromSeconds, TTimestamp, ui32, UsecondsInSecond); - DATETIME_FROM_CONVERTER_UDF(FromMilliseconds, TTimestamp, ui64, UsecondsInMilliseconds); - DATETIME_FROM_CONVERTER_UDF(FromMicroseconds, TTimestamp, ui64, 1); +DATETIME_FROM_CONVERTER_UDF(FromSeconds, TTimestamp, ui32, UsecondsInSecond); +DATETIME_FROM_CONVERTER_UDF(FromMilliseconds, TTimestamp, ui64, UsecondsInMilliseconds); +DATETIME_FROM_CONVERTER_UDF(FromMicroseconds, TTimestamp, ui64, 1); - DATETIME_FROM_CONVERTER_UDF(FromSeconds64, TTimestamp64, i64, UsecondsInSecond); - DATETIME_FROM_CONVERTER_UDF(FromMilliseconds64, TTimestamp64, i64, UsecondsInMilliseconds); - DATETIME_FROM_CONVERTER_UDF(FromMicroseconds64, TTimestamp64, i64, 1); +DATETIME_FROM_CONVERTER_UDF(FromSeconds64, TTimestamp64, i64, UsecondsInSecond); +DATETIME_FROM_CONVERTER_UDF(FromMilliseconds64, TTimestamp64, i64, UsecondsInMilliseconds); +DATETIME_FROM_CONVERTER_UDF(FromMicroseconds64, TTimestamp64, i64, 1); - DATETIME_FROM_CONVERTER_UDF(IntervalFromDays, TInterval, i32, UsecondsInDay); - DATETIME_FROM_CONVERTER_UDF(IntervalFromHours, TInterval, i32, UsecondsInHour); - DATETIME_FROM_CONVERTER_UDF(IntervalFromMinutes, TInterval, i32, UsecondsInMinute); - DATETIME_FROM_CONVERTER_UDF_N(Legacy, IntervalFromSeconds, TInterval, i32, UsecondsInSecond); - DATETIME_FROM_CONVERTER_UDF_N(Actual, IntervalFromSeconds, TInterval, i64, UsecondsInSecond); - DATETIME_FROM_CONVERTER_UDF(IntervalFromMilliseconds, TInterval, i64, UsecondsInMilliseconds); - DATETIME_FROM_CONVERTER_UDF(IntervalFromMicroseconds, TInterval, i64, 1); +DATETIME_FROM_CONVERTER_UDF(IntervalFromDays, TInterval, i32, UsecondsInDay); +DATETIME_FROM_CONVERTER_UDF(IntervalFromHours, TInterval, i32, UsecondsInHour); +DATETIME_FROM_CONVERTER_UDF(IntervalFromMinutes, TInterval, i32, UsecondsInMinute); +DATETIME_FROM_CONVERTER_UDF_N(Legacy, IntervalFromSeconds, TInterval, i32, UsecondsInSecond); +DATETIME_FROM_CONVERTER_UDF_N(Actual, IntervalFromSeconds, TInterval, i64, UsecondsInSecond); +DATETIME_FROM_CONVERTER_UDF(IntervalFromMilliseconds, TInterval, i64, UsecondsInMilliseconds); +DATETIME_FROM_CONVERTER_UDF(IntervalFromMicroseconds, TInterval, i64, 1); - DATETIME_FROM_CONVERTER_UDF(Interval64FromDays, TInterval64, i32, UsecondsInDay); - DATETIME_FROM_CONVERTER_UDF(Interval64FromHours, TInterval64, i64, UsecondsInHour); - DATETIME_FROM_CONVERTER_UDF(Interval64FromMinutes, TInterval64, i64, UsecondsInMinute); - DATETIME_FROM_CONVERTER_UDF(Interval64FromSeconds, TInterval64, i64, UsecondsInSecond); - DATETIME_FROM_CONVERTER_UDF(Interval64FromMilliseconds, TInterval64, i64, UsecondsInMilliseconds); - DATETIME_FROM_CONVERTER_UDF(Interval64FromMicroseconds, TInterval64, i64, 1); +DATETIME_FROM_CONVERTER_UDF(Interval64FromDays, TInterval64, i32, UsecondsInDay); +DATETIME_FROM_CONVERTER_UDF(Interval64FromHours, TInterval64, i64, UsecondsInHour); +DATETIME_FROM_CONVERTER_UDF(Interval64FromMinutes, TInterval64, i64, UsecondsInMinute); +DATETIME_FROM_CONVERTER_UDF(Interval64FromSeconds, TInterval64, i64, UsecondsInSecond); +DATETIME_FROM_CONVERTER_UDF(Interval64FromMilliseconds, TInterval64, i64, UsecondsInMilliseconds); +DATETIME_FROM_CONVERTER_UDF(Interval64FromMicroseconds, TInterval64, i64, 1); - // To* +// To* -template<const char* TUdfName, typename TResult, typename TWResult, i64 ScaleSeconds> -class TToConverter : public TBoxedValue { +template <const char* TUdfName, typename TResult, typename TWResult, i64 ScaleSeconds> +class TToConverter: public TBoxedValue { public: typedef bool TTypeAwareMarker; static const ::NYql::NUdf::TStringRef& Name() { @@ -1955,8 +1932,9 @@ public: SetIntervalExpectedError(builder, typeInfoHelper, argType); return true; } + private: - class TImpl : public TBoxedValue { + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { try { @@ -1965,14 +1943,13 @@ private: } catch (const std::exception& e) { TStringBuilder sb; sb << CurrentExceptionMessage(); - sb << Endl << "[" << TStringBuf(Name()) << "]" ; + sb << Endl << "[" << TStringBuf(Name()) << "]"; UdfTerminate(sb.c_str()); } } - }; - template<typename TInput, typename TOutput> + template <typename TInput, typename TOutput> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TOutput>(); builder.Args()->Add<TAutoMap<TInput>>(); @@ -1983,34 +1960,33 @@ private: } }; - // StartOf* - - template<auto Core> - struct TStartOfKernelExec : TUnaryKernelExec<TStartOfKernelExec<Core>, TResourceBlockReader<false>, TResourceArrayBuilder<true>> { - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - if (auto res = Core(Reference<TMResourceName>(item), *valueBuilder)) { - Reference<TMResourceName>(item) = res.GetRef(); - sink(item); - } else { - sink(TBlockItem{}); - } +// StartOf* +template <auto Core> +struct TStartOfKernelExec: TUnaryKernelExec<TStartOfKernelExec<Core>, TResourceBlockReader<false>, TResourceArrayBuilder<true>> { + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { + if (auto res = Core(Reference<TMResourceName>(item), *valueBuilder)) { + Reference<TMResourceName>(item) = res.GetRef(); + sink(item); + } else { + sink(TBlockItem{}); } - }; + } +}; - template<const char* TResourceName, auto Core> - TUnboxedValue SimpleDatetimeToDatetimeUdf(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) { - auto result = args[0]; - auto& storage = Reference<TResourceName>(result); - if (auto res = Core(storage, *valueBuilder)) { - storage = res.GetRef(); - return result; - } - return TUnboxedValuePod{}; +template <const char* TResourceName, auto Core> +TUnboxedValue SimpleDatetimeToDatetimeUdf(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) { + auto result = args[0]; + auto& storage = Reference<TResourceName>(result); + if (auto res = Core(storage, *valueBuilder)) { + storage = res.GetRef(); + return result; } + return TUnboxedValuePod{}; +} -template<const char* TUdfName, auto Boundary, auto WBoundary> +template <const char* TUdfName, auto Boundary, auto WBoundary> class TBoundaryOf: public ::NYql::NUdf::TBoxedValue { public: typedef bool TTypeAwareMarker; @@ -2096,23 +2072,24 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<auto Func> - class TImpl : public TBoxedValue { + template <auto Func> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { try { return Func(valueBuilder, args); } catch (const std::exception&) { - TStringBuilder sb; - sb << CurrentExceptionMessage(); - sb << Endl << "[" << TStringBuf(Name()) << "]" ; - UdfTerminate(sb.c_str()); + TStringBuilder sb; + sb << CurrentExceptionMessage(); + sb << Endl << "[" << TStringBuf(Name()) << "]"; + UdfTerminate(sb.c_str()); } } }; - template< const char* TResourceName, auto Func> + template <const char* TResourceName, auto Func> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TOptional<TResource<TResourceName>>>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>(); @@ -2123,222 +2100,222 @@ private: } }; - template<typename TStorage> - void SetStartOfDay(TStorage& storage) { - storage.Hour = 0; - storage.Minute = 0; - storage.Second = 0; - storage.Microsecond = 0; - } +template <typename TStorage> +void SetStartOfDay(TStorage& storage) { + storage.Hour = 0; + storage.Minute = 0; + storage.Second = 0; + storage.Microsecond = 0; +} - template<typename TStorage> - void SetEndOfDay(TStorage& storage) { - storage.Hour = 23; - storage.Minute = 59; - storage.Second = 59; - storage.Microsecond = 999999; - } +template <typename TStorage> +void SetEndOfDay(TStorage& storage) { + storage.Hour = 23; + storage.Minute = 59; + storage.Second = 59; + storage.Microsecond = 999999; +} - template<typename TStorage> - TMaybe<TStorage> StartOfYear(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Month = 1; - storage.Day = 1; - SetStartOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> StartOfYear(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Month = 1; + storage.Day = 1; + SetStartOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> EndOfYear(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Month = 12; - storage.Day = 31; - SetEndOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> EndOfYear(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Month = 12; + storage.Day = 31; + SetEndOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> StartOfQuarter(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Month = (storage.Month - 1) / 3 * 3 + 1; - storage.Day = 1; - SetStartOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> StartOfQuarter(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Month = (storage.Month - 1) / 3 * 3 + 1; + storage.Day = 1; + SetStartOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> EndOfQuarter(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Month = ((storage.Month - 1) / 3 + 1) * 3; - storage.Day = NMiniKQL::GetMonthLength(storage.Month, NMiniKQL::IsLeapYear(storage.Year)); - SetEndOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> EndOfQuarter(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Month = ((storage.Month - 1) / 3 + 1) * 3; + storage.Day = NMiniKQL::GetMonthLength(storage.Month, NMiniKQL::IsLeapYear(storage.Year)); + SetEndOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> StartOfMonth(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Day = 1; - SetStartOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> StartOfMonth(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Day = 1; + SetStartOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> EndOfMonth(TStorage storage, const IValueBuilder& valueBuilder) { - storage.Day = NMiniKQL::GetMonthLength(storage.Month, NMiniKQL::IsLeapYear(storage.Year)); - SetEndOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> EndOfMonth(TStorage storage, const IValueBuilder& valueBuilder) { + storage.Day = NMiniKQL::GetMonthLength(storage.Month, NMiniKQL::IsLeapYear(storage.Year)); + SetEndOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> StartOfWeek(TStorage storage, const IValueBuilder& valueBuilder) { - const ui32 shift = 86400u * (storage.DayOfWeek - 1u); - if constexpr (std::is_same_v<TStorage, TTMStorage>) { - if (shift > storage.ToDatetime(valueBuilder.GetDateBuilder())) { - return {}; - } - storage.FromDatetime(valueBuilder.GetDateBuilder(), storage.ToDatetime(valueBuilder.GetDateBuilder()) - shift, storage.TimezoneId); - } else { - if (shift > storage.ToDatetime64(valueBuilder.GetDateBuilder())) { - return {}; - } - storage.FromDatetime64(valueBuilder.GetDateBuilder(), storage.ToDatetime64(valueBuilder.GetDateBuilder()) - shift, storage.TimezoneId); - } - SetStartOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { +template <typename TStorage> +TMaybe<TStorage> StartOfWeek(TStorage storage, const IValueBuilder& valueBuilder) { + const ui32 shift = 86400u * (storage.DayOfWeek - 1u); + if constexpr (std::is_same_v<TStorage, TTMStorage>) { + if (shift > storage.ToDatetime(valueBuilder.GetDateBuilder())) { return {}; } - return storage; - } - - template<typename TStorage> - TMaybe<TStorage> EndOfWeek(TStorage storage, const IValueBuilder& valueBuilder) { - const ui32 shift = 86400u * (7u - storage.DayOfWeek); - if constexpr (std::is_same_v<TStorage, TTMStorage>) { - auto dt = storage.ToDatetime(valueBuilder.GetDateBuilder()); - if (NUdf::MAX_DATETIME - shift <= dt) { - return {}; - } - storage.FromDatetime(valueBuilder.GetDateBuilder(), dt + shift, storage.TimezoneId); - } else { - auto dt = storage.ToDatetime64(valueBuilder.GetDateBuilder()); - if (NUdf::MAX_DATETIME64 - shift <= dt) { - return {}; - } - storage.FromDatetime64(valueBuilder.GetDateBuilder(), dt + shift, storage.TimezoneId); - } - SetEndOfDay(storage); - if (!storage.Validate(valueBuilder.GetDateBuilder())) { + storage.FromDatetime(valueBuilder.GetDateBuilder(), storage.ToDatetime(valueBuilder.GetDateBuilder()) - shift, storage.TimezoneId); + } else { + if (shift > storage.ToDatetime64(valueBuilder.GetDateBuilder())) { return {}; } - return storage; + storage.FromDatetime64(valueBuilder.GetDateBuilder(), storage.ToDatetime64(valueBuilder.GetDateBuilder()) - shift, storage.TimezoneId); + } + SetStartOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> StartOfDay(TStorage storage, const IValueBuilder& valueBuilder) { - SetStartOfDay(storage); - auto& builder = valueBuilder.GetDateBuilder(); - if (!storage.Validate(builder)) { +template <typename TStorage> +TMaybe<TStorage> EndOfWeek(TStorage storage, const IValueBuilder& valueBuilder) { + const ui32 shift = 86400u * (7u - storage.DayOfWeek); + if constexpr (std::is_same_v<TStorage, TTMStorage>) { + auto dt = storage.ToDatetime(valueBuilder.GetDateBuilder()); + if (NUdf::MAX_DATETIME - shift <= dt) { return {}; } - return storage; - } - - template<typename TStorage> - TMaybe<TStorage> EndOfDay(TStorage storage, const IValueBuilder& valueBuilder) { - SetEndOfDay(storage); - auto& builder = valueBuilder.GetDateBuilder(); - if (!storage.Validate(builder)) { + storage.FromDatetime(valueBuilder.GetDateBuilder(), dt + shift, storage.TimezoneId); + } else { + auto dt = storage.ToDatetime64(valueBuilder.GetDateBuilder()); + if (NUdf::MAX_DATETIME64 - shift <= dt) { return {}; } - return storage; + storage.FromDatetime64(valueBuilder.GetDateBuilder(), dt + shift, storage.TimezoneId); + } + SetEndOfDay(storage); + if (!storage.Validate(valueBuilder.GetDateBuilder())) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> StartOf(TStorage storage, ui64 interval, const IValueBuilder& valueBuilder) { - if (interval >= 86400000000ull) { - // treat as StartOfDay - SetStartOfDay(storage); - } else { - auto current = storage.ToTimeOfDay(); - auto rounded = current / interval * interval; - storage.FromTimeOfDay(rounded); - } +template <typename TStorage> +TMaybe<TStorage> StartOfDay(TStorage storage, const IValueBuilder& valueBuilder) { + SetStartOfDay(storage); + auto& builder = valueBuilder.GetDateBuilder(); + if (!storage.Validate(builder)) { + return {}; + } + return storage; +} - auto& builder = valueBuilder.GetDateBuilder(); - if (!storage.Validate(builder)) { - return {}; - } - return storage; +template <typename TStorage> +TMaybe<TStorage> EndOfDay(TStorage storage, const IValueBuilder& valueBuilder) { + SetEndOfDay(storage); + auto& builder = valueBuilder.GetDateBuilder(); + if (!storage.Validate(builder)) { + return {}; } + return storage; +} - template<typename TStorage> - TMaybe<TStorage> EndOf(TStorage storage, ui64 interval, const IValueBuilder& valueBuilder) { - if (interval >= 86400000000ull) { - // treat as EndOfDay - SetEndOfDay(storage); - } else { - auto current = storage.ToTimeOfDay(); - auto rounded = current / interval * interval + interval - 1; - storage.FromTimeOfDay(rounded); - } +template <typename TStorage> +TMaybe<TStorage> StartOf(TStorage storage, ui64 interval, const IValueBuilder& valueBuilder) { + if (interval >= 86400000000ull) { + // treat as StartOfDay + SetStartOfDay(storage); + } else { + auto current = storage.ToTimeOfDay(); + auto rounded = current / interval * interval; + storage.FromTimeOfDay(rounded); + } - auto& builder = valueBuilder.GetDateBuilder(); - if (!storage.Validate(builder)) { - return {}; - } - return storage; + auto& builder = valueBuilder.GetDateBuilder(); + if (!storage.Validate(builder)) { + return {}; } + return storage; +} - template<bool UseEnd> - struct TStartEndOfBinaryKernelExec : TBinaryKernelExec<TStartEndOfBinaryKernelExec<UseEnd>> { - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem arg1, TBlockItem arg2, const TSink& sink) { - auto& storage = Reference<TMResourceName>(arg1); - ui64 interval = std::abs(arg2.Get<i64>()); - if (interval == 0) { - sink(arg1); - return; - } +template <typename TStorage> +TMaybe<TStorage> EndOf(TStorage storage, ui64 interval, const IValueBuilder& valueBuilder) { + if (interval >= 86400000000ull) { + // treat as EndOfDay + SetEndOfDay(storage); + } else { + auto current = storage.ToTimeOfDay(); + auto rounded = current / interval * interval + interval - 1; + storage.FromTimeOfDay(rounded); + } - if (auto res = (UseEnd ? EndOf<TTMStorage> : StartOf<TTMStorage>)(storage, interval, *valueBuilder)) { - storage = res.GetRef(); - sink(arg1); - } else { - sink(TBlockItem{}); - } - } - }; + auto& builder = valueBuilder.GetDateBuilder(); + if (!storage.Validate(builder)) { + return {}; + } + return storage; +} - template<const char* TResourceName, auto Core> - TUnboxedValue SimpleDatetimeToIntervalUdf(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) { - auto result = args[0]; - ui64 interval = std::abs(args[1].Get<i64>()); +template <bool UseEnd> +struct TStartEndOfBinaryKernelExec: TBinaryKernelExec<TStartEndOfBinaryKernelExec<UseEnd>> { + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem arg1, TBlockItem arg2, const TSink& sink) { + auto& storage = Reference<TMResourceName>(arg1); + ui64 interval = std::abs(arg2.Get<i64>()); if (interval == 0) { - return result; + sink(arg1); + return; } - auto& storage = Reference<TResourceName>(result); - if (auto res = Core(storage, interval, *valueBuilder)) { + + if (auto res = (UseEnd ? EndOf<TTMStorage> : StartOf<TTMStorage>)(storage, interval, *valueBuilder)) { storage = res.GetRef(); - return result; + sink(arg1); + } else { + sink(TBlockItem{}); } - return TUnboxedValuePod{}; } +}; + +template <const char* TResourceName, auto Core> +TUnboxedValue SimpleDatetimeToIntervalUdf(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) { + auto result = args[0]; + ui64 interval = std::abs(args[1].Get<i64>()); + if (interval == 0) { + return result; + } + auto& storage = Reference<TResourceName>(result); + if (auto res = Core(storage, interval, *valueBuilder)) { + storage = res.GetRef(); + return result; + } + return TUnboxedValuePod{}; +} -template<const char* TUdfName, auto Boundary, auto WBoundary> +template <const char* TUdfName, auto Boundary, auto WBoundary> class TBoundaryOfInterval: public ::NYql::NUdf::TBoxedValue { public: typedef bool TTypeAwareMarker; @@ -2424,27 +2401,27 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<auto Func> - class TImpl : public TBoxedValue { + template <auto Func> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { try { return Func(valueBuilder, args); } catch (const std::exception&) { - TStringBuilder sb; - sb << CurrentExceptionMessage(); - sb << Endl << "[" << TStringBuf(Name()) << "]" ; - UdfTerminate(sb.c_str()); + TStringBuilder sb; + sb << CurrentExceptionMessage(); + sb << Endl << "[" << TStringBuf(Name()) << "]"; + UdfTerminate(sb.c_str()); } } }; - template<const char* TResourceName, auto Func> + template <const char* TResourceName, auto Func> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TOptional<TResource<TResourceName>>>(); - builder.Args()->Add<TAutoMap<TResource<TResourceName>>>() - .template Add<TAutoMap<std::conditional_t<TResourceName == TMResourceName, TInterval, TInterval64>>>(); + builder.Args()->Add<TAutoMap<TResource<TResourceName>>>().template Add<TAutoMap<std::conditional_t<TResourceName == TMResourceName, TInterval, TInterval64>>>(); builder.IsStrict(); if (!typesOnly) { builder.Implementation(new TImpl<Func>()); @@ -2452,14 +2429,14 @@ private: } }; - struct TTimeOfDayKernelExec : TUnaryKernelExec<TTimeOfDayKernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<TDataType<TInterval>::TLayout, false>> { - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { - Y_UNUSED(valueBuilder); - auto& storage = Reference<TMResourceName>(item); - sink(TBlockItem{(TDataType<TInterval>::TLayout)storage.ToTimeOfDay()}); - } - }; +struct TTimeOfDayKernelExec: TUnaryKernelExec<TTimeOfDayKernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<TDataType<TInterval>::TLayout, false>> { + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) { + Y_UNUSED(valueBuilder); + auto& storage = Reference<TMResourceName>(item); + sink(TBlockItem{(TDataType<TInterval>::TLayout)storage.ToTimeOfDay()}); + } +}; class TTimeOfDay: public ::NYql::NUdf::TBoxedValue { public: @@ -2546,9 +2523,10 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<const char* TResourceName> - class TImpl : public TBoxedValue { + template <const char* TResourceName> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { try { @@ -2556,15 +2534,15 @@ private: auto& storage = Reference<TResourceName>(args[0]); return TUnboxedValuePod((i64)storage.ToTimeOfDay()); } catch (const std::exception&) { - TStringBuilder sb; - sb << CurrentExceptionMessage(); - sb << Endl << "[" << TStringBuf(Name()) << "]" ; - UdfTerminate(sb.c_str()); + TStringBuilder sb; + sb << CurrentExceptionMessage(); + sb << Endl << "[" << TStringBuf(Name()) << "]"; + UdfTerminate(sb.c_str()); } } }; - template< const char* TResourceName> + template <const char* TResourceName> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<std::conditional_t<TResourceName == TMResourceName, TInterval, TInterval64>>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>(); @@ -2575,19 +2553,18 @@ private: } }; +// Add ... - // Add ... - - template<auto Core> - struct TAddKernelExec : TBinaryKernelExec<TAddKernelExec<Core>> { - template<typename TSink> - static void Process(const IValueBuilder* valueBuilder, TBlockItem date, TBlockItem arg, const TSink& sink) { - sink(Core(date, arg.Get<i32>(), valueBuilder->GetDateBuilder())); - } - }; +template <auto Core> +struct TAddKernelExec: TBinaryKernelExec<TAddKernelExec<Core>> { + template <typename TSink> + static void Process(const IValueBuilder* valueBuilder, TBlockItem date, TBlockItem arg, const TSink& sink) { + sink(Core(date, arg.Get<i32>(), valueBuilder->GetDateBuilder())); + } +}; -template<const char* TUdfName, auto Shifter, auto WShifter> -class TShift : public TBoxedValue { +template <const char* TUdfName, auto Shifter, auto WShifter> +class TShift: public TBoxedValue { public: typedef bool TTypeAwareMarker; @@ -2673,16 +2650,17 @@ public: SetUnexpectedTagError(builder, resource.GetTag()); return true; } + private: - template<auto ShiftHanler> - class TImpl : public TBoxedValue { + template <auto ShiftHanler> + class TImpl: public TBoxedValue { public: TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final { return ShiftHanler(args[0], args[1].Get<i32>(), valueBuilder->GetDateBuilder()); } }; - template<const char* TResourceName, auto ShiftHandler> + template <const char* TResourceName, auto ShiftHandler> static void BuildSignature(NUdf::IFunctionTypeInfoBuilder& builder, bool typesOnly) { builder.Returns<TOptional<TResource<TResourceName>>>(); builder.Args()->Add<TAutoMap<TResource<TResourceName>>>().template Add<i32>(); @@ -2693,154 +2671,155 @@ private: } }; - template<size_t Digits, bool Trailing = true, bool Leading = true> - struct PrintNDigits; +template <size_t Digits, bool Trailing = true, bool Leading = true> +struct PrintNDigits; - template<bool Trailing, bool Leading> - struct PrintNDigits<0U, Trailing, Leading> { - static constexpr ui32 Miltiplier = 1U; +template <bool Trailing, bool Leading> +struct PrintNDigits<0U, Trailing, Leading> { + static constexpr ui32 Miltiplier = 1U; - template <typename T> - static constexpr size_t Do(T, char*) { return 0U; } - }; + template <typename T> + static constexpr size_t Do(T, char*) { + return 0U; + } +}; - template<size_t Digits, bool Trailing, bool Leading> - struct PrintNDigits { - using TNextNoLeadPrint = PrintNDigits<Digits - 1U, Trailing, false>; - using TNextCommonPrint = PrintNDigits<Digits - 1U, Trailing, true>; - static_assert(TNextNoLeadPrint::Miltiplier == TNextCommonPrint::Miltiplier); - static constexpr ui32 Miltiplier = TNextCommonPrint::Miltiplier * 10U; - - template <typename T> - static constexpr size_t Do(T in, char* out) { - in %= Miltiplier; - if (!Trailing && in == 0) { - return 0U; - } - const auto digit = in / TNextCommonPrint::Miltiplier; - if (!Leading && digit == 0) { - return TNextNoLeadPrint::Do(in, out); - } - *out = "0123456789"[digit]; - return 1U + TNextCommonPrint::Do(in, ++out); - } - }; +template <size_t Digits, bool Trailing, bool Leading> +struct PrintNDigits { + using TNextNoLeadPrint = PrintNDigits<Digits - 1U, Trailing, false>; + using TNextCommonPrint = PrintNDigits<Digits - 1U, Trailing, true>; + static_assert(TNextNoLeadPrint::Miltiplier == TNextCommonPrint::Miltiplier); + static constexpr ui32 Miltiplier = TNextCommonPrint::Miltiplier * 10U; - // Format + template <typename T> + static constexpr size_t Do(T in, char* out) { + in %= Miltiplier; + if (!Trailing && in == 0) { + return 0U; + } + const auto digit = in / TNextCommonPrint::Miltiplier; + if (!Leading && digit == 0) { + return TNextNoLeadPrint::Do(in, out); + } + *out = "0123456789"[digit]; + return 1U + TNextCommonPrint::Do(in, ++out); + } +}; - class TFormat : public TBoxedValue { - public: - explicit TFormat(TSourcePosition pos) - : Pos_(pos) - {} +// Format - static const TStringRef& Name() { - static auto name = TStringRef::Of("Format"); - return name; - } +class TFormat: public TBoxedValue { +public: + explicit TFormat(TSourcePosition pos) + : Pos_(pos) + { + } - static bool DeclareSignature( - const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) - { - if (Name() != name) { - return false; - } + static const TStringRef& Name() { + static auto name = TStringRef::Of("Format"); + return name; + } - builder.OptionalArgs(1).Args()->Add<char*>() - .Add<TOptional<bool>>().Name("AlwaysWriteFractionalSeconds"); - builder.Returns( - builder.SimpleSignatureType<char*(TAutoMap<TResource<TM64ResourceName>>)>()); - if (!typesOnly) { - builder.Implementation(new TFormat(builder.GetSourcePosition())); - } + static bool DeclareSignature( + const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) + { + if (Name() != name) { + return false; + } - return true; + builder.OptionalArgs(1).Args()->Add<char*>().Add<TOptional<bool>>().Name("AlwaysWriteFractionalSeconds"); + builder.Returns( + builder.SimpleSignatureType<char*(TAutoMap<TResource<TM64ResourceName>>)>()); + if (!typesOnly) { + builder.Implementation(new TFormat(builder.GetSourcePosition())); } - private: - using TPrintersList = std::vector<std::function<size_t(char*, const TUnboxedValuePod&, const IDateBuilder&)>>; + return true; + } - struct TDataPrinter { - const std::string_view Data; +private: + using TPrintersList = std::vector<std::function<size_t(char*, const TUnboxedValuePod&, const IDateBuilder&)>>; - size_t operator()(char* out, const TUnboxedValuePod&, const IDateBuilder&) const { - std::memcpy(out, Data.data(), Data.size()); - return Data.size(); - } - }; + struct TDataPrinter { + const std::string_view Data; - TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try { - bool alwaysWriteFractionalSeconds = false; - if (auto val = args[1]) { - alwaysWriteFractionalSeconds = val.Get<bool>(); - } + size_t operator()(char* out, const TUnboxedValuePod&, const IDateBuilder&) const { + std::memcpy(out, Data.data(), Data.size()); + return Data.size(); + } + }; - return TUnboxedValuePod(new TImpl(Pos_, args[0], alwaysWriteFractionalSeconds)); - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); + TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try { + bool alwaysWriteFractionalSeconds = false; + if (auto val = args[1]) { + alwaysWriteFractionalSeconds = val.Get<bool>(); } - class TImpl : public TBoxedValue { - public: - TUnboxedValue Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); - const auto value = args[0]; + return TUnboxedValuePod(new TImpl(Pos_, args[0], alwaysWriteFractionalSeconds)); + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); + } - auto& builder = valueBuilder->GetDateBuilder(); + class TImpl: public TBoxedValue { + public: + TUnboxedValue Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); + const auto value = args[0]; - auto result = valueBuilder->NewStringNotFilled(ReservedSize_); - auto pos = result.AsStringRef().Data(); - ui32 size = 0U; + auto& builder = valueBuilder->GetDateBuilder(); - for (const auto& printer : Printers_) { - if (const auto plus = printer(pos, value, builder)) { - size += plus; - pos += plus; - } - } + auto result = valueBuilder->NewStringNotFilled(ReservedSize_); + auto pos = result.AsStringRef().Data(); + ui32 size = 0U; - if (size < ReservedSize_) { - result = valueBuilder->SubString(result.Release(), 0U, size); + for (const auto& printer : Printers_) { + if (const auto plus = printer(pos, value, builder)) { + size += plus; + pos += plus; } + } - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); + if (size < ReservedSize_) { + result = valueBuilder->SubString(result.Release(), 0U, size); } + + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } + } - TImpl(TSourcePosition pos, TUnboxedValue format, bool alwaysWriteFractionalSeconds) - : Pos_(pos) - , Format_(format) - { - const std::string_view formatView(Format_.AsStringRef()); - auto dataStart = formatView.begin(); - size_t dataSize = 0U; - - for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) { - if (*ptr != '%') { - ++dataSize; - continue; - } + TImpl(TSourcePosition pos, TUnboxedValue format, bool alwaysWriteFractionalSeconds) + : Pos_(pos) + , Format_(format) + { + const std::string_view formatView(Format_.AsStringRef()); + auto dataStart = formatView.begin(); + size_t dataSize = 0U; - if (dataSize) { - Printers_.emplace_back(TDataPrinter{std::string_view(&*dataStart, dataSize)}); - ReservedSize_ += dataSize; - dataSize = 0U; - } + for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) { + if (*ptr != '%') { + ++dataSize; + continue; + } - if (formatView.end() == ++ptr) { - ythrow yexception() << "format string ends with single %%"; - } + if (dataSize) { + Printers_.emplace_back(TDataPrinter{std::string_view(&*dataStart, dataSize)}); + ReservedSize_ += dataSize; + dataSize = 0U; + } + + if (formatView.end() == ++ptr) { + ythrow yexception() << "format string ends with single %%"; + } - switch (*ptr) { + switch (*ptr) { case '%': { static constexpr size_t size = 1; Printers_.emplace_back([](char* out, const TUnboxedValuePod&, const IDateBuilder&) { @@ -2904,9 +2883,7 @@ private: out += PrintNDigits<size>::Do(GetSecond<TM64ResourceName>(value), out); *out++ = '.'; constexpr size_t msize = 6; - auto addSz = alwaysWriteFractionalSeconds ? - PrintNDigits<msize, true>::Do(microsecond, out) : - PrintNDigits<msize, false>::Do(microsecond, out); + auto addSz = alwaysWriteFractionalSeconds ? PrintNDigits<msize, true>::Do(microsecond, out) : PrintNDigits<msize, false>::Do(microsecond, out); return size + 1U + addSz; } return PrintNDigits<size>::Do(GetSecond<TM64ResourceName>(value), out); @@ -2956,7 +2933,7 @@ private: case 'b': { static constexpr size_t size = 3; Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) { - static constexpr std::string_view mp[] { + static constexpr std::string_view mp[]{ "Jan", "Feb", "Mar", @@ -2968,8 +2945,7 @@ private: "Sep", "Oct", "Nov", - "Dec" - }; + "Dec"}; auto month = GetMonth<TM64ResourceName>(value); Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value"); std::memcpy(out, mp[month - 1].data(), size); @@ -2980,7 +2956,7 @@ private: } case 'B': { Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) { - static constexpr std::string_view mp[] { + static constexpr std::string_view mp[]{ "January", "February", "March", @@ -2992,8 +2968,7 @@ private: "September", "October", "November", - "December" - }; + "December"}; auto month = GetMonth<TM64ResourceName>(value); Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value"); const std::string_view monthFullName = mp[month - 1]; @@ -3006,181 +2981,180 @@ private: default: throw yexception() << "character '" << *ptr << "' is not a valid format specifier." << "\nSee documentation for valid format characters"; - } - - dataStart = ptr + 1U; } - if (dataSize) { - Printers_.emplace_back(TDataPrinter{std::string_view(dataStart, dataSize)}); - ReservedSize_ += dataSize; - } + dataStart = ptr + 1U; } - private: - const TSourcePosition Pos_; - - TUnboxedValue Format_; - TPrintersList Printers_{}; - size_t ReservedSize_ = 0; - }; + if (dataSize) { + Printers_.emplace_back(TDataPrinter{std::string_view(dataStart, dataSize)}); + ReservedSize_ += dataSize; + } + } + private: const TSourcePosition Pos_; + + TUnboxedValue Format_; + TPrintersList Printers_{}; + size_t ReservedSize_ = 0; }; - template<size_t Digits, bool Variable = false> - struct ParseNDigits; + const TSourcePosition Pos_; +}; - template<bool Variable> - struct ParseNDigits<0U, Variable> { - template <typename T> - static constexpr bool Do(std::string_view::const_iterator&, T&) { - return true; - } - }; +template <size_t Digits, bool Variable = false> +struct ParseNDigits; - template<size_t Digits, bool Variable> - struct ParseNDigits { - template <typename T> - static constexpr bool Do(std::string_view::const_iterator& it, T& out) { - const auto d = *it; - if (!std::isdigit(d)) { - // XXX: If the current char is not a digit, the - // parsing succeeds iff there are no more digits - // to be parsed (see the class specialization - // above) or there are given less than N digits - // to be parsed. - if constexpr (Variable) { - return true; - } - return false; +template <bool Variable> +struct ParseNDigits<0U, Variable> { + template <typename T> + static constexpr bool Do(std::string_view::const_iterator&, T&) { + return true; + } +}; + +template <size_t Digits, bool Variable> +struct ParseNDigits { + template <typename T> + static constexpr bool Do(std::string_view::const_iterator& it, T& out) { + const auto d = *it; + if (!std::isdigit(d)) { + // XXX: If the current char is not a digit, the + // parsing succeeds iff there are no more digits + // to be parsed (see the class specialization + // above) or there are given less than N digits + // to be parsed. + if constexpr (Variable) { + return true; } - out *= 10U; - out += d - '0'; - return ParseNDigits<Digits - 1U, Variable>::Do(++it, out); + return false; } - }; + out *= 10U; + out += d - '0'; + return ParseNDigits<Digits - 1U, Variable>::Do(++it, out); + } +}; - // Parse +// Parse - template<const char* TUdfName, const char* TResourceName> - class TParse : public TBoxedValue { +template <const char* TUdfName, const char* TResourceName> +class TParse: public TBoxedValue { +public: + class TFactory: public TBoxedValue { public: - class TFactory : public TBoxedValue { - public: - explicit TFactory(TSourcePosition pos) - : Pos_(pos) - {} - - private: - TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try { - return TUnboxedValuePod(new TParse(args[0], Pos_)); - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); - } - - const TSourcePosition Pos_; - }; + explicit TFactory(TSourcePosition pos) + : Pos_(pos) + { + } - static const TStringRef& Name() { - static auto name = TStringRef(TUdfName, std::strlen(TUdfName)); - return name; + private: + TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try { + return TUnboxedValuePod(new TParse(args[0], Pos_)); + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } - static bool DeclareSignature( - const TStringRef& name, - TType*, - IFunctionTypeInfoBuilder& builder, - bool typesOnly) - { - if (Name() != name) { - return false; - } + const TSourcePosition Pos_; + }; - builder.OptionalArgs(1).Args()->Add<char*>() - .template Add<TOptional<ui16>>(); - builder.Returns( - builder.SimpleSignatureType<TOptional<TResource<TResourceName>>(TAutoMap<char*>)>()); - if (!typesOnly) { - builder.Implementation(new TParse::TFactory(builder.GetSourcePosition())); - } + static const TStringRef& Name() { + static auto name = TStringRef(TUdfName, std::strlen(TUdfName)); + return name; + } - return true; + static bool DeclareSignature( + const TStringRef& name, + TType*, + IFunctionTypeInfoBuilder& builder, + bool typesOnly) + { + if (Name() != name) { + return false; } - private: - const TSourcePosition Pos_; - const TUnboxedValue Format_; + builder.OptionalArgs(1).Args()->Add<char*>().template Add<TOptional<ui16>>(); + builder.Returns( + builder.SimpleSignatureType<TOptional<TResource<TResourceName>>(TAutoMap<char*>)>()); + if (!typesOnly) { + builder.Implementation(new TParse::TFactory(builder.GetSourcePosition())); + } - std::vector<std::function<bool(std::string_view::const_iterator& it, size_t, TUnboxedValuePod&, const IDateBuilder&)>> Scanners_; + return true; + } - struct TDataScanner { - const std::string_view Data; +private: + const TSourcePosition Pos_; + const TUnboxedValue Format_; - bool operator()(std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) const { - if (limit < Data.size() || !std::equal(Data.begin(), Data.end(), it)) { - return false; - } - std::advance(it, Data.size()); - return true; - } - }; + std::vector<std::function<bool(std::string_view::const_iterator& it, size_t, TUnboxedValuePod&, const IDateBuilder&)>> Scanners_; - TUnboxedValue Run( - const IValueBuilder* valueBuilder, - const TUnboxedValuePod* args) const override - { - try { - EMPTY_RESULT_ON_EMPTY_ARG(0); + struct TDataScanner { + const std::string_view Data; + + bool operator()(std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) const { + if (limit < Data.size() || !std::equal(Data.begin(), Data.end(), it)) { + return false; + } + std::advance(it, Data.size()); + return true; + } + }; - const std::string_view buffer = args[0].AsStringRef(); + TUnboxedValue Run( + const IValueBuilder* valueBuilder, + const TUnboxedValuePod* args) const override { + try { + EMPTY_RESULT_ON_EMPTY_ARG(0); - TUnboxedValuePod result(0); - auto& storage = Reference<TResourceName>(result); - storage.MakeDefault(); + const std::string_view buffer = args[0].AsStringRef(); - auto& builder = valueBuilder->GetDateBuilder(); + TUnboxedValuePod result(0); + auto& storage = Reference<TResourceName>(result); + storage.MakeDefault(); - auto it = buffer.begin(); - for (const auto& scanner : Scanners_) { - if (!scanner(it, std::distance(it, buffer.end()), result, builder)) { - return TUnboxedValuePod(); - } - } + auto& builder = valueBuilder->GetDateBuilder(); - if (buffer.end() != it || !storage.Validate(builder)) { + auto it = buffer.begin(); + for (const auto& scanner : Scanners_) { + if (!scanner(it, std::distance(it, buffer.end()), result, builder)) { return TUnboxedValuePod(); } - return result; - } catch (const std::exception& e) { - UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } + + if (buffer.end() != it || !storage.Validate(builder)) { + return TUnboxedValuePod(); + } + return result; + } catch (const std::exception& e) { + UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).c_str()); } + } - TParse(const TUnboxedValuePod& runConfig, TSourcePosition pos) - : Pos_(pos) - , Format_(runConfig) - { - const std::string_view formatView(Format_.AsStringRef()); - auto dataStart = formatView.begin(); - size_t dataSize = 0U; + TParse(const TUnboxedValuePod& runConfig, TSourcePosition pos) + : Pos_(pos) + , Format_(runConfig) + { + const std::string_view formatView(Format_.AsStringRef()); + auto dataStart = formatView.begin(); + size_t dataSize = 0U; - for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) { - if (*ptr != '%') { - ++dataSize; - continue; - } + for (auto ptr = formatView.begin(); formatView.end() != ptr; ++ptr) { + if (*ptr != '%') { + ++dataSize; + continue; + } - if (dataSize) { - Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)}); - dataSize = 0; - } + if (dataSize) { + Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)}); + dataSize = 0; + } - if (++ptr == formatView.end()) { - ythrow yexception() << "format string ends with single %%"; - } + if (++ptr == formatView.end()) { + ythrow yexception() << "format string ends with single %%"; + } - switch (*ptr) { + switch (*ptr) { case '%': Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) { return limit > 0U && *it++ == '%'; @@ -3313,7 +3287,8 @@ private: ++it; --digits; } - for (; !digits && limit && std::isdigit(*it); --limit, ++it); + for (; !digits && limit && std::isdigit(*it); --limit, ++it) + ; while (digits--) { usec *= 10U; } @@ -3381,16 +3356,16 @@ private: } default: ythrow yexception() << "invalid format character: " << *ptr; - } - - dataStart = ptr + 1U; } - if (dataSize) { - Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)}); - } + dataStart = ptr + 1U; } - }; + + if (dataSize) { + Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)}); + } + } +}; #define PARSE_SPECIFIC_FORMAT(format) \ SIMPLE_STRICT_UDF(TParse##format, TOptional<TResource<TMResourceName>>(TAutoMap<char*>)) { \ @@ -3406,140 +3381,139 @@ private: return result; \ } - PARSE_SPECIFIC_FORMAT(Rfc822); - PARSE_SPECIFIC_FORMAT(Iso8601); - PARSE_SPECIFIC_FORMAT(Http); - PARSE_SPECIFIC_FORMAT(X509); - - SIMPLE_MODULE(TDateTime2Module, - TUserDataTypeFuncFactory<true, true, SplitUDF, TSplit, - TDate, - TDatetime, - TTimestamp, - TTzDate, - TTzDatetime, - TTzTimestamp, - TDate32, - TDatetime64, - TTimestamp64, - TTzDate32, - TTzDatetime64, - TTzTimestamp64>, - - TMakeDate, - TMakeDatetime, - TMakeTimestamp, - TMakeTzDate, - TMakeTzDatetime, - TMakeTzTimestamp, - - TConvert, - - TMakeDate32, - TMakeDatetime64, - TMakeTimestamp64, - TMakeTzDate32, - TMakeTzDatetime64, - TMakeTzTimestamp64, - - TGetDateComponent<GetYearUDF, ui16, GetYear<TMResourceName>, i32, GetYear<TM64ResourceName>>, - TGetDateComponent<GetDayOfYearUDF, ui16, GetDayOfYear<TMResourceName>, ui16, GetDayOfYear<TM64ResourceName>>, - TGetDateComponent<GetMonthUDF, ui8, GetMonth<TMResourceName>, ui8, GetMonth<TM64ResourceName>>, - TGetDateComponentName<GetMonthNameUDF, GetMonthName<TMResourceName>, GetMonthName<TM64ResourceName>>, - TGetDateComponent<GetWeekOfYearUDF, ui8, GetWeekOfYear<TMResourceName>, ui8, GetWeekOfYear<TM64ResourceName>>, - TGetDateComponent<GetWeekOfYearIso8601UDF, ui8, GetWeekOfYearIso8601<TMResourceName>, ui8, GetWeekOfYearIso8601<TM64ResourceName>>, - TGetDateComponent<GetDayOfMonthUDF, ui8, GetDay<TMResourceName>, ui8, GetDay<TM64ResourceName>>, - TGetDateComponent<GetDayOfWeekUDF, ui8, GetDayOfWeek<TMResourceName>, ui8, GetDayOfWeek<TM64ResourceName>>, - TGetDateComponentName<GetDayOfWeekNameUDF, GetDayOfWeekName<TMResourceName>, GetDayOfWeekName<TM64ResourceName>>, - TGetTimeComponent<GetHourUDF, ui8, GetHour<TMResourceName>, GetHour<TM64ResourceName>, 1u, 3600u, 24u, false>, - TGetTimeComponent<GetMinuteUDF, ui8, GetMinute<TMResourceName>, GetMinute<TM64ResourceName>, 1u, 60u, 60u, false>, - TGetTimeComponent<GetSecondUDF, ui8, GetSecond<TMResourceName>, GetSecond<TM64ResourceName>, 1u, 1u, 60u, false>, - TGetTimeComponent<GetMillisecondOfSecondUDF, ui32, GetMicrosecond<TMResourceName>, GetMicrosecond<TM64ResourceName>, 1000u, 1000u, 1000u, true>, - TGetTimeComponent<GetMicrosecondOfSecondUDF, ui32, GetMicrosecond<TMResourceName>, GetMicrosecond<TM64ResourceName>, 1u, 1u, 1000000u, true>, - TGetDateComponent<GetTimezoneIdUDF, ui16, GetTimezoneId<TMResourceName>, ui16, GetTimezoneId<TM64ResourceName>>, - TGetDateComponentName<GetTimezoneNameUDF, GetTimezoneName<TMResourceName>, GetTimezoneName<TM64ResourceName>>, - - TUpdate, - - TFromSeconds, - TFromMilliseconds, - TFromMicroseconds, - - TFromSeconds64, - TFromMilliseconds64, - TFromMicroseconds64, - - TIntervalFromDays, - TIntervalFromHours, - TIntervalFromMinutes, - - TLangVerForked< - NYql::MakeLangVersion(2025, 03), - NLegacy::TIntervalFromSeconds, - NActual::TIntervalFromSeconds>, - - TIntervalFromMilliseconds, - TIntervalFromMicroseconds, - - TInterval64FromDays, - TInterval64FromHours, - TInterval64FromMinutes, - TInterval64FromSeconds, - TInterval64FromMilliseconds, - TInterval64FromMicroseconds, - - TToConverter<ToDaysUDF, i32, i32, UsecondsInDay>, - TToConverter<ToHoursUDF, i32, i64, UsecondsInHour>, - TToConverter<ToMinutesUDF, i32, i64, UsecondsInMinute>, - - TBoundaryOf<StartOfYearUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfYear<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfYear<TTM64Storage>>>, - TBoundaryOf<StartOfQuarterUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfQuarter<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfQuarter<TTM64Storage>>>, - TBoundaryOf<StartOfMonthUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfMonth<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfMonth<TTM64Storage>>>, - TBoundaryOf<StartOfWeekUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfWeek<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfWeek<TTM64Storage>>>, - TBoundaryOf<StartOfDayUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfDay<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfDay<TTM64Storage>>>, - TBoundaryOfInterval<StartOfUDF, SimpleDatetimeToIntervalUdf<TMResourceName, StartOf<TTMStorage>>, - SimpleDatetimeToIntervalUdf<TM64ResourceName, StartOf<TTM64Storage>>>, - TTimeOfDay, - - TShift<ShiftYearsUDF, DoAddYears<TMResourceName>, DoAddYears<TM64ResourceName>>, - TShift<ShiftQuartersUDF, DoAddQuarters<TMResourceName>, DoAddQuarters<TM64ResourceName>>, - TShift<ShiftMonthsUDF, DoAddMonths<TMResourceName>, DoAddMonths<TM64ResourceName>>, - - TBoundaryOf<EndOfYearUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfYear<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfYear<TTM64Storage>>>, - TBoundaryOf<EndOfQuarterUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfQuarter<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfQuarter<TTM64Storage>>>, - TBoundaryOf<EndOfMonthUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfMonth<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfMonth<TTM64Storage>>>, - TBoundaryOf<EndOfWeekUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfWeek<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfWeek<TTM64Storage>>>, - TBoundaryOf<EndOfDayUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfDay<TTMStorage>>, - SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfDay<TTM64Storage>>>, - TBoundaryOfInterval<EndOfUDF, SimpleDatetimeToIntervalUdf<TMResourceName, EndOf<TTMStorage>>, - SimpleDatetimeToIntervalUdf<TM64ResourceName, EndOf<TTM64Storage>>>, - - TLangVerForked< - NYql::MakeLangVersion(2025, 03), - TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i32, /* TWResult = */ i64, 1>, - TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i64, /* TWResult = */ i64, 1>>, - - TToUnits<ToMillisecondsUDF, /* TResult = */ ui64, /* TSignedResult = */ i64, /* TWResult = */ i64, 1000>, - TToUnits<ToMicrosecondsUDF, /* TResult = */ ui64, /* TSignedResult = */ i64, /* TWResult = */ i64, 1000000>, - - TFormat, - TParse<ParseUDF, TMResourceName>, - TParse<Parse64UDF, TM64ResourceName>, - - TParseRfc822, - TParseIso8601, - TParseHttp, - TParseX509 - ) -} +PARSE_SPECIFIC_FORMAT(Rfc822); +PARSE_SPECIFIC_FORMAT(Iso8601); +PARSE_SPECIFIC_FORMAT(Http); +PARSE_SPECIFIC_FORMAT(X509); + +SIMPLE_MODULE(TDateTime2Module, + TUserDataTypeFuncFactory<true, true, SplitUDF, TSplit, + TDate, + TDatetime, + TTimestamp, + TTzDate, + TTzDatetime, + TTzTimestamp, + TDate32, + TDatetime64, + TTimestamp64, + TTzDate32, + TTzDatetime64, + TTzTimestamp64>, + + TMakeDate, + TMakeDatetime, + TMakeTimestamp, + TMakeTzDate, + TMakeTzDatetime, + TMakeTzTimestamp, + + TConvert, + + TMakeDate32, + TMakeDatetime64, + TMakeTimestamp64, + TMakeTzDate32, + TMakeTzDatetime64, + TMakeTzTimestamp64, + + TGetDateComponent<GetYearUDF, ui16, GetYear<TMResourceName>, i32, GetYear<TM64ResourceName>>, + TGetDateComponent<GetDayOfYearUDF, ui16, GetDayOfYear<TMResourceName>, ui16, GetDayOfYear<TM64ResourceName>>, + TGetDateComponent<GetMonthUDF, ui8, GetMonth<TMResourceName>, ui8, GetMonth<TM64ResourceName>>, + TGetDateComponentName<GetMonthNameUDF, GetMonthName<TMResourceName>, GetMonthName<TM64ResourceName>>, + TGetDateComponent<GetWeekOfYearUDF, ui8, GetWeekOfYear<TMResourceName>, ui8, GetWeekOfYear<TM64ResourceName>>, + TGetDateComponent<GetWeekOfYearIso8601UDF, ui8, GetWeekOfYearIso8601<TMResourceName>, ui8, GetWeekOfYearIso8601<TM64ResourceName>>, + TGetDateComponent<GetDayOfMonthUDF, ui8, GetDay<TMResourceName>, ui8, GetDay<TM64ResourceName>>, + TGetDateComponent<GetDayOfWeekUDF, ui8, GetDayOfWeek<TMResourceName>, ui8, GetDayOfWeek<TM64ResourceName>>, + TGetDateComponentName<GetDayOfWeekNameUDF, GetDayOfWeekName<TMResourceName>, GetDayOfWeekName<TM64ResourceName>>, + TGetTimeComponent<GetHourUDF, ui8, GetHour<TMResourceName>, GetHour<TM64ResourceName>, 1u, 3600u, 24u, false>, + TGetTimeComponent<GetMinuteUDF, ui8, GetMinute<TMResourceName>, GetMinute<TM64ResourceName>, 1u, 60u, 60u, false>, + TGetTimeComponent<GetSecondUDF, ui8, GetSecond<TMResourceName>, GetSecond<TM64ResourceName>, 1u, 1u, 60u, false>, + TGetTimeComponent<GetMillisecondOfSecondUDF, ui32, GetMicrosecond<TMResourceName>, GetMicrosecond<TM64ResourceName>, 1000u, 1000u, 1000u, true>, + TGetTimeComponent<GetMicrosecondOfSecondUDF, ui32, GetMicrosecond<TMResourceName>, GetMicrosecond<TM64ResourceName>, 1u, 1u, 1000000u, true>, + TGetDateComponent<GetTimezoneIdUDF, ui16, GetTimezoneId<TMResourceName>, ui16, GetTimezoneId<TM64ResourceName>>, + TGetDateComponentName<GetTimezoneNameUDF, GetTimezoneName<TMResourceName>, GetTimezoneName<TM64ResourceName>>, + + TUpdate, + + TFromSeconds, + TFromMilliseconds, + TFromMicroseconds, + + TFromSeconds64, + TFromMilliseconds64, + TFromMicroseconds64, + + TIntervalFromDays, + TIntervalFromHours, + TIntervalFromMinutes, + + TLangVerForked< + NYql::MakeLangVersion(2025, 03), + NLegacy::TIntervalFromSeconds, + NActual::TIntervalFromSeconds>, + + TIntervalFromMilliseconds, + TIntervalFromMicroseconds, + + TInterval64FromDays, + TInterval64FromHours, + TInterval64FromMinutes, + TInterval64FromSeconds, + TInterval64FromMilliseconds, + TInterval64FromMicroseconds, + + TToConverter<ToDaysUDF, i32, i32, UsecondsInDay>, + TToConverter<ToHoursUDF, i32, i64, UsecondsInHour>, + TToConverter<ToMinutesUDF, i32, i64, UsecondsInMinute>, + + TBoundaryOf<StartOfYearUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfYear<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfYear<TTM64Storage>>>, + TBoundaryOf<StartOfQuarterUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfQuarter<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfQuarter<TTM64Storage>>>, + TBoundaryOf<StartOfMonthUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfMonth<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfMonth<TTM64Storage>>>, + TBoundaryOf<StartOfWeekUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfWeek<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfWeek<TTM64Storage>>>, + TBoundaryOf<StartOfDayUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, StartOfDay<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, StartOfDay<TTM64Storage>>>, + TBoundaryOfInterval<StartOfUDF, SimpleDatetimeToIntervalUdf<TMResourceName, StartOf<TTMStorage>>, + SimpleDatetimeToIntervalUdf<TM64ResourceName, StartOf<TTM64Storage>>>, + TTimeOfDay, + + TShift<ShiftYearsUDF, DoAddYears<TMResourceName>, DoAddYears<TM64ResourceName>>, + TShift<ShiftQuartersUDF, DoAddQuarters<TMResourceName>, DoAddQuarters<TM64ResourceName>>, + TShift<ShiftMonthsUDF, DoAddMonths<TMResourceName>, DoAddMonths<TM64ResourceName>>, + + TBoundaryOf<EndOfYearUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfYear<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfYear<TTM64Storage>>>, + TBoundaryOf<EndOfQuarterUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfQuarter<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfQuarter<TTM64Storage>>>, + TBoundaryOf<EndOfMonthUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfMonth<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfMonth<TTM64Storage>>>, + TBoundaryOf<EndOfWeekUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfWeek<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfWeek<TTM64Storage>>>, + TBoundaryOf<EndOfDayUDF, SimpleDatetimeToDatetimeUdf<TMResourceName, EndOfDay<TTMStorage>>, + SimpleDatetimeToDatetimeUdf<TM64ResourceName, EndOfDay<TTM64Storage>>>, + TBoundaryOfInterval<EndOfUDF, SimpleDatetimeToIntervalUdf<TMResourceName, EndOf<TTMStorage>>, + SimpleDatetimeToIntervalUdf<TM64ResourceName, EndOf<TTM64Storage>>>, + + TLangVerForked< + NYql::MakeLangVersion(2025, 03), + TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i32, /* TWResult = */ i64, 1>, + TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i64, /* TWResult = */ i64, 1>>, + + TToUnits<ToMillisecondsUDF, /* TResult = */ ui64, /* TSignedResult = */ i64, /* TWResult = */ i64, 1000>, + TToUnits<ToMicrosecondsUDF, /* TResult = */ ui64, /* TSignedResult = */ i64, /* TWResult = */ i64, 1000000>, + + TFormat, + TParse<ParseUDF, TMResourceName>, + TParse<Parse64UDF, TM64ResourceName>, + + TParseRfc822, + TParseIso8601, + TParseHttp, + TParseX509) +} // namespace REGISTER_MODULES(TDateTime2Module) |