1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440 |
- #include <yql/essentials/minikql/mkql_type_ops.h>
- #include <yql/essentials/public/udf/tz/udf_tz.h>
- #include <yql/essentials/public/udf/udf_helpers.h>
- #include <yql/essentials/minikql/datetime/datetime.h>
- #include <yql/essentials/minikql/datetime/datetime64.h>
- #include <yql/essentials/public/udf/arrow/udf_arrow_helpers.h>
- #include <util/datetime/base.h>
- using namespace NKikimr;
- using namespace NUdf;
- using namespace NYql::DateTime;
- extern const char SplitName[] = "Split";
- extern const char ToSecondsName[] = "ToSeconds";
- extern const char ToMillisecondsName[] = "ToMilliseconds";
- extern const char ToMicrosecondsName[] = "ToMicroseconds";
- extern const char GetHourName[] = "GetHour";
- extern const char GetMinuteName[] = "GetMinute";
- extern const char GetSecondName[] = "GetSecond";
- extern const char GetMillisecondOfSecondName[] = "GetMillisecondOfSecond";
- extern const char GetMicrosecondOfSecondName[] = "GetMicrosecondOfSecond";
- extern const char TMResourceName[] = "DateTime2.TM";
- extern const char TM64ResourceName[] = "DateTime2.TM64";
- const auto UsecondsInDay = 86400000000ll;
- const auto UsecondsInHour = 3600000000ll;
- const auto UsecondsInMinute = 60000000ll;
- const auto UsecondsInSecond = 1000000ll;
- const auto UsecondsInMilliseconds = 1000ll;
- template <const char* TFuncName, typename TResult, ui32 ScaleAfterSeconds>
- class TToUnits {
- public:
- typedef bool TTypeAwareMarker;
- using TSignedResult = typename std::make_signed<TResult>::type;
- static TResult DateCore(ui16 value) {
- return value * ui32(86400) * TResult(ScaleAfterSeconds);
- }
- template<typename TTzDate>
- static TResult TzBlockCore(TBlockItem tzDate);
- template<>
- static TResult TzBlockCore<TTzDate>(TBlockItem tzDate) {
- return DateCore(tzDate.Get<ui16>());
- }
- template<>
- static TResult TzBlockCore<TTzDatetime>(TBlockItem tzDate) {
- return DatetimeCore(tzDate.Get<ui32>());
- }
- template<>
- static TResult TzBlockCore<TTzTimestamp>(TBlockItem tzDate) {
- return TimestampCore(tzDate.Get<ui64>());
- }
- static TResult DatetimeCore(ui32 value) {
- return value * TResult(ScaleAfterSeconds);
- }
- static TResult TimestampCore(ui64 value) {
- return TResult(value / (1000000u / ScaleAfterSeconds));
- }
- static TSignedResult IntervalCore(i64 value) {
- return TSignedResult(value / (1000000u / ScaleAfterSeconds));
- }
- static const TStringRef& Name() {
- static auto name = TStringRef(TFuncName, std::strlen(TFuncName));
- return name;
- }
- template<typename TTzDate, typename TOutput>
- static auto MakeTzBlockExec() {
- using TReader = TTzDateBlockReader<TTzDate, /*Nullable*/ false>;
- return UnaryPreallocatedReaderExecImpl<TReader, TOutput, TzBlockCore<TTzDate>>;
- }
- static bool DeclareSignature(
- const TStringRef& name,
- TType* userType,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly)
- {
- if (Name() != name) {
- return false;
- }
- try {
- 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);
- if (argsTuple.GetElementsCount() != 1) {
- builder.SetError("Expected one argument");
- return true;
- }
- auto argType = argsTuple.GetElementType(0);
- TVector<const TType*> argBlockTypes;
- argBlockTypes.push_back(argType);
- TBlockTypeInspector block(*typeInfoHelper, argType);
- if (block) {
- Y_ENSURE(!block.IsScalar());
- argType = block.GetItemType();
- }
- bool isOptional = false;
- if (auto opt = TOptionalTypeInspector(*typeInfoHelper, argType)) {
- argType = opt.GetItemType();
- isOptional = true;
- }
- TDataTypeInspector data(*typeInfoHelper, argType);
- if (!data) {
- builder.SetError("Expected data type");
- return true;
- }
- auto typeId = data.GetTypeId();
- if (!(typeId == TDataType<TDate>::Id || typeId == TDataType<TTzDate>::Id ||
- typeId == TDataType<TDatetime>::Id || typeId == TDataType<TTzDatetime>::Id ||
- typeId == TDataType<TTimestamp>::Id || typeId == TDataType<TTzTimestamp>::Id ||
- typeId == TDataType<TInterval>::Id)) {
- builder.SetError(TStringBuilder() << "Type " << GetDataTypeInfo(GetDataSlot(typeId)).Name << " is not supported");
- }
- builder.Args()->Add(argsTuple.GetElementType(0)).Done();
- const TType* retType;
- if (typeId != TDataType<TInterval>::Id) {
- retType = builder.SimpleType<TResult>();
- } else {
- retType = builder.SimpleType<TSignedResult>();
- }
- if (isOptional) {
- retType = builder.Optional()->Item(retType).Build();
- }
- auto outputType = retType;
- if (block) {
- retType = builder.Block(block.IsScalar())->Item(retType).Build();
- }
- builder.Returns(retType);
- builder.SupportsBlocks();
- builder.IsStrict();
- builder.UserType(userType);
- if (!typesOnly) {
- 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>;
- builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(),
- exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui16, TResult, DateCore>());
- }
- }
- 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>;
- builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(),
- exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui32, TResult, DatetimeCore>());
- }
- }
- 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>;
- builder.Implementation(new TSimpleArrowUdfImpl(argBlockTypes, outputType, block.IsScalar(),
- exec, builder, TString(name), arrow::compute::NullHandling::INTERSECTION));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui64, TResult, TimestampCore>());
- }
- }
- 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));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<i64, TSignedResult, IntervalCore>());
- }
- }
- }
- } catch (const std::exception& e) {
- builder.SetError(TStringBuf(e.what()));
- }
- return true;
- }
- };
- template <const char* TFuncName, typename TFieldStorage, TFieldStorage (*FieldFunc)(const TUnboxedValuePod&), ui32 Divisor, ui32 Scale, ui32 Limit, bool Fractional>
- struct TGetTimeComponent {
- typedef bool TTypeAwareMarker;
- template <typename TInput, bool AlwaysZero, bool InputFractional>
- static TFieldStorage Core(TInput val) {
- if constexpr (AlwaysZero) {
- return 0;
- }
- if constexpr (InputFractional) {
- if constexpr (Fractional) {
- return (val / Scale) % Limit;
- } else {
- return (val / 1000000u / Scale) % Limit;
- }
- } else {
- if constexpr (Fractional) {
- return 0;
- } else {
- return (val / Scale) % Limit;
- }
- }
- }
- class TImpl : public TBoxedValue {
- public:
- TUnboxedValue Run(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) const final {
- Y_UNUSED(valueBuilder);
- if (!args[0]) {
- return {};
- }
- return TUnboxedValuePod(TFieldStorage((FieldFunc(args[0])) / Divisor));
- }
- };
- static const TStringRef& Name() {
- static auto name = TStringRef(TFuncName, std::strlen(TFuncName));
- return name;
- }
- static bool DeclareSignature(
- const TStringRef& name,
- TType* userType,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly)
- {
- if (Name() != name) {
- return false;
- }
- try {
- auto typeInfoHelper = builder.TypeInfoHelper();
- TTupleTypeInspector tuple(*typeInfoHelper, userType);
- if (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);
- TVector<const TType*> argBlockTypes;
- argBlockTypes.push_back(argType);
- TBlockTypeInspector block(*typeInfoHelper, argType);
- if (block) {
- Y_ENSURE(!block.IsScalar());
- argType = block.GetItemType();
- }
- bool isOptional = false;
- if (auto opt = TOptionalTypeInspector(*typeInfoHelper, argType)) {
- argType = opt.GetItemType();
- isOptional = true;
- }
- TResourceTypeInspector res(*typeInfoHelper, argType);
- if (!res) {
- TDataTypeInspector data(*typeInfoHelper, argType);
- if (!data) {
- builder.SetError("Expected data type");
- return true;
- }
- auto typeId = data.GetTypeId();
- if (typeId == TDataType<TDate>::Id ||
- typeId == TDataType<TDatetime>::Id ||
- typeId == TDataType<TTimestamp>::Id) {
- builder.Args()->Add(argsTuple.GetElementType(0)).Done();
- const TType* retType = builder.SimpleType<TFieldStorage>();
- if (isOptional) {
- retType = builder.Optional()->Item(retType).Build();
- }
- auto outputType = retType;
- if (block) {
- retType = builder.Block(block.IsScalar())->Item(retType).Build();
- }
- builder.Returns(retType);
- builder.SupportsBlocks();
- builder.IsStrict();
- builder.UserType(userType);
- if (!typesOnly) {
- 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));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui16, TFieldStorage, Core<ui16, true, false>>());
- }
- }
- 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));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui32, TFieldStorage, Core<ui32, false, false>>());
- }
- }
- 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));
- } else {
- builder.Implementation(new TUnaryOverOptionalImpl<ui64, TFieldStorage, Core<ui64, false, true>>());
- }
- }
- }
- return true;
- }
- } else {
- Y_ENSURE(!block);
- if (res.GetTag() != TStringRef::Of(TMResourceName)) {
- builder.SetError("Unexpected resource tag");
- return true;
- }
- }
- }
- // default implementation
- builder.Args()->Add<TResource<TMResourceName>>().Flags(ICallablePayload::TArgumentFlags::AutoMap).Done();
- builder.Returns<TFieldStorage>();
- builder.IsStrict();
- if (!typesOnly) {
- builder.Implementation(new TImpl());
- }
- } catch (const std::exception& e) {
- builder.SetError(TStringBuf(e.what()));
- }
- return true;
- }
- };
- namespace {
- const TTMStorage& Reference(const NUdf::TUnboxedValuePod& value) {
- return *reinterpret_cast<const TTMStorage*>(value.GetRawPtr());
- }
- TTMStorage& Reference(NUdf::TUnboxedValuePod& value) {
- return *reinterpret_cast<TTMStorage*>(value.GetRawPtr());
- }
- const TTMStorage& Reference(const TBlockItem& value) {
- return *reinterpret_cast<const TTMStorage*>(value.GetRawPtr());
- }
- Y_DECLARE_UNUSED TTMStorage& Reference(TBlockItem& value) {
- return *reinterpret_cast<TTMStorage*>(value.GetRawPtr());
- }
- const TTM64Storage& Reference64(const NUdf::TUnboxedValuePod& value) {
- return *reinterpret_cast<const TTM64Storage*>(value.GetRawPtr());
- }
- TTM64Storage& Reference64(NUdf::TUnboxedValuePod& value) {
- return *reinterpret_cast<TTM64Storage*>(value.GetRawPtr());
- }
- template<typename TValue>
- TValue DoAddMonths(const TValue& date, i64 months, const NUdf::IDateBuilder& builder) {
- auto result = date;
- auto& storage = Reference(result);
- if (!NYql::DateTime::DoAddMonths(storage, months, builder)) {
- return TValue{};
- }
- return result;
- }
- template<typename TValue>
- TValue DoAddQuarters(const TValue& date, i64 quarters, const NUdf::IDateBuilder& builder) {
- return DoAddMonths(date, quarters * 3ll, builder);
- }
- template<typename TValue>
- TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& builder) {
- auto result = date;
- auto& storage = Reference(result);
- if (!NYql::DateTime::DoAddYears(storage, years, builder)) {
- return TValue{};
- }
- return result;
- }
- #define ACCESSORS(field, type) \
- template<typename TValue> \
- inline type Get##field(const TValue& tm) { \
- return (type)Reference(tm).field; \
- } \
- template<typename TValue> \
- Y_DECLARE_UNUSED inline void Set##field(TValue& tm, type value) { \
- Reference(tm).field = value; \
- }
- ACCESSORS(Year, ui16)
- 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
- inline bool ValidateYear(ui16 year) {
- return year >= NUdf::MIN_YEAR - 1 || year <= NUdf::MAX_YEAR + 1;
- }
- inline bool ValidateMonth(ui8 month) {
- return month >= 1 && month <= 12;
- }
- inline bool ValidateDay(ui8 day) {
- return day >= 1 && day <= 31;
- }
- inline bool ValidateHour(ui8 hour) {
- return hour < 24;
- }
- inline bool ValidateMinute(ui8 minute) {
- return minute < 60;
- }
- inline bool ValidateSecond(ui8 second) {
- return second < 60;
- }
- inline bool ValidateMicrosecond(ui32 microsecond) {
- return microsecond < 1000000;
- }
- inline bool ValidateTimezoneId(ui16 timezoneId) {
- const auto& zones = NUdf::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;
- }
- 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 false;
- }
- inline bool ValidateDatetime(ui32 datetime) {
- return datetime < MAX_DATETIME;
- }
- inline bool ValidateTimestamp(ui64 timestamp) {
- return timestamp < MAX_TIMESTAMP;
- }
- inline bool ValidateInterval(i64 interval) {
- return interval > -i64(MAX_TIMESTAMP) && interval < i64(MAX_TIMESTAMP);
- }
- // 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>
- 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(res), *valueBuilder);
- sink(res);
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << e.what()).data());
- }
- }
- };
- template <typename TUserDataType>
- class TSplit : public TBoxedValue {
- const TSourcePosition Pos_;
- public:
- explicit TSplit(TSourcePosition pos)
- : Pos_(pos)
- {}
- 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();
- 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);
- 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);
- 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::BigDateType) {
- builder.Returns(builder.Resource(TM64ResourceName));
- } else {
- builder.Returns(builder.Resource(TMResourceName));
- }
- if (!typesOnly) {
- builder.Implementation(new TSplit<TUserDataType>(builder.GetSourcePosition()));
- }
- }
- return true;
- }
- };
- 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>());
- }
- template <>
- void TSplitKernelExec<TTimestamp>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) {
- storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>());
- }
- template <>
- void TSplitKernelExec<TTzDate>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) {
- storage.FromDate(builder.GetDateBuilder(), arg.Get<ui16>(), arg.GetTimezoneId());
- }
- template <>
- void TSplitKernelExec<TTzDatetime>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) {
- storage.FromDatetime(builder.GetDateBuilder(), arg.Get<ui32>(), arg.GetTimezoneId());
- }
- template <>
- void TSplitKernelExec<TTzTimestamp>::Split(TBlockItem arg, TTMStorage &storage, const IValueBuilder& builder) {
- storage.FromTimestamp(builder.GetDateBuilder(), arg.Get<ui64>(), arg.GetTimezoneId());
- }
- template <>
- void TSplitKernelExec<TDate32>::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<TTimestamp64>::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);
- auto& builder = valueBuilder->GetDateBuilder();
- TUnboxedValuePod result(0);
- auto& storage = Reference(result);
- storage.FromDate(builder, args[0].Get<ui16>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- template <>
- TUnboxedValue TSplit<TDate32>::Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const
- {
- try {
- EMPTY_RESULT_ON_EMPTY_ARG(0);
- TUnboxedValuePod result(0);
- auto& storage = Reference64(result);
- storage.FromDate32(valueBuilder->GetDateBuilder(), args[0].Get<i32>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- template <>
- TUnboxedValue TSplit<TDatetime>::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(result);
- storage.FromDatetime(builder, args[0].Get<ui32>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- template <>
- TUnboxedValue TSplit<TDatetime64>::Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const
- {
- try {
- EMPTY_RESULT_ON_EMPTY_ARG(0);
- TUnboxedValuePod result(0);
- auto& storage = Reference64(result);
- storage.FromDatetime64(valueBuilder->GetDateBuilder(), args[0].Get<i64>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- template <>
- TUnboxedValue TSplit<TTimestamp>::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(result);
- storage.FromTimestamp(builder, args[0].Get<ui64>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- template <>
- TUnboxedValue TSplit<TTimestamp64>::Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const
- {
- try {
- EMPTY_RESULT_ON_EMPTY_ARG(0);
- TUnboxedValuePod result(0);
- auto& storage = Reference64(result);
- storage.FromTimestamp64(valueBuilder->GetDateBuilder(), args[0].Get<i64>());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- 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(result);
- storage.FromDate(builder, args[0].Get<ui16>(), args[0].GetTimezoneId());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- 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(result);
- storage.FromDatetime(builder, args[0].Get<ui32>(), args[0].GetTimezoneId());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- 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(result);
- storage.FromTimestamp(builder, args[0].Get<ui64>(), args[0].GetTimezoneId());
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- // Make*
- template<typename TUserDataType, bool Nullable>
- using TMakeResBuilder = std::conditional_t<TTzDataType<TUserDataType>::Result,
- TTzDateArrayBuilder<TUserDataType, Nullable>,
- TFixedSizeArrayBuilder<typename TDataType<TUserDataType>::TLayout, Nullable>>;
- template<typename TUserDataType>
- struct TMakeDateKernelExec : TUnaryKernelExec<TMakeDateKernelExec<TUserDataType>, TReaderTraits::TResource<false>, TMakeResBuilder<TUserDataType, false>> {
- static TBlockItem Make(TTMStorage& storage, const IValueBuilder& valueBuilder);
- template<typename TSink>
- static void Process(const IValueBuilder* valueBuilder, TBlockItem item, const TSink& sink) {
- auto& storage = Reference(item);
- sink(TBlockItem(Make(storage, *valueBuilder)));
- }
- };
- template<> TBlockItem TMakeDateKernelExec<TDate>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) {
- TBlockItem res(storage.ToDate(valueBuilder.GetDateBuilder(), /*local*/ false));
- return res;
- }
- template<> TBlockItem TMakeDateKernelExec<TDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) {
- TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder()));
- return res;
- }
- template<> TBlockItem TMakeDateKernelExec<TTimestamp>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) {
- TBlockItem res(storage.ToTimestamp(valueBuilder.GetDateBuilder()));
- 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<TTzDatetime>::Make(TTMStorage& storage, const IValueBuilder& valueBuilder) {
- TBlockItem res(storage.ToDatetime(valueBuilder.GetDateBuilder()));
- res.SetTimezoneId(storage.TimezoneId);
- return res;
- }
- 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(TMakeDate, TDate(TAutoMap<TResource<TMResourceName>>)) {
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(args[0]);
- return TUnboxedValuePod(storage.ToDate(builder, false));
- }
- END_SIMPLE_ARROW_UDF(TMakeDate, TMakeDateKernelExec<TDate>::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeDatetime, TDatetime(TAutoMap<TResource<TMResourceName>>)) {
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(args[0]);
- return TUnboxedValuePod(storage.ToDatetime(builder));
- }
- END_SIMPLE_ARROW_UDF(TMakeDatetime, TMakeDateKernelExec<TDatetime>::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTimestamp, TTimestamp(TAutoMap<TResource<TMResourceName>>)) {
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(args[0]);
- return TUnboxedValuePod(storage.ToTimestamp(builder));
- }
- END_SIMPLE_ARROW_UDF(TMakeTimestamp, TMakeDateKernelExec<TTimestamp>::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TMakeTzDate, TTzDate(TAutoMap<TResource<TMResourceName>>)) {
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(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"
- ).data());
- }
- }
- 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(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(TMakeTzTimestamp, TTzTimestamp(TAutoMap<TResource<TMResourceName>>)) {
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(args[0]);
- TUnboxedValuePod result(storage.ToTimestamp(builder));
- result.SetTimezoneId(storage.TimezoneId);
- return result;
- }
- END_SIMPLE_ARROW_UDF(TMakeTzTimestamp, TMakeDateKernelExec<TTzTimestamp>::Do);
- SIMPLE_STRICT_UDF(TConvert, TResource<TM64ResourceName>(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- TUnboxedValuePod result(0);
- auto& arg = Reference(args[0]);
- auto& storage = Reference64(result);
- storage.From(arg);
- return result;
- }
- SIMPLE_STRICT_UDF(TMakeDate32, TDate32(TAutoMap<TResource<TM64ResourceName>>)) {
- auto& storage = Reference64(args[0]);
- return TUnboxedValuePod(storage.ToDate32(valueBuilder->GetDateBuilder()));
- }
- SIMPLE_STRICT_UDF(TMakeDatetime64, TDatetime64(TAutoMap<TResource<TM64ResourceName>>)) {
- auto& storage = Reference64(args[0]);
- return TUnboxedValuePod(storage.ToDatetime64(valueBuilder->GetDateBuilder()));
- }
- SIMPLE_STRICT_UDF(TMakeTimestamp64, TTimestamp64(TAutoMap<TResource<TM64ResourceName>>)) {
- auto& storage = Reference64(args[0]);
- return TUnboxedValuePod(storage.ToTimestamp64(valueBuilder->GetDateBuilder()));
- }
- // Get*
- #define GET_METHOD(field, type) \
- SIMPLE_STRICT_UDF(TGet##field, type(TAutoMap<TResource<TMResourceName>>)) { \
- Y_UNUSED(valueBuilder); \
- return TUnboxedValuePod(Get##field(args[0])); \
- }
- // #define GET_METHOD(field, type) \
- // struct TGet##field##KernelExec : TUnaryKernelExec<TGet##field##KernelExec, TReaderTraits::TResource<false>, TFixedSizeArrayBuilder<type, false>> { \
- // template<typename TSink> \
- // static void Process(TBlockItem item, const IValueBuilder& valueBuilder, const TSink& sink) { \
- // Y_UNUSED(valueBuilder); \
- // sink(TBlockItem(Get##field(item))); \
- // } \
- // }; \
- // BEGIN_SIMPLE_STRICT_ARROW_UDF(TGet##field, type(TAutoMap<TResource<TMResourceName>>)) { \
- // Y_UNUSED(valueBuilder); \
- // return TUnboxedValuePod(Get##field(args[0])); \
- // } \
- // END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TGet##field, TGet##field##KernelExec::Do, arrow::compute::NullHandling::INTERSECTION);
- GET_METHOD(Year, ui16)
- GET_METHOD(DayOfYear, ui16)
- GET_METHOD(Month, ui8)
- // 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);
- SIMPLE_STRICT_UDF(TGetMonthName, char*(TAutoMap<TResource<TMResourceName>>)) {
- 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"))
- }};
- return monthNames.at(GetMonth(*args) - 1U);
- }
- GET_METHOD(WeekOfYear, ui8)
- GET_METHOD(WeekOfYearIso8601, ui8)
- // 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);
- SIMPLE_STRICT_UDF(TGetDayOfMonth, ui8(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(GetDay(args[0]));
- }
- GET_METHOD(DayOfWeek, ui8)
- template<typename TValue>
- TValue GetDayNameValue(size_t idx) {
- static const std::array<TValue, 7U> dayNames = {{
- TValue::Embedded(TStringRef::Of("Monday")),
- TValue::Embedded(TStringRef::Of("Tuesday")),
- TValue::Embedded(TStringRef::Of("Wednesday")),
- TValue::Embedded(TStringRef::Of("Thursday")),
- TValue::Embedded(TStringRef::Of("Friday")),
- TValue::Embedded(TStringRef::Of("Saturday")),
- TValue::Embedded(TStringRef::Of("Sunday"))
- }};
- return dayNames.at(idx);
- }
- SIMPLE_STRICT_UDF(TGetDayOfWeekName, char*(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- return GetDayNameValue<TUnboxedValuePod>(GetDayOfWeek(*args) - 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);
- GET_METHOD(TimezoneId, ui16)
- 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(item);
- if (timezoneId >= NUdf::GetTimezones().size()) {
- sink(TBlockItem{});
- } else {
- sink(TBlockItem{NUdf::GetTimezones()[timezoneId]});
- }
- }
- };
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TGetTimezoneName, char*(TAutoMap<TResource<TMResourceName>>)) {
- auto timezoneId = GetTimezoneId(args[0]);
- if (timezoneId >= NUdf::GetTimezones().size()) {
- return TUnboxedValuePod();
- }
- return valueBuilder->NewString(NUdf::GetTimezones()[timezoneId]);
- }
- END_SIMPLE_ARROW_UDF(TGetTimezoneName, TTGetTimezoneNameKernelExec::Do);
- // Update
- class TUpdate : public TBoxedValue {
- const TSourcePosition Pos_;
- public:
- explicit TUpdate(TSourcePosition pos)
- : Pos_(pos)
- {}
- TUnboxedValue Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override
- {
- try {
- EMPTY_RESULT_ON_EMPTY_ARG(0);
- auto result = args[0];
- if (args[1]) {
- auto year = args[1].Get<ui16>();
- if (!ValidateYear(year)) {
- return TUnboxedValuePod();
- }
- SetYear(result, year);
- }
- if (args[2]) {
- auto month = args[2].Get<ui8>();
- if (!ValidateMonth(month)) {
- return TUnboxedValuePod();
- }
- SetMonth(result, month);
- }
- if (args[3]) {
- auto day = args[3].Get<ui8>();
- if (!ValidateDay(day)) {
- return TUnboxedValuePod();
- }
- SetDay(result, day);
- }
- if (args[4]) {
- auto hour = args[4].Get<ui8>();
- if (!ValidateHour(hour)) {
- return TUnboxedValuePod();
- }
- SetHour(result, hour);
- }
- if (args[5]) {
- auto minute = args[5].Get<ui8>();
- if (!ValidateMinute(minute)) {
- return TUnboxedValuePod();
- }
- SetMinute(result, minute);
- }
- if (args[6]) {
- auto second = args[6].Get<ui8>();
- if (!ValidateSecond(second)) {
- return TUnboxedValuePod();
- }
- SetSecond(result, second);
- }
- if (args[7]) {
- auto microsecond = args[7].Get<ui32>();
- if (!ValidateMicrosecond(microsecond)) {
- return TUnboxedValuePod();
- }
- SetMicrosecond(result, microsecond);
- }
- if (args[8]) {
- auto timezoneId = args[8].Get<ui16>();
- if (!ValidateTimezoneId(timezoneId)) {
- return TUnboxedValuePod();
- }
- SetTimezoneId(result, timezoneId);
- }
- auto& builder = valueBuilder->GetDateBuilder();
- auto& storage = Reference(result);
- if (!storage.Validate(builder)) {
- return TUnboxedValuePod();
- }
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("Update");
- return name;
- }
- static bool DeclareSignature(
- const TStringRef& name,
- TType*,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly)
- {
- if (Name() != name) {
- return false;
- }
- auto resourceType = builder.Resource(TMResourceName);
- auto optionalResourceType = builder.Optional()->Item(resourceType).Build();
- builder.OptionalArgs(8).Args()->Add(resourceType).Flags(ICallablePayload::TArgumentFlags::AutoMap)
- .Add(builder.Optional()->Item<ui16>().Build()).Name("Year")
- .Add(builder.Optional()->Item<ui8>().Build()).Name("Month")
- .Add(builder.Optional()->Item<ui8>().Build()).Name("Day")
- .Add(builder.Optional()->Item<ui8>().Build()).Name("Hour")
- .Add(builder.Optional()->Item<ui8>().Build()).Name("Minute")
- .Add(builder.Optional()->Item<ui8>().Build()).Name("Second")
- .Add(builder.Optional()->Item<ui32>().Build()).Name("Microsecond")
- .Add(builder.Optional()->Item<ui16>().Build()).Name("TimezoneId");
- builder.Returns(optionalResourceType);
- if (!typesOnly) {
- builder.Implementation(new TUpdate(builder.GetSourcePosition()));
- }
- builder.IsStrict();
- return true;
- }
- };
- // From*
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TFromSeconds, TOptional<TTimestamp>(TAutoMap<ui32>)) {
- Y_UNUSED(valueBuilder);
- auto res = args[0].Get<ui32>();
- if (!ValidateDatetime(res)) {
- return TUnboxedValuePod();
- }
- return TUnboxedValuePod((ui64)(res * 1000000ull));
- }
- using TFromSecondsKernel = TUnaryUnsafeFixedSizeFilterKernel<ui32, ui64,
- [] (ui32 seconds) { return std::make_pair(ui64(seconds * 1000000ull), ValidateDatetime(seconds)); }>;
- END_SIMPLE_ARROW_UDF(TFromSeconds, TFromSecondsKernel::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TFromMilliseconds, TOptional<TTimestamp>(TAutoMap<ui64>)) {
- Y_UNUSED(valueBuilder);
- auto res = args[0].Get<ui64>();
- if (res >= MAX_TIMESTAMP / 1000u) {
- return TUnboxedValuePod();
- }
- return TUnboxedValuePod(res * 1000u);
- }
- using TFromMillisecondsKernel = TUnaryUnsafeFixedSizeFilterKernel<ui64, ui64,
- [] (ui64 milliseconds) { return std::make_pair(ui64(milliseconds * 1000u), milliseconds < MAX_TIMESTAMP / 1000u); }>;
- END_SIMPLE_ARROW_UDF(TFromMilliseconds, TFromMillisecondsKernel::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TFromMicroseconds, TOptional<TTimestamp>(TAutoMap<ui64>)) {
- Y_UNUSED(valueBuilder);
- auto res = args[0].Get<ui64>();
- if (!ValidateTimestamp(res)) {
- return TUnboxedValuePod();
- }
- return TUnboxedValuePod(res);
- }
- using TFromMicrosecondsKernel = TUnaryUnsafeFixedSizeFilterKernel<ui64, ui64,
- [] (ui64 timestamp) { return std::make_pair(timestamp, ValidateTimestamp(timestamp)); }>;
- END_SIMPLE_ARROW_UDF(TFromMicroseconds, TFromMicrosecondsKernel::Do);
- template <typename TInput, i64 Multiplier>
- using TIntervalFromKernel = TUnaryUnsafeFixedSizeFilterKernel<TInput, i64,
- [] (TInput interval) { return std::make_pair(i64(interval * Multiplier), ValidateInterval(interval)); }>;
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromDays, TOptional<TInterval>(TAutoMap<i32>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * UsecondsInDay;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromDays, (TIntervalFromKernel<i32, UsecondsInDay>::Do));
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromHours, TOptional<TInterval>(TAutoMap<i32>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * UsecondsInHour;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromHours, (TIntervalFromKernel<i32, UsecondsInHour>::Do));
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromMinutes, TOptional<TInterval>(TAutoMap<i32>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * UsecondsInMinute;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromMinutes, (TIntervalFromKernel<i32, UsecondsInMinute>::Do));
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromSeconds, TOptional<TInterval>(TAutoMap<i32>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i32>()) * UsecondsInSecond;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromSeconds, (TIntervalFromKernel<i32, UsecondsInSecond>::Do));
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromMilliseconds, TOptional<TInterval>(TAutoMap<i64>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = i64(args[0].Get<i64>()) * UsecondsInMilliseconds;
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromMilliseconds, (TIntervalFromKernel<i64, UsecondsInMilliseconds>::Do));
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TIntervalFromMicroseconds, TOptional<TInterval>(TAutoMap<i64>)) {
- Y_UNUSED(valueBuilder);
- const i64 res = args[0].Get<i64>();
- return ValidateInterval(res) ? TUnboxedValuePod(res) : TUnboxedValuePod();
- }
- END_SIMPLE_ARROW_UDF(TIntervalFromMicroseconds, (TIntervalFromKernel<i64, 1>::Do));
- // To*
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TToDays, i32(TAutoMap<TInterval>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(i32(args[0].Get<i64>() / UsecondsInDay));
- }
- END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TToDays,
- (UnaryPreallocatedExecImpl<i64, i32, [] (i64 arg) { return i32(arg / UsecondsInDay); }>),
- arrow::compute::NullHandling::INTERSECTION);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TToHours, i32(TAutoMap<TInterval>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(i32(args[0].Get<i64>() / UsecondsInHour));
- }
- END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TToHours,
- (UnaryPreallocatedExecImpl<i64, i32, [] (i64 arg) { return i32(arg / UsecondsInHour); }>),
- arrow::compute::NullHandling::INTERSECTION);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TToMinutes, i32(TAutoMap<TInterval>)) {
- Y_UNUSED(valueBuilder);
- return TUnboxedValuePod(i32(args[0].Get<i64>() / UsecondsInMinute));
- }
- END_SIMPLE_ARROW_UDF_WITH_NULL_HANDLING(TToMinutes,
- (UnaryPreallocatedExecImpl<i64, i32, [] (i64 arg) { return i32(arg / UsecondsInMinute); }>),
- arrow::compute::NullHandling::INTERSECTION);
- // 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(item), *valueBuilder)) {
- Reference(item) = res.GetRef();
- sink(item);
- } else {
- sink(TBlockItem{});
- }
- }
- };
- template<auto Core>
- TUnboxedValue SimpleDatetimeToDatetimeUdf(const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) {
- auto result = args[0];
- auto& storage = Reference(result);
- if (auto res = Core(storage, *valueBuilder)) {
- storage = res.GetRef();
- return result;
- }
- return TUnboxedValuePod{};
- }
- TMaybe<TTMStorage> StartOfYear(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Month = 1;
- storage.Day = 1;
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOfYear, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<StartOfYear>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TStartOfYear, TStartOfKernelExec<StartOfYear>::Do);
- void SetEndOfDay(TTMStorage& storage) {
- storage.Hour = 23;
- storage.Minute = 59;
- storage.Second = 59;
- storage.Microsecond = 999999;
- }
- TMaybe<TTMStorage> EndOfYear(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Month = 12;
- storage.Day = 31;
- SetEndOfDay(storage);
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TEndOfYear, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<EndOfYear>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TEndOfYear, TStartOfKernelExec<EndOfYear>::Do);
- TMaybe<TTMStorage> StartOfQuarter(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Month = (storage.Month - 1) / 3 * 3 + 1;
- storage.Day = 1;
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOfQuarter, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<StartOfQuarter>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TStartOfQuarter, TStartOfKernelExec<StartOfQuarter>::Do);
- TMaybe<TTMStorage> EndOfQuarter(TTMStorage 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;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TEndOfQuarter, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<EndOfQuarter>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TEndOfQuarter, TStartOfKernelExec<EndOfQuarter>::Do);
- TMaybe<TTMStorage> StartOfMonth(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Day = 1;
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOfMonth, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<StartOfMonth>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TStartOfMonth, TStartOfKernelExec<StartOfMonth>::Do);
- TMaybe<TTMStorage> EndOfMonth(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Day = NMiniKQL::GetMonthLength(storage.Month, NMiniKQL::IsLeapYear(storage.Year));
- SetEndOfDay(storage);
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TEndOfMonth, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<EndOfMonth>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TEndOfMonth, TStartOfKernelExec<EndOfMonth>::Do);
- TMaybe<TTMStorage> StartOfWeek(TTMStorage storage, const IValueBuilder& valueBuilder) {
- const ui32 shift = 86400u * (storage.DayOfWeek - 1u);
- if (shift > storage.ToDatetime(valueBuilder.GetDateBuilder())) {
- return {};
- }
- storage.FromDatetime(valueBuilder.GetDateBuilder(), storage.ToDatetime(valueBuilder.GetDateBuilder()) - shift, storage.TimezoneId);
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOfWeek, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<StartOfWeek>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TStartOfWeek, TStartOfKernelExec<StartOfWeek>::Do);
- TMaybe<TTMStorage> EndOfWeek(TTMStorage storage, const IValueBuilder& valueBuilder) {
- const ui32 shift = 86400u * (7u - storage.DayOfWeek);
- auto dt = storage.ToDatetime(valueBuilder.GetDateBuilder());
- if (NUdf::MAX_DATETIME - shift <= dt) {
- return {};
- }
- storage.FromDatetime(valueBuilder.GetDateBuilder(), dt + shift, storage.TimezoneId);
- SetEndOfDay(storage);
- if (!storage.Validate(valueBuilder.GetDateBuilder())) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TEndOfWeek, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<EndOfWeek>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TEndOfWeek, TStartOfKernelExec<EndOfWeek>::Do);
- TMaybe<TTMStorage> StartOfDay(TTMStorage storage, const IValueBuilder& valueBuilder) {
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- auto& builder = valueBuilder.GetDateBuilder();
- if (!storage.Validate(builder)) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOfDay, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<StartOfDay>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TStartOfDay, TStartOfKernelExec<StartOfDay>::Do);
- TMaybe<TTMStorage> EndOfDay(TTMStorage storage, const IValueBuilder& valueBuilder) {
- SetEndOfDay(storage);
- auto& builder = valueBuilder.GetDateBuilder();
- if (!storage.Validate(builder)) {
- return {};
- }
- return storage;
- }
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TEndOfDay, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
- return SimpleDatetimeToDatetimeUdf<EndOfDay>(valueBuilder, args);
- }
- END_SIMPLE_ARROW_UDF(TEndOfDay, TStartOfKernelExec<EndOfDay>::Do);
- TMaybe<TTMStorage> StartOf(TTMStorage storage, ui64 interval, const IValueBuilder& valueBuilder) {
- if (interval >= 86400000000ull) {
- // treat as StartOfDay
- storage.Hour = 0;
- storage.Minute = 0;
- storage.Second = 0;
- storage.Microsecond = 0;
- } else {
- auto current = storage.ToTimeOfDay();
- auto rounded = current / interval * interval;
- storage.FromTimeOfDay(rounded);
- }
- auto& builder = valueBuilder.GetDateBuilder();
- if (!storage.Validate(builder)) {
- return {};
- }
- return storage;
- }
- struct TStartOfBinaryKernelExec : TBinaryKernelExec<TStartOfBinaryKernelExec> {
- template<typename TSink>
- static void Process(const IValueBuilder* valueBuilder, TBlockItem arg1, TBlockItem arg2, const TSink& sink) {
- auto& storage = Reference(arg1);
- ui64 interval = std::abs(arg2.Get<i64>());
- if (interval == 0) {
- sink(arg1);
- return;
- }
- if (auto res = StartOf(storage, interval, *valueBuilder)) {
- storage = res.GetRef();
- sink(arg1);
- } else {
- sink(TBlockItem{});
- }
- }
- };
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TStartOf, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>, TAutoMap<TInterval>)) {
- auto result = args[0];
- ui64 interval = std::abs(args[1].Get<i64>());
- if (interval == 0) {
- return result;
- }
- if (auto res = StartOf(Reference(result), interval, *valueBuilder)) {
- Reference(result) = res.GetRef();
- return result;
- }
- return TUnboxedValuePod{};
- }
- END_SIMPLE_ARROW_UDF(TStartOf, TStartOfBinaryKernelExec::Do);
- 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(item);
- sink(TBlockItem{(TDataType<TInterval>::TLayout)storage.ToTimeOfDay()});
- }
- };
- const auto timeOfDayKernelExecDo = TTimeOfDayKernelExec::Do;
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TTimeOfDay, TInterval(TAutoMap<TResource<TMResourceName>>)) {
- Y_UNUSED(valueBuilder);
- auto& storage = Reference(args[0]);
- return TUnboxedValuePod((i64)storage.ToTimeOfDay());
- }
- END_SIMPLE_ARROW_UDF(TTimeOfDay, timeOfDayKernelExecDo);
- // 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()));
- }
- };
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TShiftYears, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>, i32)) {
- return DoAddYears(args[0], args[1].Get<i32>(), valueBuilder->GetDateBuilder());
- }
- END_SIMPLE_ARROW_UDF(TShiftYears, TAddKernelExec<DoAddYears<TBlockItem>>::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TShiftQuarters, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>, i32)) {
- return DoAddQuarters(args[0], args[1].Get<i32>(), valueBuilder->GetDateBuilder());
- }
- END_SIMPLE_ARROW_UDF(TShiftQuarters, TAddKernelExec<DoAddQuarters<TBlockItem>>::Do);
- BEGIN_SIMPLE_STRICT_ARROW_UDF(TShiftMonths, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>, i32)) {
- return DoAddMonths(args[0], args[1].Get<i32>(), valueBuilder->GetDateBuilder());
- }
- END_SIMPLE_ARROW_UDF(TShiftMonths, TAddKernelExec<DoAddMonths<TBlockItem>>::Do);
- template<size_t Digits, bool Exacly = true>
- struct PrintNDigits;
- template<bool Exacly>
- struct PrintNDigits<0U, Exacly> {
- static constexpr ui32 Miltiplier = 1U;
- template <typename T>
- static constexpr size_t Do(T, char*) { return 0U; }
- };
- template<size_t Digits, bool Exacly>
- struct PrintNDigits {
- using TNextPrint = PrintNDigits<Digits - 1U, Exacly>;
- static constexpr ui32 Miltiplier = TNextPrint::Miltiplier * 10U;
- template <typename T>
- static constexpr size_t Do(T in, char* out) {
- in %= Miltiplier;
- if (Exacly || in) {
- *out = "0123456789"[in / TNextPrint::Miltiplier];
- return 1U + TNextPrint::Do(in, ++out);
- }
- return 0U;
- }
- };
- // Format
- class TFormat : public TBoxedValue {
- public:
- explicit TFormat(TSourcePosition pos)
- : Pos_(pos)
- {}
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("Format");
- return name;
- }
- static bool DeclareSignature(
- const TStringRef& name,
- TType*,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly)
- {
- if (Name() != name) {
- return false;
- }
- auto resourceType = builder.Resource(TMResourceName);
- auto stringType = builder.SimpleType<char*>();
- auto boolType = builder.SimpleType<bool>();
- auto optionalBoolType = builder.Optional()->Item(boolType).Build();
- auto args = builder.Args();
- args->Add(stringType);
- args->Add(optionalBoolType).Name("AlwaysWriteFractionalSeconds");
- args->Done();
- builder.OptionalArgs(1);
- builder.Returns(
- builder.Callable(1)
- ->Returns(stringType)
- .Arg(resourceType)
- .Flags(ICallablePayload::TArgumentFlags::AutoMap)
- .Build()
- );
- if (!typesOnly) {
- builder.Implementation(new TFormat(builder.GetSourcePosition()));
- }
- return true;
- }
- private:
- using TPrintersList = std::vector<std::function<size_t(char*, const TUnboxedValuePod&, const IDateBuilder&)>>;
- struct TDataPrinter {
- const std::string_view Data;
- size_t operator()(char* out, const TUnboxedValuePod&, const IDateBuilder&) const {
- std::memcpy(out, Data.data(), Data.size());
- return Data.size();
- }
- };
- TUnboxedValue Run(const IValueBuilder*, const TUnboxedValuePod* args) const final try {
- bool alwaysWriteFractionalSeconds = false;
- if (auto val = args[1]) {
- alwaysWriteFractionalSeconds = val.Get<bool>();
- }
- return TUnboxedValuePod(new TImpl(Pos_, args[0], alwaysWriteFractionalSeconds));
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- 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& builder = valueBuilder->GetDateBuilder();
- auto result = valueBuilder->NewStringNotFilled(ReservedSize_);
- auto pos = result.AsStringRef().Data();
- ui32 size = 0U;
- for (const auto& printer : Printers_) {
- if (const auto plus = printer(pos, value, builder)) {
- size += plus;
- pos += plus;
- }
- }
- if (size < ReservedSize_) {
- result = valueBuilder->SubString(result.Release(), 0U, size);
- }
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- 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;
- }
- 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) {
- case '%': {
- static constexpr size_t size = 1;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod&, const IDateBuilder&) {
- *out = '%';
- return size;
- });
- ReservedSize_ += size;
- break;
- }
- case 'Y': {
- static constexpr size_t size = 4;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetYear(value), out);
- });
- ReservedSize_ += size;
- break;
- }
- case 'm': {
- static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetMonth(value), out);
- });
- ReservedSize_ += size;
- break;
- }
- case 'd': {
- static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetDay(value), out);
- });
- ReservedSize_ += size;
- break;
- }
- case 'H': {
- static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetHour(value), out);
- });
- ReservedSize_ += size;
- break;
- }
- case 'M': {
- static constexpr size_t size = 2;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- return PrintNDigits<size>::Do(GetMinute(value), out);
- });
- ReservedSize_ += size;
- break;
- }
- case 'S':
- Printers_.emplace_back([alwaysWriteFractionalSeconds](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- constexpr size_t size = 2;
- if (const auto microsecond = GetMicrosecond(value); microsecond || alwaysWriteFractionalSeconds) {
- out += PrintNDigits<size>::Do(GetSecond(value), out);
- *out++ = '.';
- constexpr size_t msize = 6;
- auto addSz = alwaysWriteFractionalSeconds ?
- PrintNDigits<msize, true>::Do(microsecond, out) :
- PrintNDigits<msize, false>::Do(microsecond, out);
- return size + 1U + addSz;
- }
- return PrintNDigits<size>::Do(GetSecond(value), out);
- });
- ReservedSize_ += 9;
- break;
- case 'z': {
- static constexpr size_t size = 5;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder& builder) {
- auto timezoneId = GetTimezoneId(value);
- if (TTMStorage::IsUniversal(timezoneId)) {
- std::memcpy(out, "+0000", size);
- return size;
- }
- i32 shift;
- if (!builder.GetTimezoneShift(GetYear(value), GetMonth(value), GetDay(value),
- GetHour(value), GetMinute(value), GetSecond(value), timezoneId, shift))
- {
- std::memcpy(out, "+0000", size);
- return size;
- }
- *out++ = shift > 0 ? '+' : '-';
- shift = std::abs(shift);
- out += PrintNDigits<2U>::Do(shift / 60U, out);
- out += PrintNDigits<2U>::Do(shift % 60U, out);
- return size;
- });
- ReservedSize_ += size;
- break;
- }
- case 'Z':
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- const auto timezoneId = GetTimezoneId(value);
- const auto tzName = NUdf::GetTimezones()[timezoneId];
- std::memcpy(out, tzName.data(), std::min(tzName.size(), MAX_TIMEZONE_NAME_LEN));
- return tzName.size();
- });
- ReservedSize_ += MAX_TIMEZONE_NAME_LEN;
- break;
- case 'b': {
- static constexpr size_t size = 3;
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- static constexpr std::string_view mp[] {
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec"
- };
- auto month = GetMonth(value);
- Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value");
- std::memcpy(out, mp[month - 1].data(), size);
- return size;
- });
- ReservedSize_ += size;
- break;
- }
- case 'B': {
- Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
- static constexpr std::string_view mp[] {
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December"
- };
- auto month = GetMonth(value);
- Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value");
- const std::string_view monthFullName = mp[month - 1];
- std::memcpy(out, monthFullName.data(), monthFullName.size());
- return monthFullName.size();
- });
- ReservedSize_ += 9U; // MAX_MONTH_FULL_NAME_LEN
- break;
- }
- default:
- ythrow yexception() << "invalid format character: " << *ptr;
- }
- dataStart = ptr + 1U;
- }
- 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;
- };
- const TSourcePosition Pos_;
- };
- template<size_t Digits>
- struct ParseExaclyNDigits;
- template<>
- struct ParseExaclyNDigits<0U> {
- template <typename T>
- static constexpr bool Do(std::string_view::const_iterator&, T&) {
- return true;
- }
- };
- template<size_t Digits>
- struct ParseExaclyNDigits {
- template <typename T>
- static constexpr bool Do(std::string_view::const_iterator& it, T& out) {
- const auto d = *it;
- if (!std::isdigit(d)) {
- return false;
- }
- out *= 10U;
- out += d - '0';
- return ParseExaclyNDigits<Digits - 1U>::Do(++it, out);
- }
- };
- // Parse
- class TParse : 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()).data());
- }
- const TSourcePosition Pos_;
- };
- static const TStringRef& Name() {
- static auto name = TStringRef::Of("Parse");
- return name;
- }
- static bool DeclareSignature(
- const TStringRef& name,
- TType*,
- IFunctionTypeInfoBuilder& builder,
- bool typesOnly)
- {
- if (Name() != name) {
- return false;
- }
- auto resourceType = builder.Resource(TMResourceName);
- auto optionalResourceType = builder.Optional()->Item(resourceType).Build();
- builder.Args()->Add<char*>().Flags(ICallablePayload::TArgumentFlags::AutoMap)
- .Add(builder.Optional()->Item<ui16>())
- .Done()
- .OptionalArgs(1);
- builder.RunConfig<char*>().Returns(optionalResourceType);
- if (!typesOnly) {
- builder.Implementation(new TParse::TFactory(builder.GetSourcePosition()));
- }
- return true;
- }
- private:
- const TSourcePosition Pos_;
- const TUnboxedValue Format_;
- std::vector<std::function<bool(std::string_view::const_iterator& it, size_t, TUnboxedValuePod&, const IDateBuilder&)>> Scanners_;
- 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;
- }
- };
- TUnboxedValue Run(
- const IValueBuilder* valueBuilder,
- const TUnboxedValuePod* args) const override
- {
- try {
- EMPTY_RESULT_ON_EMPTY_ARG(0);
- const std::string_view buffer = args[0].AsStringRef();
- TUnboxedValuePod result(0);
- auto& storage = Reference(result);
- storage.MakeDefault();
- auto& builder = valueBuilder->GetDateBuilder();
- auto it = buffer.begin();
- for (const auto& scanner : Scanners_) {
- if (!scanner(it, std::distance(it, buffer.end()), result, builder)) {
- return TUnboxedValuePod();
- }
- }
- if (buffer.end() != it || !storage.Validate(builder)) {
- return TUnboxedValuePod();
- }
- return result;
- } catch (const std::exception& e) {
- UdfTerminate((TStringBuilder() << Pos_ << " " << e.what()).data());
- }
- }
- 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;
- }
- if (dataSize) {
- Scanners_.emplace_back(TDataScanner{std::string_view(&*dataStart, dataSize)});
- dataSize = 0;
- }
- if (++ptr == formatView.end()) {
- ythrow yexception() << "format string ends with single %%";
- }
- switch (*ptr) {
- case '%':
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod&, const IDateBuilder&) {
- return limit > 0U && *it++ == '%';
- });
- break;
- case 'Y': {
- static constexpr size_t size = 4;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 year = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, year) || !ValidateYear(year)) {
- return false;
- }
- SetYear(result, year);
- return true;
- });
- break;
- }
- case 'm': {
- static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 month = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, month) || !ValidateMonth(month)) {
- return false;
- }
- SetMonth(result, month);
- return true;
- });
- break;
- }
- case 'd': {
- static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 day = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, day) || !ValidateDay(day)) {
- return false;
- }
- SetDay(result, day);
- return true;
- });
- break;
- }
- case 'H': {
- static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 hour = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, hour) || !ValidateHour(hour)) {
- return false;
- }
- SetHour(result, hour);
- return true;
- });
- break;
- }
- case 'M': {
- static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 minute = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, minute) || !ValidateMinute(minute)) {
- return false;
- }
- SetMinute(result, minute);
- return true;
- });
- break;
- }
- case 'S': {
- static constexpr size_t size = 2;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- ui32 second = 0U;
- if (limit < size || !ParseExaclyNDigits<size>::Do(it, second) || !ValidateSecond(second)) {
- return false;
- }
- SetSecond(result, second);
- limit -= size;
- if (!limit || *it != '.') {
- return true;
- }
- ++it;
- --limit;
- ui32 usec = 0U;
- size_t digits = 6U;
- for (; limit; --limit) {
- const auto c = *it;
- if (!digits || !std::isdigit(c)) {
- break;
- }
- usec *= 10U;
- usec += c - '0';
- ++it;
- --digits;
- }
- for (; !digits && limit && std::isdigit(*it); --limit, ++it);
- while (digits--) {
- usec *= 10U;
- }
- SetMicrosecond(result, usec);
- return true;
- });
- break;
- }
- case 'Z':
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder& builder) {
- const auto start = it;
- while (limit > 0 && (std::isalnum(*it) || *it == '/' || *it == '_' || *it == '-' || *it == '+')) {
- ++it;
- --limit;
- }
- const auto size = std::distance(start, it);
- ui32 timezoneId;
- if (!builder.FindTimezoneId(TStringRef(&*start, size), timezoneId)) {
- return false;
- }
- SetTimezoneId(result, timezoneId);
- return true;
- });
- break;
- case 'b': {
- static constexpr size_t size = 3;
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- const auto start = it;
- size_t cnt = 0U;
- while (limit > 0 && cnt < size && std::isalpha(*it)) {
- ++it;
- ++cnt;
- --limit;
- }
- const std::string_view monthName{start, cnt};
- ui8 month = 0U;
- if (cnt < size || !ValidateMonthShortName(monthName, month)) {
- return false;
- }
- SetMonth(result, month);
- return true;
- });
- break;
- }
- case 'B': {
- Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
- const auto start = it;
- size_t cnt = 0U;
- while (limit > 0 && std::isalpha(*it)) {
- ++it;
- ++cnt;
- --limit;
- }
- const std::string_view monthName{start, cnt};
- ui8 month = 0U;
- if (!ValidateMonthFullName(monthName, month)) {
- return false;
- }
- SetMonth(result, month);
- return true;
- });
- break;
- }
- default:
- ythrow yexception() << "invalid format character: " << *ptr;
- }
- 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*>)) { \
- auto str = args[0].AsStringRef(); \
- TInstant instant; \
- if (!TInstant::TryParse##format(TStringBuf(str.Data(), str.Size()), instant) || instant.Seconds() >= NUdf::MAX_DATETIME) { \
- return TUnboxedValuePod(); \
- } \
- auto& builder = valueBuilder->GetDateBuilder(); \
- TUnboxedValuePod result(0); \
- auto& storage = Reference(result); \
- storage.FromTimestamp(builder, instant.MicroSeconds()); \
- return result; \
- }
- PARSE_SPECIFIC_FORMAT(Rfc822);
- PARSE_SPECIFIC_FORMAT(Iso8601);
- PARSE_SPECIFIC_FORMAT(Http);
- PARSE_SPECIFIC_FORMAT(X509);
- SIMPLE_MODULE(TDateTime2Module,
- TUserDataTypeFuncFactory<true, true, SplitName, TSplit,
- TDate,
- TDatetime,
- TTimestamp,
- TTzDate,
- TTzDatetime,
- TTzTimestamp,
- TDate32,
- TDatetime64,
- TTimestamp64>,
- TMakeDate,
- TMakeDatetime,
- TMakeTimestamp,
- TMakeTzDate,
- TMakeTzDatetime,
- TMakeTzTimestamp,
- TConvert,
- TMakeDate32,
- TMakeDatetime64,
- TMakeTimestamp64,
- TGetYear,
- TGetDayOfYear,
- TGetMonth,
- TGetMonthName,
- TGetWeekOfYear,
- TGetWeekOfYearIso8601,
- TGetDayOfMonth,
- TGetDayOfWeek,
- TGetDayOfWeekName,
- TGetTimeComponent<GetHourName, ui8, GetHour, 1u, 3600u, 24u, false>,
- TGetTimeComponent<GetMinuteName, ui8, GetMinute, 1u, 60u, 60u, false>,
- TGetTimeComponent<GetSecondName, ui8, GetSecond, 1u, 1u, 60u, false>,
- TGetTimeComponent<GetMillisecondOfSecondName, ui32, GetMicrosecond, 1000u, 1000u, 1000u, true>,
- TGetTimeComponent<GetMicrosecondOfSecondName, ui32, GetMicrosecond, 1u, 1u, 1000000u, true>,
- TGetTimezoneId,
- TGetTimezoneName,
- TUpdate,
- TFromSeconds,
- TFromMilliseconds,
- TFromMicroseconds,
- TIntervalFromDays,
- TIntervalFromHours,
- TIntervalFromMinutes,
- TIntervalFromSeconds,
- TIntervalFromMilliseconds,
- TIntervalFromMicroseconds,
- TToDays,
- TToHours,
- TToMinutes,
- TStartOfYear,
- TStartOfQuarter,
- TStartOfMonth,
- TStartOfWeek,
- TStartOfDay,
- TStartOf,
- TTimeOfDay,
- TShiftYears,
- TShiftQuarters,
- TShiftMonths,
- TEndOfYear,
- TEndOfQuarter,
- TEndOfMonth,
- TEndOfWeek,
- TEndOfDay,
- TToUnits<ToSecondsName, ui32, 1>,
- TToUnits<ToMillisecondsName, ui64, 1000>,
- TToUnits<ToMicrosecondsName, ui64, 1000000>,
- TFormat,
- TParse,
- TParseRfc822,
- TParseIso8601,
- TParseHttp,
- TParseX509
- )
- }
- REGISTER_MODULES(TDateTime2Module)
|