Skip to content

Commit 900e106

Browse files
committed
feat: construct temporal values from structural inputs
1 parent 9fa0d15 commit 900e106

File tree

7 files changed

+378
-48
lines changed

7 files changed

+378
-48
lines changed

src/iceberg/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ add_iceberg_test(util_test
105105
endian_test.cc
106106
formatter_test.cc
107107
string_util_test.cc
108+
temporal_util_test.cc
108109
truncate_util_test.cc
109110
uuid_test.cc
110111
visit_type_test.cc)

src/iceberg/test/bucket_util_test.cc

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <gtest/gtest.h>
2525

2626
#include "iceberg/util/decimal.h"
27+
#include "iceberg/util/temporal_util.h"
2728
#include "iceberg/util/uuid.h"
2829

2930
namespace iceberg {
@@ -41,27 +42,54 @@ TEST(BucketUtilsTest, HashHelper) {
4142
EXPECT_EQ(BucketUtils::HashBytes(decimal->ToBigEndian()), -500754589);
4243

4344
// date hash
44-
std::chrono::sys_days sd = std::chrono::year{2017} / 11 / 16;
45-
std::chrono::sys_days epoch{std::chrono::year{1970} / 1 / 1};
46-
int32_t days = (sd - epoch).count();
47-
EXPECT_EQ(BucketUtils::HashInt(days), -653330422);
45+
EXPECT_EQ(BucketUtils::HashInt(
46+
TemporalUtils::CreateDate({.year = 2017, .month = 11, .day = 16})),
47+
-653330422);
4848

4949
// time
50-
// 22:31:08 in microseconds
51-
int64_t time_micros = (22 * 3600 + 31 * 60 + 8) * 1000000LL;
52-
EXPECT_EQ(BucketUtils::HashLong(time_micros), -662762989);
50+
EXPECT_EQ(BucketUtils::HashLong(
51+
TemporalUtils::CreateTime({.hour = 22, .minute = 31, .second = 8})),
52+
-662762989);
5353

5454
// timestamp
5555
// 2017-11-16T22:31:08 in microseconds
56-
std::chrono::system_clock::time_point tp =
57-
std::chrono::sys_days{std::chrono::year{2017} / 11 / 16} + std::chrono::hours{22} +
58-
std::chrono::minutes{31} + std::chrono::seconds{8};
59-
int64_t timestamp_micros =
60-
std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch())
61-
.count();
62-
EXPECT_EQ(BucketUtils::HashLong(timestamp_micros), -2047944441);
56+
EXPECT_EQ(
57+
BucketUtils::HashLong(TemporalUtils::CreateTimestamp(
58+
{.year = 2017, .month = 11, .day = 16, .hour = 22, .minute = 31, .second = 8})),
59+
-2047944441);
60+
6361
// 2017-11-16T22:31:08.000001 in microseconds
64-
EXPECT_EQ(BucketUtils::HashLong(timestamp_micros + 1), -1207196810);
62+
EXPECT_EQ(BucketUtils::HashLong(TemporalUtils::CreateTimestamp({.year = 2017,
63+
.month = 11,
64+
.day = 16,
65+
.hour = 22,
66+
.minute = 31,
67+
.second = 8,
68+
.microsecond = 1})),
69+
-1207196810);
70+
71+
// 2017-11-16T14:31:08-08:00 in microseconds
72+
EXPECT_EQ(BucketUtils::HashLong(
73+
TemporalUtils::CreateTimestampTz({.year = 2017,
74+
.month = 11,
75+
.day = 16,
76+
.hour = 14,
77+
.minute = 31,
78+
.second = 8,
79+
.tz_offset_minutes = -480})),
80+
-2047944441);
81+
82+
// 2017-11-16T14:31:08.000001-08:00 in microseconds
83+
EXPECT_EQ(BucketUtils::HashLong(
84+
TemporalUtils::CreateTimestampTz({.year = 2017,
85+
.month = 11,
86+
.day = 16,
87+
.hour = 14,
88+
.minute = 31,
89+
.second = 8,
90+
.microsecond = 1,
91+
.tz_offset_minutes = -480})),
92+
-1207196810);
6593

6694
// string
6795
std::string str = "iceberg";

src/iceberg/test/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ iceberg_tests = {
7474
'endian_test.cc',
7575
'formatter_test.cc',
7676
'string_util_test.cc',
77+
'temporal_util_test.cc',
7778
'truncate_util_test.cc',
7879
'uuid_test.cc',
7980
'visit_type_test.cc',
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "iceberg/util/temporal_util.h"
21+
22+
#include <gtest/gtest.h>
23+
24+
namespace iceberg {
25+
26+
TEST(TemporalUtilTest, CreateDate) {
27+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 1970, .month = 1, .day = 1}), 0);
28+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 1970, .month = 1, .day = 2}), 1);
29+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 1969, .month = 12, .day = 31}), -1);
30+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 2000, .month = 1, .day = 1}), 10957);
31+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 2017, .month = 11, .day = 16}), 17486);
32+
EXPECT_EQ(TemporalUtils::CreateDate({.year = 2052, .month = 2, .day = 20}), 30000);
33+
}
34+
35+
TEST(TemporalUtilTest, CreateTime) {
36+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 0, .minute = 0, .second = 0}), 0);
37+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 1, .minute = 0, .second = 0}),
38+
3600000000LL);
39+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 0, .minute = 1, .second = 0}), 60000000LL);
40+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 0, .minute = 0, .second = 1}), 1000000LL);
41+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 22, .minute = 31, .second = 8}),
42+
81068000000LL);
43+
EXPECT_EQ(TemporalUtils::CreateTime({.hour = 23, .minute = 59, .second = 59}),
44+
86399000000LL);
45+
EXPECT_EQ(
46+
TemporalUtils::CreateTime({.hour = 0, .minute = 0, .second = 0, .microsecond = 1}),
47+
1LL);
48+
EXPECT_EQ(TemporalUtils::CreateTime(
49+
{.hour = 0, .minute = 0, .second = 0, .microsecond = 999999}),
50+
999999LL);
51+
EXPECT_EQ(
52+
TemporalUtils::CreateTime({.hour = 0, .minute = 0, .second = 1, .microsecond = 1}),
53+
1000001LL);
54+
EXPECT_EQ(TemporalUtils::CreateTime(
55+
{.hour = 23, .minute = 59, .second = 59, .microsecond = 999999}),
56+
86399999999LL);
57+
}
58+
59+
TEST(TemporalUtilTest, CreateTimestamp) {
60+
EXPECT_EQ(
61+
TemporalUtils::CreateTimestamp(
62+
{.year = 1970, .month = 1, .day = 1, .hour = 0, .minute = 0, .second = 0}),
63+
0LL);
64+
EXPECT_EQ(
65+
TemporalUtils::CreateTimestamp(
66+
{.year = 1970, .month = 1, .day = 2, .hour = 0, .minute = 0, .second = 0}),
67+
86400000000LL);
68+
EXPECT_EQ(
69+
TemporalUtils::CreateTimestamp(
70+
{.year = 1969, .month = 12, .day = 31, .hour = 23, .minute = 59, .second = 59}),
71+
-1000000LL);
72+
EXPECT_EQ(
73+
TemporalUtils::CreateTimestamp(
74+
{.year = 2000, .month = 1, .day = 1, .hour = 0, .minute = 0, .second = 0}),
75+
946684800000000LL);
76+
EXPECT_EQ(
77+
TemporalUtils::CreateTimestamp(
78+
{.year = 2017, .month = 11, .day = 16, .hour = 22, .minute = 31, .second = 8}),
79+
1510871468000000LL);
80+
EXPECT_EQ(TemporalUtils::CreateTimestamp({.year = 2017,
81+
.month = 11,
82+
.day = 16,
83+
.hour = 22,
84+
.minute = 31,
85+
.second = 8,
86+
.microsecond = 1}),
87+
1510871468000001LL);
88+
EXPECT_EQ(TemporalUtils::CreateTimestamp({.year = 2023,
89+
.month = 10,
90+
.day = 5,
91+
.hour = 15,
92+
.minute = 45,
93+
.second = 30,
94+
.microsecond = 123456}),
95+
1696520730123456LL);
96+
}
97+
98+
TEST(TemporalUtilTest, CreateTimestampTz) {
99+
EXPECT_EQ(TemporalUtils::CreateTimestampTz({.year = 2017,
100+
.month = 11,
101+
.day = 16,
102+
.hour = 14,
103+
.minute = 31,
104+
.second = 8,
105+
.tz_offset_minutes = -480}),
106+
1510871468000000LL);
107+
EXPECT_EQ(TemporalUtils::CreateTimestampTz({.year = 2017,
108+
.month = 11,
109+
.day = 16,
110+
.hour = 14,
111+
.minute = 31,
112+
.second = 8,
113+
.microsecond = 1,
114+
.tz_offset_minutes = -480}),
115+
1510871468000001LL);
116+
EXPECT_EQ(TemporalUtils::CreateTimestampTz({.year = 2023,
117+
.month = 10,
118+
.day = 5,
119+
.hour = 15,
120+
.minute = 45,
121+
.second = 30,
122+
.microsecond = 123456,
123+
.tz_offset_minutes = 60}),
124+
1696517130123456LL);
125+
EXPECT_EQ(TemporalUtils::CreateTimestampTz({.year = 2023,
126+
.month = 10,
127+
.day = 5,
128+
.hour = 15,
129+
.minute = 45,
130+
.second = 30,
131+
.microsecond = 123456,
132+
.tz_offset_minutes = -60}),
133+
1696524330123456LL);
134+
}
135+
136+
TEST(TemporalUtilTest, CreateTimestampNanos) {
137+
EXPECT_EQ(
138+
TemporalUtils::CreateTimestampNanos(
139+
{.year = 2017, .month = 11, .day = 16, .hour = 22, .minute = 31, .second = 8}),
140+
1510871468000000000LL);
141+
EXPECT_EQ(TemporalUtils::CreateTimestampNanos({.year = 2017,
142+
.month = 11,
143+
.day = 16,
144+
.hour = 22,
145+
.minute = 31,
146+
.second = 8,
147+
.nanosecond = 1}),
148+
1510871468000000001LL);
149+
}
150+
151+
TEST(TemporalUtilTest, CreateTimestampTzNanos) {
152+
EXPECT_EQ(TemporalUtils::CreateTimestampTzNanos({.year = 2017,
153+
.month = 11,
154+
.day = 16,
155+
.hour = 14,
156+
.minute = 31,
157+
.second = 8,
158+
.tz_offset_minutes = -480}),
159+
1510871468000000000LL);
160+
EXPECT_EQ(TemporalUtils::CreateTimestampTzNanos({.year = 2017,
161+
.month = 11,
162+
.day = 16,
163+
.hour = 14,
164+
.minute = 31,
165+
.second = 8,
166+
.nanosecond = 1,
167+
.tz_offset_minutes = -480}),
168+
1510871468000000001LL);
169+
}
170+
171+
} // namespace iceberg

0 commit comments

Comments
 (0)