@@ -17,9 +17,27 @@ using namespace arrow;
17
17
using namespace odbcabstraction ;
18
18
19
19
TEST (TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) {
20
- std::vector<int64_t > values = {86400370 , 172800000 , 259200000 , 1649793238110LL ,
21
- 345600000 , 432000000 , 518400000 };
22
-
20
+ std::vector<int64_t > values = {86400370 , 172800000 , 259200000 , 1649793238110LL , 345600000 ,
21
+ 432000000 , 518400000 , -86399000 , 0 , -86399999 , -86399001 ,
22
+ 86400001 , 86400999 };
23
+ std::vector<TIMESTAMP_STRUCT> expected = {
24
+ /* year(16), month(u16), day(u16), hour(u16), minute(u16), second(u16), fraction(u32) */
25
+ {1970 , 1 , 2 , 0 , 0 , 0 , 370000000 },
26
+ {1970 , 1 , 3 , 0 , 0 , 0 , 0 },
27
+ {1970 , 1 , 4 , 0 , 0 , 0 , 0 },
28
+ {2022 , 4 , 12 , 19 , 53 , 58 , 110000000 },
29
+ {1970 , 1 , 5 , 0 , 0 , 0 , 0 },
30
+ {1970 , 1 , 6 , 0 , 0 , 0 , 0 },
31
+ {1970 , 1 , 7 , 0 , 0 , 0 , 0 },
32
+ {1969 , 12 , 31 , 0 , 0 , 1 , 0 },
33
+ {1970 , 1 , 1 , 0 , 0 , 0 , 0 },
34
+ /* Tests both ends of the fraction rounding range to ensure we don't tip the wrong way */
35
+ {1969 , 12 , 31 , 0 , 0 , 0 , 1000000 },
36
+ {1969 , 12 , 31 , 0 , 0 , 0 , 999000000 },
37
+ {1970 , 1 , 2 , 0 , 0 , 0 , 1000000 },
38
+ {1970 , 1 , 2 , 0 , 0 , 0 , 999000000 },
39
+ };
40
+
23
41
std::shared_ptr<Array> timestamp_array;
24
42
25
43
auto timestamp_field = field (" timestamp_field" , timestamp (TimeUnit::MILLI));
@@ -40,26 +58,31 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) {
40
58
for (size_t i = 0 ; i < values.size (); ++i) {
41
59
ASSERT_EQ (sizeof (TIMESTAMP_STRUCT), strlen_buffer[i]);
42
60
43
- tm date{};
44
-
45
- auto converted_time = values[i] / MILLI_TO_SECONDS_DIVISOR;
46
- GetTimeForSecondsSinceEpoch (date, converted_time);
47
-
48
- ASSERT_EQ (buffer[i].year , 1900 + (date.tm_year ));
49
- ASSERT_EQ (buffer[i].month , date.tm_mon + 1 );
50
- ASSERT_EQ (buffer[i].day , date.tm_mday );
51
- ASSERT_EQ (buffer[i].hour , date.tm_hour );
52
- ASSERT_EQ (buffer[i].minute , date.tm_min );
53
- ASSERT_EQ (buffer[i].second , date.tm_sec );
54
-
55
- constexpr uint32_t NANOSECONDS_PER_MILLI = 1000000 ;
56
- ASSERT_EQ (buffer[i].fraction , (values[i] % MILLI_TO_SECONDS_DIVISOR) * NANOSECONDS_PER_MILLI);
61
+ ASSERT_EQ (buffer[i].year , expected[i].year );
62
+ ASSERT_EQ (buffer[i].month , expected[i].month );
63
+ ASSERT_EQ (buffer[i].day , expected[i].day );
64
+ ASSERT_EQ (buffer[i].hour , expected[i].hour );
65
+ ASSERT_EQ (buffer[i].minute , expected[i].minute );
66
+ ASSERT_EQ (buffer[i].second , expected[i].second );
67
+ ASSERT_EQ (buffer[i].fraction , expected[i].fraction );
57
68
}
58
69
}
59
70
60
71
TEST (TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) {
61
72
std::vector<int64_t > values = {86400 , 172800 , 259200 , 1649793238 ,
62
- 345600 , 432000 , 518400 };
73
+ 345600 , 432000 , 518400 , -86399 , 0 };
74
+ std::vector<TIMESTAMP_STRUCT> expected = {
75
+ /* year(16), month(u16), day(u16), hour(u16), minute(u16), second(u16), fraction(u32) */
76
+ {1970 , 1 , 2 , 0 , 0 , 0 , 0 },
77
+ {1970 , 1 , 3 , 0 , 0 , 0 , 0 },
78
+ {1970 , 1 , 4 , 0 , 0 , 0 , 0 },
79
+ {2022 , 4 , 12 , 19 , 53 , 58 , 0 },
80
+ {1970 , 1 , 5 , 0 , 0 , 0 , 0 },
81
+ {1970 , 1 , 6 , 0 , 0 , 0 , 0 },
82
+ {1970 , 1 , 7 , 0 , 0 , 0 , 0 },
83
+ {1969 , 12 , 31 , 0 , 0 , 1 , 0 },
84
+ {1970 , 1 , 1 , 0 , 0 , 0 , 0 },
85
+ };
63
86
64
87
std::shared_ptr<Array> timestamp_array;
65
88
@@ -81,23 +104,27 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) {
81
104
82
105
for (size_t i = 0 ; i < values.size (); ++i) {
83
106
ASSERT_EQ (sizeof (TIMESTAMP_STRUCT), strlen_buffer[i]);
84
- tm date{};
85
-
86
- auto converted_time = values[i];
87
- GetTimeForSecondsSinceEpoch (date, converted_time);
88
107
89
- ASSERT_EQ (buffer[i].year , 1900 + (date. tm_year ) );
90
- ASSERT_EQ (buffer[i].month , date. tm_mon + 1 );
91
- ASSERT_EQ (buffer[i].day , date. tm_mday );
92
- ASSERT_EQ (buffer[i].hour , date. tm_hour );
93
- ASSERT_EQ (buffer[i].minute , date. tm_min );
94
- ASSERT_EQ (buffer[i].second , date. tm_sec );
108
+ ASSERT_EQ (buffer[i].year , expected[i]. year );
109
+ ASSERT_EQ (buffer[i].month , expected[i]. month );
110
+ ASSERT_EQ (buffer[i].day , expected[i]. day );
111
+ ASSERT_EQ (buffer[i].hour , expected[i]. hour );
112
+ ASSERT_EQ (buffer[i].minute , expected[i]. minute );
113
+ ASSERT_EQ (buffer[i].second , expected[i]. second );
95
114
ASSERT_EQ (buffer[i].fraction , 0 );
96
115
}
97
116
}
98
117
99
118
TEST (TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) {
100
- std::vector<int64_t > values = {86400000000 , 1649793238000000 };
119
+ std::vector<int64_t > values = {0 , 86400000000 , 1649793238000000 , -86399999999 , -86399000001 };
120
+ std::vector<TIMESTAMP_STRUCT> expected = {
121
+ /* year(16), month(u16), day(u16), hour(u16), minute(u16), second(u16), fraction(u32) */
122
+ {1970 , 1 , 1 , 0 , 0 , 0 , 0 },
123
+ {1970 , 1 , 2 , 0 , 0 , 0 , 0 },
124
+ {2022 , 4 , 12 , 19 , 53 , 58 , 0 },
125
+ {1969 , 12 , 31 , 0 , 0 , 0 , 1000 },
126
+ {1969 , 12 , 31 , 0 , 0 , 0 , 999999000 },
127
+ };
101
128
102
129
std::shared_ptr<Array> timestamp_array;
103
130
@@ -120,24 +147,31 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) {
120
147
for (size_t i = 0 ; i < values.size (); ++i) {
121
148
ASSERT_EQ (sizeof (TIMESTAMP_STRUCT), strlen_buffer[i]);
122
149
123
- tm date{};
124
-
125
- auto converted_time = values[i] / MICRO_TO_SECONDS_DIVISOR;
126
- GetTimeForSecondsSinceEpoch (date, converted_time);
127
-
128
- ASSERT_EQ (buffer[i].year , 1900 + (date.tm_year ));
129
- ASSERT_EQ (buffer[i].month , date.tm_mon + 1 );
130
- ASSERT_EQ (buffer[i].day , date.tm_mday );
131
- ASSERT_EQ (buffer[i].hour , date.tm_hour );
132
- ASSERT_EQ (buffer[i].minute , date.tm_min );
133
- ASSERT_EQ (buffer[i].second , date.tm_sec );
134
- constexpr uint32_t MICROS_PER_NANO = 1000 ;
135
- ASSERT_EQ (buffer[i].fraction , (values[i] % MICRO_TO_SECONDS_DIVISOR) * MICROS_PER_NANO);
150
+ ASSERT_EQ (buffer[i].year , expected[i].year );
151
+ ASSERT_EQ (buffer[i].month , expected[i].month );
152
+ ASSERT_EQ (buffer[i].day , expected[i].day );
153
+ ASSERT_EQ (buffer[i].hour , expected[i].hour );
154
+ ASSERT_EQ (buffer[i].minute , expected[i].minute );
155
+ ASSERT_EQ (buffer[i].second , expected[i].second );
156
+ ASSERT_EQ (buffer[i].fraction , expected[i].fraction );
136
157
}
137
158
}
138
159
139
160
TEST (TEST_TIMESTAMP, TIMESTAMP_WITH_NANO) {
140
- std::vector<int64_t > values = {86400000010000 , 1649793238000000000 };
161
+ std::vector<int64_t > values = {86400000010000 , 1649793238000000000 , -86399999999999 , -86399000000001 ,
162
+ 86400000000001 , 86400999999999 , 0 , -9223372036000000001 };
163
+ std::vector<TIMESTAMP_STRUCT> expected = {
164
+ /* year(16), month(u16), day(u16), hour(u16), minute(u16), second(u16), fraction(u32) */
165
+ {1970 , 1 , 2 , 0 , 0 , 0 , 10000 },
166
+ {2022 , 4 , 12 , 19 , 53 , 58 , 0 },
167
+ {1969 , 12 , 31 , 0 , 0 , 0 , 1 },
168
+ {1969 , 12 , 31 , 0 , 0 , 0 , 999999999 },
169
+ {1970 , 1 , 2 , 0 , 0 , 0 , 1 },
170
+ {1970 , 1 , 2 , 0 , 0 , 0 , 999999999 },
171
+ {1970 , 1 , 1 , 0 , 0 , 0 , 0 },
172
+ /* Test within range where floor (seconds) value is below INT64_MIN in nanoseconds */
173
+ {1677 , 9 , 21 , 0 , 12 , 43 , 999999999 },
174
+ };
141
175
142
176
std::shared_ptr<Array> timestamp_array;
143
177
@@ -159,19 +193,16 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_NANO) {
159
193
160
194
for (size_t i = 0 ; i < values.size (); ++i) {
161
195
ASSERT_EQ (sizeof (TIMESTAMP_STRUCT), strlen_buffer[i]);
162
- tm date{};
163
-
164
- auto converted_time = values[i] / NANO_TO_SECONDS_DIVISOR;
165
- GetTimeForSecondsSinceEpoch (date, converted_time);
166
-
167
- ASSERT_EQ (buffer[i].year , 1900 + (date.tm_year ));
168
- ASSERT_EQ (buffer[i].month , date.tm_mon + 1 );
169
- ASSERT_EQ (buffer[i].day , date.tm_mday );
170
- ASSERT_EQ (buffer[i].hour , date.tm_hour );
171
- ASSERT_EQ (buffer[i].minute , date.tm_min );
172
- ASSERT_EQ (buffer[i].second , date.tm_sec );
173
- ASSERT_EQ (buffer[i].fraction , (values[i] % NANO_TO_SECONDS_DIVISOR));
196
+
197
+ ASSERT_EQ (buffer[i].year , expected[i].year );
198
+ ASSERT_EQ (buffer[i].month , expected[i].month );
199
+ ASSERT_EQ (buffer[i].day , expected[i].day );
200
+ ASSERT_EQ (buffer[i].hour , expected[i].hour );
201
+ ASSERT_EQ (buffer[i].minute , expected[i].minute );
202
+ ASSERT_EQ (buffer[i].second , expected[i].second );
203
+ ASSERT_EQ (buffer[i].fraction , expected[i].fraction );
174
204
}
175
205
}
206
+
176
207
} // namespace flight_sql
177
208
} // namespace driver
0 commit comments