Skip to content

Commit dc4ee9f

Browse files
committed
YQL-18303: Introduce Parse64 function
commit_hash:f2068081a3ddfb16f531239f3e0dcc923084d3b0 (cherry picked from commit afb5748)
1 parent 6429c9c commit dc4ee9f

File tree

10 files changed

+355
-46
lines changed

10 files changed

+355
-46
lines changed

yql/essentials/sql/v1/builtin.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,8 +3471,6 @@ TNodePtr BuildBuiltinFunc(TContext& ctx, TPosition pos, TString name, const TVec
34713471

34723472
return BuildUdf(ctx, pos, moduleName, name, newArgs);
34733473
}
3474-
} else if (ns == "datetime2" && (name == "Parse")) {
3475-
return BuildUdf(ctx, pos, nameSpace, name, args);
34763474
} else if (MKQL_RUNTIME_VERSION < 51U && ns == "datetime2" && name == "Format") {
34773475
// FIXME: The condition above is required to untie the
34783476
// Gordian knot with the upgrade, when two MiniKQL

yql/essentials/tests/sql/minirun/part0/canondata/result.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,9 @@
630630
],
631631
"test.test[expr-tzdate_result-default.txt-Debug]": [
632632
{
633-
"checksum": "e686ef209841ef2196efb49ff5948533",
634-
"size": 1672,
635-
"uri": "https://{canondata_backend}/1942525/ede9d81525f3cde3c09402fe9435fdbba85f47bc/resource.tar.gz#test.test_expr-tzdate_result-default.txt-Debug_/opt.yql"
633+
"checksum": "c798e2dcfc53e7d8738597618f525530",
634+
"size": 1738,
635+
"uri": "https://{canondata_backend}/1937424/d5801c5f9b3fed693a453918eecd6867c4180227/resource.tar.gz#test.test_expr-tzdate_result-default.txt-Debug_/opt.yql"
636636
}
637637
],
638638
"test.test[expr-tzdate_result-default.txt-Results]": [

yql/essentials/tests/sql/sql2yql/canondata/result.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,9 +3312,9 @@
33123312
],
33133313
"test_sql2yql.test[expr-tzdate_result]": [
33143314
{
3315-
"checksum": "d9e70a97bb5dcd9ea59c1689b0c83669",
3316-
"size": 4337,
3317-
"uri": "https://{canondata_backend}/1942173/99e88108149e222741552e7e6cddef041d6a2846/resource.tar.gz#test_sql2yql.test_expr-tzdate_result_/sql.yql"
3315+
"checksum": "25714e036675294420faf7d4747a19b5",
3316+
"size": 4385,
3317+
"uri": "https://{canondata_backend}/1937424/0282bf99f985d9dd5cf648994fc10170e7f998c8/resource.tar.gz#test_sql2yql.test_expr-tzdate_result_/sql.yql"
33183318
}
33193319
],
33203320
"test_sql2yql.test[expr-udaf_with_list_zip]": [

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

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ extern const char EndOfUDF[] = "EndOf";
4949
extern const char ShiftYearsUDF[] = "ShiftYears";
5050
extern const char ShiftQuartersUDF[] = "ShiftQuarters";
5151
extern const char ShiftMonthsUDF[] = "ShiftMonths";
52+
extern const char ParseUDF[] = "Parse";
53+
extern const char Parse64UDF[] = "Parse64";
5254

5355
extern const char TMResourceName[] = "DateTime2.TM";
5456
extern const char TM64ResourceName[] = "DateTime2.TM64";
@@ -2942,33 +2944,42 @@ class TShift : public TBoxedValue {
29422944
const TSourcePosition Pos_;
29432945
};
29442946

2945-
template<size_t Digits>
2946-
struct ParseExaclyNDigits;
2947+
template<size_t Digits, bool Variable = false>
2948+
struct ParseNDigits;
29472949

2948-
template<>
2949-
struct ParseExaclyNDigits<0U> {
2950+
template<bool Variable>
2951+
struct ParseNDigits<0U, Variable> {
29502952
template <typename T>
29512953
static constexpr bool Do(std::string_view::const_iterator&, T&) {
29522954
return true;
29532955
}
29542956
};
29552957

2956-
template<size_t Digits>
2957-
struct ParseExaclyNDigits {
2958+
template<size_t Digits, bool Variable>
2959+
struct ParseNDigits {
29582960
template <typename T>
29592961
static constexpr bool Do(std::string_view::const_iterator& it, T& out) {
29602962
const auto d = *it;
29612963
if (!std::isdigit(d)) {
2964+
// XXX: If the current char is not a digit, the
2965+
// parsing succeeds iff there are no more digits
2966+
// to be parsed (see the class specialization
2967+
// above) or there are given less than N digits
2968+
// to be parsed.
2969+
if constexpr (Variable) {
2970+
return true;
2971+
}
29622972
return false;
29632973
}
29642974
out *= 10U;
29652975
out += d - '0';
2966-
return ParseExaclyNDigits<Digits - 1U>::Do(++it, out);
2976+
return ParseNDigits<Digits - 1U, Variable>::Do(++it, out);
29672977
}
29682978
};
29692979

29702980
// Parse
29712981

2982+
template<const char* TUdfName, const char* TResourceName>
29722983
class TParse : public TBoxedValue {
29732984
public:
29742985
class TFactory : public TBoxedValue {
@@ -2988,7 +2999,7 @@ class TShift : public TBoxedValue {
29882999
};
29893000

29903001
static const TStringRef& Name() {
2991-
static auto name = TStringRef::Of("Parse");
3002+
static auto name = TStringRef(TUdfName, std::strlen(TUdfName));
29923003
return name;
29933004
}
29943005

@@ -3002,15 +3013,10 @@ class TShift : public TBoxedValue {
30023013
return false;
30033014
}
30043015

3005-
auto resourceType = builder.Resource(TMResourceName);
3006-
auto optionalResourceType = builder.Optional()->Item(resourceType).Build();
3007-
3008-
builder.Args()->Add<char*>().Flags(ICallablePayload::TArgumentFlags::AutoMap)
3009-
.Add(builder.Optional()->Item<ui16>())
3010-
.Done()
3011-
.OptionalArgs(1);
3012-
builder.RunConfig<char*>().Returns(optionalResourceType);
3013-
3016+
builder.OptionalArgs(1).Args()->Add<char*>()
3017+
.template Add<TOptional<ui16>>();
3018+
builder.Returns(
3019+
builder.SimpleSignatureType<TOptional<TResource<TResourceName>>(TAutoMap<char*>)>());
30143020
if (!typesOnly) {
30153021
builder.Implementation(new TParse::TFactory(builder.GetSourcePosition()));
30163022
}
@@ -3046,7 +3052,7 @@ class TShift : public TBoxedValue {
30463052
const std::string_view buffer = args[0].AsStringRef();
30473053

30483054
TUnboxedValuePod result(0);
3049-
auto& storage = Reference(result);
3055+
auto& storage = Reference<TResourceName>(result);
30503056
storage.MakeDefault();
30513057

30523058
auto& builder = valueBuilder->GetDateBuilder();
@@ -3098,13 +3104,27 @@ class TShift : public TBoxedValue {
30983104
break;
30993105

31003106
case 'Y': {
3101-
static constexpr size_t size = 4;
31023107
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
3103-
ui32 year = 0U;
3104-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, year) || !ValidateYear(year)) {
3105-
return false;
3108+
if constexpr (TResourceName == TMResourceName) {
3109+
static constexpr size_t size = 4;
3110+
ui32 year = 0U;
3111+
if (limit < size || !ParseNDigits<size>::Do(it, year) || !ValidateYear(year)) {
3112+
return false;
3113+
}
3114+
SetYear<TMResourceName>(result, year);
3115+
} else {
3116+
static constexpr size_t size = 6;
3117+
i64 year = 0LL;
3118+
i64 negative = 1LL;
3119+
if (*it == '-') {
3120+
negative = -1LL;
3121+
it++;
3122+
}
3123+
if (!ParseNDigits<size, true>::Do(it, year) || !ValidateYear(negative * year)) {
3124+
return false;
3125+
}
3126+
SetYear<TM64ResourceName>(result, negative * year);
31063127
}
3107-
SetYear(result, year);
31083128
return true;
31093129
});
31103130
break;
@@ -3113,10 +3133,10 @@ class TShift : public TBoxedValue {
31133133
static constexpr size_t size = 2;
31143134
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
31153135
ui32 month = 0U;
3116-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, month) || !ValidateMonth(month)) {
3136+
if (limit < size || !ParseNDigits<size>::Do(it, month) || !ValidateMonth(month)) {
31173137
return false;
31183138
}
3119-
SetMonth(result, month);
3139+
SetMonth<TResourceName>(result, month);
31203140
return true;
31213141
});
31223142
break;
@@ -3125,10 +3145,10 @@ class TShift : public TBoxedValue {
31253145
static constexpr size_t size = 2;
31263146
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
31273147
ui32 day = 0U;
3128-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, day) || !ValidateDay(day)) {
3148+
if (limit < size || !ParseNDigits<size>::Do(it, day) || !ValidateDay(day)) {
31293149
return false;
31303150
}
3131-
SetDay(result, day);
3151+
SetDay<TResourceName>(result, day);
31323152
return true;
31333153
});
31343154
break;
@@ -3137,10 +3157,10 @@ class TShift : public TBoxedValue {
31373157
static constexpr size_t size = 2;
31383158
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
31393159
ui32 hour = 0U;
3140-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, hour) || !ValidateHour(hour)) {
3160+
if (limit < size || !ParseNDigits<size>::Do(it, hour) || !ValidateHour(hour)) {
31413161
return false;
31423162
}
3143-
SetHour(result, hour);
3163+
SetHour<TResourceName>(result, hour);
31443164
return true;
31453165
});
31463166
break;
@@ -3149,10 +3169,10 @@ class TShift : public TBoxedValue {
31493169
static constexpr size_t size = 2;
31503170
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
31513171
ui32 minute = 0U;
3152-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, minute) || !ValidateMinute(minute)) {
3172+
if (limit < size || !ParseNDigits<size>::Do(it, minute) || !ValidateMinute(minute)) {
31533173
return false;
31543174
}
3155-
SetMinute(result, minute);
3175+
SetMinute<TResourceName>(result, minute);
31563176
return true;
31573177
});
31583178
break;
@@ -3161,10 +3181,10 @@ class TShift : public TBoxedValue {
31613181
static constexpr size_t size = 2;
31623182
Scanners_.emplace_back([](std::string_view::const_iterator& it, size_t limit, TUnboxedValuePod& result, const IDateBuilder&) {
31633183
ui32 second = 0U;
3164-
if (limit < size || !ParseExaclyNDigits<size>::Do(it, second) || !ValidateSecond(second)) {
3184+
if (limit < size || !ParseNDigits<size>::Do(it, second) || !ValidateSecond(second)) {
31653185
return false;
31663186
}
3167-
SetSecond(result, second);
3187+
SetSecond<TResourceName>(result, second);
31683188
limit -= size;
31693189

31703190
if (!limit || *it != '.') {
@@ -3190,7 +3210,7 @@ class TShift : public TBoxedValue {
31903210
while (digits--) {
31913211
usec *= 10U;
31923212
}
3193-
SetMicrosecond(result, usec);
3213+
SetMicrosecond<TResourceName>(result, usec);
31943214
return true;
31953215
});
31963216
break;
@@ -3208,7 +3228,7 @@ class TShift : public TBoxedValue {
32083228
if (!builder.FindTimezoneId(TStringRef(&*start, size), timezoneId)) {
32093229
return false;
32103230
}
3211-
SetTimezoneId(result, timezoneId);
3231+
SetTimezoneId<TResourceName>(result, timezoneId);
32123232
return true;
32133233
});
32143234
break;
@@ -3227,7 +3247,7 @@ class TShift : public TBoxedValue {
32273247
if (cnt < size || !ValidateMonthShortName(monthName, month)) {
32283248
return false;
32293249
}
3230-
SetMonth(result, month);
3250+
SetMonth<TResourceName>(result, month);
32313251
return true;
32323252
});
32333253
break;
@@ -3247,7 +3267,7 @@ class TShift : public TBoxedValue {
32473267
if (!ValidateMonthFullName(monthName, month)) {
32483268
return false;
32493269
}
3250-
SetMonth(result, month);
3270+
SetMonth<TResourceName>(result, month);
32513271
return true;
32523272
});
32533273
break;
@@ -3390,7 +3410,8 @@ class TShift : public TBoxedValue {
33903410
TToUnits<ToMicrosecondsUDF, ui64, 1000000>,
33913411

33923412
TFormat,
3393-
TParse,
3413+
TParse<ParseUDF, TMResourceName>,
3414+
TParse<Parse64UDF, TM64ResourceName>,
33943415

33953416
TParseRfc822,
33963417
TParseIso8601,

yql/essentials/udfs/common/datetime2/test_bigdates/canondata/result.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
"uri": "file://test.test_From_/results.txt"
1010
}
1111
],
12+
"test.test[Parse64]": [
13+
{
14+
"uri": "file://test.test_Parse64_/results.txt"
15+
}
16+
],
1217
"test.test[SplitMake]": [
1318
{
1419
"uri": "file://test.test_SplitMake_/results.txt"

0 commit comments

Comments
 (0)