Skip to content

Commit de89917

Browse files
committed
YQL-18303: Make Format use wide resource
commit_hash:bc73748a505f7ac5ea17db28244cb84e63c0bf69 (cherry picked from commit c7a3ca4)
1 parent dc4ee9f commit de89917

File tree

3 files changed

+154
-75
lines changed

3 files changed

+154
-75
lines changed

yql/essentials/udfs/common/datetime2/datetime_udf.cpp

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2602,30 +2602,36 @@ class TShift : public TBoxedValue {
26022602
}
26032603
};
26042604

2605-
template<size_t Digits, bool Exacly = true>
2605+
template<size_t Digits, bool Trailing = true, bool Leading = true>
26062606
struct PrintNDigits;
26072607

2608-
template<bool Exacly>
2609-
struct PrintNDigits<0U, Exacly> {
2608+
template<bool Trailing, bool Leading>
2609+
struct PrintNDigits<0U, Trailing, Leading> {
26102610
static constexpr ui32 Miltiplier = 1U;
26112611

26122612
template <typename T>
26132613
static constexpr size_t Do(T, char*) { return 0U; }
26142614
};
26152615

2616-
template<size_t Digits, bool Exacly>
2616+
template<size_t Digits, bool Trailing, bool Leading>
26172617
struct PrintNDigits {
2618-
using TNextPrint = PrintNDigits<Digits - 1U, Exacly>;
2619-
static constexpr ui32 Miltiplier = TNextPrint::Miltiplier * 10U;
2618+
using TNextNoLeadPrint = PrintNDigits<Digits - 1U, Trailing, false>;
2619+
using TNextCommonPrint = PrintNDigits<Digits - 1U, Trailing, true>;
2620+
static_assert(TNextNoLeadPrint::Miltiplier == TNextCommonPrint::Miltiplier);
2621+
static constexpr ui32 Miltiplier = TNextCommonPrint::Miltiplier * 10U;
26202622

26212623
template <typename T>
26222624
static constexpr size_t Do(T in, char* out) {
26232625
in %= Miltiplier;
2624-
if (Exacly || in) {
2625-
*out = "0123456789"[in / TNextPrint::Miltiplier];
2626-
return 1U + TNextPrint::Do(in, ++out);
2626+
if (!Trailing && in == 0) {
2627+
return 0U;
26272628
}
2628-
return 0U;
2629+
const auto digit = in / TNextCommonPrint::Miltiplier;
2630+
if (!Leading && digit == 0) {
2631+
return TNextNoLeadPrint::Do(in, out);
2632+
}
2633+
*out = "0123456789"[digit];
2634+
return 1U + TNextCommonPrint::Do(in, ++out);
26292635
}
26302636
};
26312637

@@ -2664,24 +2670,10 @@ class TShift : public TBoxedValue {
26642670
return true;
26652671
}
26662672

2667-
auto stringType = builder.SimpleType<char*>();
2668-
2669-
auto boolType = builder.SimpleType<bool>();
2670-
auto optionalBoolType = builder.Optional()->Item(boolType).Build();
2671-
2672-
auto args = builder.Args();
2673-
args->Add(stringType);
2674-
args->Add(optionalBoolType).Name("AlwaysWriteFractionalSeconds");
2675-
args->Done();
2676-
builder.OptionalArgs(1);
2673+
builder.OptionalArgs(1).Args()->Add<char*>()
2674+
.Add<TOptional<bool>>().Name("AlwaysWriteFractionalSeconds");
26772675
builder.Returns(
2678-
builder.Callable(1)
2679-
->Returns(stringType)
2680-
.Arg(resourceType)
2681-
.Flags(ICallablePayload::TArgumentFlags::AutoMap)
2682-
.Build()
2683-
);
2684-
2676+
builder.SimpleSignatureType<char*(TAutoMap<TResource<TM64ResourceName>>)>());
26852677
if (!typesOnly) {
26862678
builder.Implementation(new TFormat(builder.GetSourcePosition()));
26872679
}
@@ -2780,73 +2772,85 @@ class TShift : public TBoxedValue {
27802772
break;
27812773
}
27822774
case 'Y': {
2783-
static constexpr size_t size = 4;
2775+
static constexpr size_t size = 6;
27842776
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2785-
return PrintNDigits<size>::Do(GetYear(value), out);
2777+
i64 year = GetYear<TM64ResourceName>(value);
2778+
Y_DEBUG_ABORT_UNLESS(year != 0);
2779+
i64 yearRepr = std::abs(year);
2780+
if (year < 0) {
2781+
*out++ = '-';
2782+
}
2783+
return (year < 0 ? 1 : 0) + PrintNDigits<size, true, false>::Do(yearRepr, out);
27862784
});
2787-
ReservedSize_ += size;
2785+
// Reserve one more slot for possible '-' char.
2786+
ReservedSize_ += size + 1;
27882787
break;
27892788
}
27902789
case 'm': {
27912790
static constexpr size_t size = 2;
27922791
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2793-
return PrintNDigits<size>::Do(GetMonth(value), out);
2792+
return PrintNDigits<size>::Do(GetMonth<TM64ResourceName>(value), out);
27942793
});
27952794
ReservedSize_ += size;
27962795
break;
27972796
}
27982797
case 'd': {
27992798
static constexpr size_t size = 2;
28002799
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2801-
return PrintNDigits<size>::Do(GetDay(value), out);
2800+
return PrintNDigits<size>::Do(GetDay<TM64ResourceName>(value), out);
28022801
});
28032802
ReservedSize_ += size;
28042803
break;
28052804
}
28062805
case 'H': {
28072806
static constexpr size_t size = 2;
28082807
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2809-
return PrintNDigits<size>::Do(GetHour(value), out);
2808+
return PrintNDigits<size>::Do(GetHour<TM64ResourceName>(value), out);
28102809
});
28112810
ReservedSize_ += size;
28122811
break;
28132812
}
28142813
case 'M': {
28152814
static constexpr size_t size = 2;
28162815
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2817-
return PrintNDigits<size>::Do(GetMinute(value), out);
2816+
return PrintNDigits<size>::Do(GetMinute<TM64ResourceName>(value), out);
28182817
});
28192818
ReservedSize_ += size;
28202819
break;
28212820
}
28222821
case 'S':
28232822
Printers_.emplace_back([alwaysWriteFractionalSeconds](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
28242823
constexpr size_t size = 2;
2825-
if (const auto microsecond = GetMicrosecond(value); microsecond || alwaysWriteFractionalSeconds) {
2826-
out += PrintNDigits<size>::Do(GetSecond(value), out);
2824+
if (const auto microsecond = GetMicrosecond<TM64ResourceName>(value); microsecond || alwaysWriteFractionalSeconds) {
2825+
out += PrintNDigits<size>::Do(GetSecond<TM64ResourceName>(value), out);
28272826
*out++ = '.';
28282827
constexpr size_t msize = 6;
28292828
auto addSz = alwaysWriteFractionalSeconds ?
28302829
PrintNDigits<msize, true>::Do(microsecond, out) :
28312830
PrintNDigits<msize, false>::Do(microsecond, out);
28322831
return size + 1U + addSz;
28332832
}
2834-
return PrintNDigits<size>::Do(GetSecond(value), out);
2833+
return PrintNDigits<size>::Do(GetSecond<TM64ResourceName>(value), out);
28352834
});
28362835
ReservedSize_ += 9;
28372836
break;
28382837

28392838
case 'z': {
28402839
static constexpr size_t size = 5;
28412840
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder& builder) {
2842-
auto timezoneId = GetTimezoneId(value);
2841+
auto timezoneId = GetTimezoneId<TM64ResourceName>(value);
28432842
if (TTMStorage::IsUniversal(timezoneId)) {
28442843
std::memcpy(out, "+0000", size);
28452844
return size;
28462845
}
28472846
i32 shift;
2848-
if (!builder.GetTimezoneShift(GetYear(value), GetMonth(value), GetDay(value),
2849-
GetHour(value), GetMinute(value), GetSecond(value), timezoneId, shift))
2847+
if (!builder.GetTimezoneShift(GetYear<TM64ResourceName>(value),
2848+
GetMonth<TM64ResourceName>(value),
2849+
GetDay<TM64ResourceName>(value),
2850+
GetHour<TM64ResourceName>(value),
2851+
GetMinute<TM64ResourceName>(value),
2852+
GetSecond<TM64ResourceName>(value),
2853+
timezoneId, shift))
28502854
{
28512855
std::memcpy(out, "+0000", size);
28522856
return size;
@@ -2863,7 +2867,7 @@ class TShift : public TBoxedValue {
28632867
}
28642868
case 'Z':
28652869
Printers_.emplace_back([](char* out, const TUnboxedValuePod& value, const IDateBuilder&) {
2866-
const auto timezoneId = GetTimezoneId(value);
2870+
const auto timezoneId = GetTimezoneId<TM64ResourceName>(value);
28672871
const auto tzName = NUdf::GetTimezones()[timezoneId];
28682872
std::memcpy(out, tzName.data(), std::min(tzName.size(), MAX_TIMEZONE_NAME_LEN));
28692873
return tzName.size();
@@ -2887,7 +2891,7 @@ class TShift : public TBoxedValue {
28872891
"Nov",
28882892
"Dec"
28892893
};
2890-
auto month = GetMonth(value);
2894+
auto month = GetMonth<TM64ResourceName>(value);
28912895
Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value");
28922896
std::memcpy(out, mp[month - 1].data(), size);
28932897
return size;
@@ -2911,7 +2915,7 @@ class TShift : public TBoxedValue {
29112915
"November",
29122916
"December"
29132917
};
2914-
auto month = GetMonth(value);
2918+
auto month = GetMonth<TM64ResourceName>(value);
29152919
Y_ENSURE(month > 0 && month <= sizeof(mp) / sizeof(mp[0]), "Invalid month value");
29162920
const std::string_view monthFullName = mp[month - 1];
29172921
std::memcpy(out, monthFullName.data(), monthFullName.size());

0 commit comments

Comments
 (0)