Skip to content

Commit caaeec5

Browse files
committed
Fix parsing ofinterval literals
commit_hash:a5558c14a89e996bafff7c980065e2280278f294 (cherry picked from commit b2829f5)
1 parent 36218ce commit caaeec5

File tree

8 files changed

+112
-24
lines changed

8 files changed

+112
-24
lines changed

yql/essentials/minikql/mkql_type_ops.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,8 +2223,8 @@ NUdf::TUnboxedValuePod ParseTzTimestamp(NUdf::TStringRef str) {
22232223
}
22242224
}
22252225

2226-
template <bool DecimalPart = false, i8 MaxDigits = 6>
2227-
bool ParseNumber(std::string_view::const_iterator& pos, const std::string_view& buf, ui32& value) {
2226+
template <bool DecimalPart, ui8 MaxDigits>
2227+
bool ParseNumber(std::string_view::const_iterator& pos, const std::string_view& buf, ui64& value) {
22282228
value = 0U;
22292229

22302230
if (buf.cend() == pos || !std::isdigit(*pos)) {
@@ -2263,10 +2263,16 @@ NUdf::TUnboxedValuePod ParseInterval(const std::string_view& buf) {
22632263
return NUdf::TUnboxedValuePod();
22642264
}
22652265

2266-
std::optional<ui32> days, hours, minutes, seconds, microseconds;
2267-
ui32 num;
2266+
std::optional<ui64> days, hours, minutes, seconds, microseconds;
2267+
ui64 num;
22682268

22692269
if (*pos != 'T') {
2270+
// Estimated upper bound for number of digits in the
2271+
// numeric representation of days (weeks need less).
2272+
// * Interval: MAX_DATE (49673) = 5 digits.
2273+
// * Interval64: MAX_DATE32 - MIN_DATE32 (106751616) = 9 digits.
2274+
// So, 9 digits is maximum for any interval component with
2275+
// granularity more than a day.
22702276
if (!ParseNumber<false, 9>(pos, buf, num)) {
22712277
return NUdf::TUnboxedValuePod();
22722278
}
@@ -2289,7 +2295,14 @@ NUdf::TUnboxedValuePod ParseInterval(const std::string_view& buf) {
22892295

22902296
if (buf.cend() != pos) // TODO: Remove this line later.
22912297
do {
2292-
if (!ParseNumber(pos, buf, num)) {
2298+
// Estimated upper bound for number of digits in the
2299+
// numeric representation of seconds (hours, minutes,
2300+
// microseconds need less).
2301+
// * Interval: MAX_DATETIME (4291747200) = 10 digits.
2302+
// * Interval64: MAX_DATETIME64 - MIN_DATETIME64 (9223339708799) = 13 digits.
2303+
// So, 13 digits is maximum for any interval component with
2304+
// granularity less than a day.
2305+
if (!ParseNumber<false, 13>(pos, buf, num)) {
22932306
return NUdf::TUnboxedValuePod();
22942307
}
22952308

@@ -2317,7 +2330,8 @@ NUdf::TUnboxedValuePod ParseInterval(const std::string_view& buf) {
23172330
return NUdf::TUnboxedValuePod();
23182331
}
23192332
seconds = num;
2320-
if (!ParseNumber<true>(pos, buf, num) || *pos++ != 'S') {
2333+
// 6 digits is maximum for microseconds representation.
2334+
if (!ParseNumber<true, 6>(pos, buf, num) || *pos++ != 'S') {
23212335
return NUdf::TUnboxedValuePod();
23222336
}
23232337
microseconds = num;

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,16 @@
298298
],
299299
"test.test[bigdate-input_interval64-default.txt-Debug]": [
300300
{
301-
"checksum": "632ffcd579b1f6bbf48e367ec38e0f27",
302-
"size": 6397,
303-
"uri": "https://{canondata_backend}/1031349/5d9a68084ecc9d27b7e5271088a725bb2d294cc6/resource.tar.gz#test.test_bigdate-input_interval64-default.txt-Debug_/opt.yql"
301+
"checksum": "ed3ffc93b25ff8a71b6e6659ce05acd7",
302+
"size": 7477,
303+
"uri": "https://{canondata_backend}/1031349/aa434f3964bbcd36b9d29e1bd64ac6be96249ceb/resource.tar.gz#test.test_bigdate-input_interval64-default.txt-Debug_/opt.yql"
304304
}
305305
],
306306
"test.test[bigdate-input_interval64-default.txt-Results]": [
307307
{
308-
"checksum": "c78332dfea021a025164772dffe9ba99",
309-
"size": 48883,
310-
"uri": "https://{canondata_backend}/1031349/5d9a68084ecc9d27b7e5271088a725bb2d294cc6/resource.tar.gz#test.test_bigdate-input_interval64-default.txt-Results_/results.txt"
308+
"checksum": "5f8fd7865d7554bf3849cf7408f7b752",
309+
"size": 57256,
310+
"uri": "https://{canondata_backend}/1031349/aa434f3964bbcd36b9d29e1bd64ac6be96249ceb/resource.tar.gz#test.test_bigdate-input_interval64-default.txt-Results_/results.txt"
311311
}
312312
],
313313
"test.test[bigdate-output_timestamp64-default.txt-Debug]": [

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,16 +358,16 @@
358358
],
359359
"test.test[datetime-date_in-default.txt-Debug]": [
360360
{
361-
"checksum": "d0c478d299d9317c9796a5a5689ea5ea",
362-
"size": 5307,
363-
"uri": "https://{canondata_backend}/1946324/ea335e4b9e4a11417f24b451ef1085a63908db10/resource.tar.gz#test.test_datetime-date_in-default.txt-Debug_/opt.yql"
361+
"checksum": "3e6ba7312997f15d807aa25613e84db6",
362+
"size": 6390,
363+
"uri": "https://{canondata_backend}/1689644/ad5d4ca8c2d76550a459d4741259163b48e36d05/resource.tar.gz#test.test_datetime-date_in-default.txt-Debug_/opt.yql"
364364
}
365365
],
366366
"test.test[datetime-date_in-default.txt-Results]": [
367367
{
368-
"checksum": "ec449bd5df1be1823e71d727d04cc6a0",
369-
"size": 38190,
370-
"uri": "https://{canondata_backend}/1946324/ea335e4b9e4a11417f24b451ef1085a63908db10/resource.tar.gz#test.test_datetime-date_in-default.txt-Results_/results.txt"
368+
"checksum": "2a6bd274cc5f3511fd4c04b0b023a275",
369+
"size": 46190,
370+
"uri": "https://{canondata_backend}/1689644/ad5d4ca8c2d76550a459d4741259163b48e36d05/resource.tar.gz#test.test_datetime-date_in-default.txt-Results_/results.txt"
371371
}
372372
],
373373
"test.test[datetime-date_tz_bounds_scale-default.txt-Debug]": [

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,9 +1135,9 @@
11351135
],
11361136
"test_sql2yql.test[bigdate-input_interval64]": [
11371137
{
1138-
"checksum": "46d987122b7fe9750e1b1f0ce5e4fc84",
1139-
"size": 37353,
1140-
"uri": "https://{canondata_backend}/1942173/99e88108149e222741552e7e6cddef041d6a2846/resource.tar.gz#test_sql2yql.test_bigdate-input_interval64_/sql.yql"
1138+
"checksum": "b4321aecb81505bfab6638a0d276e6a0",
1139+
"size": 43605,
1140+
"uri": "https://{canondata_backend}/1689644/d756eb6544cfd8c72af37ed4481b21fa67255f71/resource.tar.gz#test_sql2yql.test_bigdate-input_interval64_/sql.yql"
11411141
}
11421142
],
11431143
"test_sql2yql.test[bigdate-input_timestamp64]": [
@@ -2094,9 +2094,9 @@
20942094
],
20952095
"test_sql2yql.test[datetime-date_in]": [
20962096
{
2097-
"checksum": "68c9e3557926f3a6b12d602e682e9558",
2098-
"size": 29101,
2099-
"uri": "https://{canondata_backend}/1942173/99e88108149e222741552e7e6cddef041d6a2846/resource.tar.gz#test_sql2yql.test_datetime-date_in_/sql.yql"
2097+
"checksum": "f042635815e0ece3c9aa69a5cc35c44f",
2098+
"size": 35323,
2099+
"uri": "https://{canondata_backend}/1809005/d23a86a41976b5deadc93862c9d4b33c732d638d/resource.tar.gz#test_sql2yql.test_datetime-date_in_/sql.yql"
21002100
}
21012101
],
21022102
"test_sql2yql.test[datetime-date_out]": [

yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_bigdate-input_interval64_/formatted.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,21 @@ SELECT
8888
CAST(CAST('P106751616D' AS interval64) AS string)
8989
;
9090

91+
SELECT
92+
CAST('-P106751616D' AS interval64),
93+
CAST(CAST('-P106751616D' AS interval64) AS string)
94+
;
95+
9196
SELECT
9297
CAST('P106751617D' AS interval64),
9398
CAST(CAST('P106751617D' AS interval64) AS string)
9499
;
95100

101+
SELECT
102+
CAST('-P106751617D' AS interval64),
103+
CAST(CAST('-P106751617D' AS interval64) AS string)
104+
;
105+
96106
SELECT
97107
CAST('P15250230W' AS interval64),
98108
CAST(CAST('P15250230W' AS interval64) AS string)
@@ -103,6 +113,26 @@ SELECT
103113
CAST(CAST('P15250231W' AS interval64) AS string)
104114
;
105115

116+
SELECT
117+
CAST('PT9223339708799S' AS interval64),
118+
CAST(CAST('PT9223339708799S' AS interval64) AS string)
119+
;
120+
121+
SELECT
122+
CAST('-PT9223339708799S' AS interval64),
123+
CAST(CAST('-PT9223339708799S' AS interval64) AS string)
124+
;
125+
126+
SELECT
127+
CAST('PT9223339708800S' AS interval64),
128+
CAST(CAST('PT9223339708800S' AS interval64) AS string)
129+
;
130+
131+
SELECT
132+
CAST('-PT9223339708800S' AS interval64),
133+
CAST(CAST('-PT9223339708800S' AS interval64) AS string)
134+
;
135+
106136
SELECT
107137
CAST('PT0000000S' AS interval64),
108138
CAST(CAST('PT0000000S' AS interval64) AS string)

yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_datetime-date_in_/formatted.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,37 @@ SELECT
134134
CAST(CAST('P49672DT23H59M59.999999S' AS interval) AS string)
135135
;
136136

137+
SELECT
138+
CAST('-P49672DT23H59M59.999999S' AS interval),
139+
CAST(CAST('-P49672DT23H59M59.999999S' AS interval) AS string)
140+
;
141+
137142
SELECT
138143
CAST('P49673D' AS interval),
139144
CAST(CAST('P49673D' AS interval) AS string)
140145
;
146+
147+
SELECT
148+
CAST('-P49673D' AS interval),
149+
CAST(CAST('-P49673D' AS interval) AS string)
150+
;
151+
152+
SELECT
153+
CAST('PT4291747199S' AS interval),
154+
CAST(CAST('PT4291747199S' AS interval) AS string)
155+
;
156+
157+
SELECT
158+
CAST('-PT4291747199S' AS interval),
159+
CAST(CAST('-PT4291747199S' AS interval) AS string)
160+
;
161+
162+
SELECT
163+
CAST('PT4291747200S' AS interval),
164+
CAST(CAST('PT4291747200S' AS interval) AS string)
165+
;
166+
167+
SELECT
168+
CAST('-PT4291747200S' AS interval),
169+
CAST(CAST('-PT4291747200S' AS interval) AS string)
170+
;

yql/essentials/tests/sql/suites/bigdate/input_interval64.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,17 @@ select cast("PT999999M" as interval64), cast(cast("PT999999M" as interval64) as
2121
select cast("PT999999H" as interval64), cast(cast("PT999999H" as interval64) as string);
2222

2323
select cast("P106751616D" as interval64), cast(cast("P106751616D" as interval64) as string);
24+
select cast("-P106751616D" as interval64), cast(cast("-P106751616D" as interval64) as string);
2425
select cast("P106751617D" as interval64), cast(cast("P106751617D" as interval64) as string);
26+
select cast("-P106751617D" as interval64), cast(cast("-P106751617D" as interval64) as string);
2527
select cast("P15250230W" as interval64), cast(cast("P15250230W" as interval64) as string);
2628
select cast("P15250231W" as interval64), cast(cast("P15250231W" as interval64) as string);
2729

30+
select cast("PT9223339708799S" as interval64), cast(cast("PT9223339708799S" as interval64) as string);
31+
select cast("-PT9223339708799S" as interval64), cast(cast("-PT9223339708799S" as interval64) as string);
32+
select cast("PT9223339708800S" as interval64), cast(cast("PT9223339708800S" as interval64) as string);
33+
select cast("-PT9223339708800S" as interval64), cast(cast("-PT9223339708800S" as interval64) as string);
34+
2835
select cast("PT0000000S" as interval64), cast(cast("PT0000000S" as interval64) as string);
2936
select cast("PT0000000M" as interval64), cast(cast("PT0000000M" as interval64) as string);
3037
select cast("PT0000000H" as interval64), cast(cast("PT0000000H" as interval64) as string);

yql/essentials/tests/sql/suites/datetime/date_in.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,11 @@ select cast("2105-12-31T23:59:59.999999Z" as timestamp),cast(cast("2105-12-31T23
3232
select cast("2106-01-01T00:00:00.000000Z" as timestamp),cast(cast("2106-01-01T00:00:00.000000Z" as timestamp) as string);
3333

3434
select cast("P49672DT23H59M59.999999S" as interval),cast(cast("P49672DT23H59M59.999999S" as interval) as string);
35+
select cast("-P49672DT23H59M59.999999S" as interval),cast(cast("-P49672DT23H59M59.999999S" as interval) as string);
3536
select cast("P49673D" as interval),cast(cast("P49673D" as interval) as string);
37+
select cast("-P49673D" as interval),cast(cast("-P49673D" as interval) as string);
38+
39+
select cast("PT4291747199S" as interval),cast(cast("PT4291747199S" as interval) as string);
40+
select cast("-PT4291747199S" as interval),cast(cast("-PT4291747199S" as interval) as string);
41+
select cast("PT4291747200S" as interval),cast(cast("PT4291747200S" as interval) as string);
42+
select cast("-PT4291747200S" as interval),cast(cast("-PT4291747200S" as interval) as string);

0 commit comments

Comments
 (0)