Skip to content

Commit 3f01673

Browse files
Update vendored DuckDB sources to 0f935a6
1 parent 0f935a6 commit 3f01673

File tree

14 files changed

+254
-158
lines changed

14 files changed

+254
-158
lines changed

src/duckdb/extension/icu/icu-dateadd.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,27 @@
88
#include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
99
#include "duckdb/planner/expression/bound_function_expression.hpp"
1010
#include "include/icu-datefunc.hpp"
11+
#include "icu-helpers.hpp"
1112

1213
namespace duckdb {
1314

1415
struct ICUCalendarAdd {
1516
template <class TA, class TB, class TR>
16-
static inline TR Operation(TA left, TB right, icu::Calendar *calendar) {
17+
static inline TR Operation(TA left, TB right, TZCalendar &calendar_p) {
1718
throw InternalException("Unimplemented type for ICUCalendarAdd");
1819
}
1920
};
2021

2122
struct ICUCalendarSub : public ICUDateFunc {
2223
template <class TA, class TB, class TR>
23-
static inline TR Operation(TA left, TB right, icu::Calendar *calendar) {
24+
static inline TR Operation(TA left, TB right, TZCalendar &calendar_p) {
2425
throw InternalException("Unimplemented type for ICUCalendarSub");
2526
}
2627
};
2728

2829
struct ICUCalendarAge : public ICUDateFunc {
2930
template <class TA, class TB, class TR>
30-
static inline TR Operation(TA left, TB right, icu::Calendar *calendar) {
31+
static inline TR Operation(TA left, TB right, TZCalendar &calendar_p) {
3132
throw InternalException("Unimplemented type for ICUCalendarAge");
3233
}
3334
};
@@ -53,10 +54,11 @@ static inline void CalendarAddHour(icu::Calendar *calendar, int64_t interval_hou
5354
}
5455

5556
template <>
56-
timestamp_t ICUCalendarAdd::Operation(timestamp_t timestamp, interval_t interval, icu::Calendar *calendar) {
57+
timestamp_t ICUCalendarAdd::Operation(timestamp_t timestamp, interval_t interval, TZCalendar &calendar_p) {
5758
if (!Timestamp::IsFinite(timestamp)) {
5859
return timestamp;
5960
}
61+
auto calendar = calendar_p.GetICUCalendar();
6062

6163
int64_t millis = timestamp.value / Interval::MICROS_PER_MSEC;
6264
int64_t micros = timestamp.value % Interval::MICROS_PER_MSEC;
@@ -120,25 +122,26 @@ timestamp_t ICUCalendarAdd::Operation(timestamp_t timestamp, interval_t interval
120122
}
121123

122124
template <>
123-
timestamp_t ICUCalendarAdd::Operation(interval_t interval, timestamp_t timestamp, icu::Calendar *calendar) {
125+
timestamp_t ICUCalendarAdd::Operation(interval_t interval, timestamp_t timestamp, TZCalendar &calendar) {
124126
return Operation<timestamp_t, interval_t, timestamp_t>(timestamp, interval, calendar);
125127
}
126128

127129
template <>
128-
timestamp_t ICUCalendarSub::Operation(timestamp_t timestamp, interval_t interval, icu::Calendar *calendar) {
130+
timestamp_t ICUCalendarSub::Operation(timestamp_t timestamp, interval_t interval, TZCalendar &calendar) {
129131
const interval_t negated {-interval.months, -interval.days, -interval.micros};
130132
return ICUCalendarAdd::template Operation<timestamp_t, interval_t, timestamp_t>(timestamp, negated, calendar);
131133
}
132134

133135
template <>
134-
interval_t ICUCalendarSub::Operation(timestamp_t end_date, timestamp_t start_date, icu::Calendar *calendar) {
136+
interval_t ICUCalendarSub::Operation(timestamp_t end_date, timestamp_t start_date, TZCalendar &calendar_p) {
135137
if (!Timestamp::IsFinite(end_date) || !Timestamp::IsFinite(start_date)) {
136138
throw InvalidInputException("Cannot subtract infinite timestamps");
137139
}
138140
if (start_date > end_date) {
139-
auto negated = Operation<timestamp_t, timestamp_t, interval_t>(start_date, end_date, calendar);
141+
auto negated = Operation<timestamp_t, timestamp_t, interval_t>(start_date, end_date, calendar_p);
140142
return {-negated.months, -negated.days, -negated.micros};
141143
}
144+
auto calendar = calendar_p.GetICUCalendar();
142145

143146
auto start_micros = ICUDateFunc::SetTime(calendar, start_date);
144147
auto end_micros = (uint64_t)(end_date.value % Interval::MICROS_PER_MSEC);
@@ -166,9 +169,16 @@ interval_t ICUCalendarSub::Operation(timestamp_t end_date, timestamp_t start_dat
166169
}
167170

168171
template <>
169-
interval_t ICUCalendarAge::Operation(timestamp_t end_date, timestamp_t start_date, icu::Calendar *calendar) {
172+
interval_t ICUCalendarAge::Operation(timestamp_t end_date, timestamp_t start_date, TZCalendar &calendar_p) {
173+
auto calendar = calendar_p.GetICUCalendar();
174+
if (calendar_p.IsGregorian()) {
175+
auto start_data = ICUHelpers::GetComponents(timestamp_tz_t(start_date.value), calendar);
176+
auto end_data = ICUHelpers::GetComponents(timestamp_tz_t(end_date.value), calendar);
177+
return Interval::GetAge(end_data, start_data, start_date > end_date);
178+
}
179+
// fallback for non-gregorian calendars, since Interval::GetAge does not handle
170180
if (start_date > end_date) {
171-
auto negated = Operation<timestamp_t, timestamp_t, interval_t>(start_date, end_date, calendar);
181+
auto negated = Operation<timestamp_t, timestamp_t, interval_t>(start_date, end_date, calendar_p);
172182
return {-negated.months, -negated.days, -negated.micros};
173183
}
174184

@@ -205,13 +215,13 @@ struct ICUDateAdd : public ICUDateFunc {
205215

206216
auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
207217
auto &info = func_expr.bind_info->Cast<BindData>();
208-
CalendarPtr calendar(info.calendar->clone());
218+
TZCalendar calendar(*info.calendar, info.cal_setting);
209219

210220
// Subtract argument from current_date (at midnight)
211-
const auto end_date = CurrentMidnight(calendar.get(), state);
221+
const auto end_date = CurrentMidnight(calendar.GetICUCalendar(), state);
212222

213223
UnaryExecutor::Execute<TA, TR>(args.data[0], result, args.size(), [&](TA start_date) {
214-
return OP::template Operation<timestamp_t, TA, TR>(end_date, start_date, calendar.get());
224+
return OP::template Operation<timestamp_t, TA, TR>(end_date, start_date, calendar);
215225
});
216226
}
217227

@@ -227,10 +237,10 @@ struct ICUDateAdd : public ICUDateFunc {
227237

228238
auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
229239
auto &info = func_expr.bind_info->Cast<BindData>();
230-
CalendarPtr calendar(info.calendar->clone());
240+
TZCalendar calendar(*info.calendar, info.cal_setting);
231241

232242
BinaryExecutor::Execute<TA, TB, TR>(args.data[0], args.data[1], result, args.size(), [&](TA left, TB right) {
233-
return OP::template Operation<TA, TB, TR>(left, right, calendar.get());
243+
return OP::template Operation<TA, TB, TR>(left, right, calendar);
234244
});
235245
}
236246

@@ -287,15 +297,15 @@ struct ICUDateAdd : public ICUDateFunc {
287297
}
288298
};
289299

290-
timestamp_t ICUDateFunc::Add(icu::Calendar *calendar, timestamp_t timestamp, interval_t interval) {
300+
timestamp_t ICUDateFunc::Add(TZCalendar &calendar, timestamp_t timestamp, interval_t interval) {
291301
return ICUCalendarAdd::Operation<timestamp_t, interval_t, timestamp_t>(timestamp, interval, calendar);
292302
}
293303

294-
timestamp_t ICUDateFunc::Sub(icu::Calendar *calendar, timestamp_t timestamp, interval_t interval) {
304+
timestamp_t ICUDateFunc::Sub(TZCalendar &calendar, timestamp_t timestamp, interval_t interval) {
295305
return ICUCalendarSub::Operation<timestamp_t, interval_t, timestamp_t>(timestamp, interval, calendar);
296306
}
297307

298-
interval_t ICUDateFunc::Sub(icu::Calendar *calendar, timestamp_t end_date, timestamp_t start_date) {
308+
interval_t ICUDateFunc::Sub(TZCalendar &calendar, timestamp_t end_date, timestamp_t start_date) {
299309
return ICUCalendarSub::Operation<timestamp_t, timestamp_t, interval_t>(end_date, start_date, calendar);
300310
}
301311

src/duckdb/extension/icu/icu-list-range.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ struct ICUListRange : public ICUDateFunc {
6060
increment_value = ListIncrementValue(row_idx);
6161
}
6262

63-
uint64_t ListLength(idx_t row_idx, icu::Calendar *calendar) {
63+
uint64_t ListLength(idx_t row_idx, TZCalendar &calendar) {
6464
timestamp_t start_value;
6565
timestamp_t end_value;
6666
interval_t increment_value;
6767
GetListValues(row_idx, start_value, end_value, increment_value);
6868
return ListLength(start_value, end_value, increment_value, INCLUSIVE_BOUND, calendar);
6969
}
7070

71-
void Increment(timestamp_t &input, interval_t increment, icu::Calendar *calendar) {
71+
void Increment(timestamp_t &input, interval_t increment, TZCalendar &calendar) {
7272
input = Add(calendar, input, increment);
7373
}
7474

@@ -77,7 +77,7 @@ struct ICUListRange : public ICUDateFunc {
7777
UnifiedVectorFormat vdata[3];
7878

7979
uint64_t ListLength(timestamp_t start_value, timestamp_t end_value, interval_t increment_value,
80-
bool inclusive_bound, icu::Calendar *calendar) {
80+
bool inclusive_bound, TZCalendar &calendar) {
8181
bool is_positive = increment_value.months > 0 || increment_value.days > 0 || increment_value.micros > 0;
8282
bool is_negative = increment_value.months < 0 || increment_value.days < 0 || increment_value.micros < 0;
8383
if (!is_negative && !is_positive) {
@@ -130,8 +130,7 @@ struct ICUListRange : public ICUDateFunc {
130130

131131
auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
132132
auto &bind_info = func_expr.bind_info->Cast<BindData>();
133-
CalendarPtr calendar_ptr(bind_info.calendar->clone());
134-
auto calendar = calendar_ptr.get();
133+
TZCalendar calendar(*bind_info.calendar, bind_info.cal_setting);
135134

136135
RangeInfoStruct<INCLUSIVE_BOUND> info(args);
137136
idx_t args_size = 1;

src/duckdb/extension/icu/icu-strptime.cpp

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "include/icu-strptime.hpp"
22
#include "include/icu-datefunc.hpp"
3+
#include "include/icu-helpers.hpp"
34

45
#include "duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp"
56
#include "duckdb/common/operator/cast_operators.hpp"
@@ -17,6 +18,28 @@
1718

1819
namespace duckdb {
1920

21+
TimestampComponents ICUHelpers::GetComponents(timestamp_tz_t ts, icu::Calendar *calendar) {
22+
// Get the parts in the given time zone
23+
uint64_t micros = ICUDateFunc::SetTime(calendar, timestamp_t(ts.value));
24+
25+
TimestampComponents ts_data;
26+
ts_data.year = ICUDateFunc::ExtractField(calendar, UCAL_EXTENDED_YEAR);
27+
ts_data.month = ICUDateFunc::ExtractField(calendar, UCAL_MONTH) + 1;
28+
ts_data.day = ICUDateFunc::ExtractField(calendar, UCAL_DATE);
29+
30+
ts_data.hour = ICUDateFunc::ExtractField(calendar, UCAL_HOUR_OF_DAY);
31+
ts_data.minute = ICUDateFunc::ExtractField(calendar, UCAL_MINUTE);
32+
ts_data.second = ICUDateFunc::ExtractField(calendar, UCAL_SECOND);
33+
ts_data.microsecond = UnsafeNumericCast<int32_t>(
34+
ICUDateFunc::ExtractField(calendar, UCAL_MILLISECOND) * Interval::MICROS_PER_MSEC + micros);
35+
return ts_data;
36+
}
37+
38+
timestamp_t ICUHelpers::ToTimestamp(TimestampComponents data) {
39+
date_t date_val = Date::FromDate(data.year, data.month, data.day);
40+
dtime_t time_val = Time::FromTime(data.hour, data.minute, data.second, data.microsecond);
41+
return Timestamp::FromDatetime(date_val, time_val);
42+
}
2043
struct ICUStrptime : public ICUDateFunc {
2144
using ParseResult = StrpTimeFormat::ParseResult;
2245

@@ -445,27 +468,15 @@ struct ICUStrftime : public ICUDateFunc {
445468
return StringVector::AddString(result, Timestamp::ToString(input));
446469
}
447470

448-
// Get the parts in the given time zone
449-
uint64_t micros = SetTime(calendar, input);
450-
451-
int32_t date_units[3];
452-
date_units[0] = ExtractField(calendar, UCAL_EXTENDED_YEAR); // strftime doesn't understand eras.
453-
date_units[1] = ExtractField(calendar, UCAL_MONTH) + 1;
454-
date_units[2] = ExtractField(calendar, UCAL_DATE);
455-
456-
int32_t time_units[4];
457-
time_units[0] = ExtractField(calendar, UCAL_HOUR_OF_DAY);
458-
time_units[1] = ExtractField(calendar, UCAL_MINUTE);
459-
time_units[2] = ExtractField(calendar, UCAL_SECOND);
460-
time_units[3] =
461-
UnsafeNumericCast<int32_t>(ExtractField(calendar, UCAL_MILLISECOND) * Interval::MICROS_PER_MSEC + micros);
471+
// decompose the timestamp
472+
auto ts_data = ICUHelpers::GetComponents(timestamp_tz_t(input.value), calendar);
462473

463474
idx_t year_length;
464475
bool add_bc;
465-
const auto date_len = DateToStringCast::Length(date_units, year_length, add_bc);
476+
const auto date_len = DateToStringCast::YearLength(ts_data.year, year_length, add_bc);
466477

467478
char micro_buffer[6];
468-
const auto time_len = TimeToStringCast::Length(time_units, micro_buffer);
479+
const auto time_len = TimeToStringCast::MicrosLength(ts_data.microsecond, micro_buffer);
469480

470481
auto offset = ExtractField(calendar, UCAL_ZONE_OFFSET) + ExtractField(calendar, UCAL_DST_OFFSET);
471482
offset /= Interval::MSECS_PER_SEC;
@@ -479,11 +490,12 @@ struct ICUStrftime : public ICUDateFunc {
479490
string_t target = StringVector::EmptyString(result, len);
480491
auto buffer = target.GetDataWriteable();
481492

482-
DateToStringCast::Format(buffer, date_units, year_length, add_bc);
493+
DateToStringCast::Format(buffer, ts_data.year, ts_data.month, ts_data.day, year_length, add_bc);
483494
buffer += date_len;
484495
*buffer++ = ' ';
485496

486-
TimeToStringCast::Format(buffer, time_len, time_units, micro_buffer);
497+
TimeToStringCast::Format(buffer, time_len, ts_data.hour, ts_data.minute, ts_data.second, ts_data.microsecond,
498+
micro_buffer);
487499
buffer += time_len;
488500

489501
memcpy(buffer, offset_str.c_str(), offset_len);

src/duckdb/extension/icu/icu-table-range.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "duckdb/parser/parsed_data/create_table_function_info.hpp"
88
#include "include/icu-datefunc.hpp"
99
#include "unicode/calendar.h"
10+
#include "tz_calendar.hpp"
1011

1112
namespace duckdb {
1213

@@ -151,8 +152,7 @@ struct ICUTableRange {
151152
DataChunk &input, DataChunk &output) {
152153
auto &bind_data = data_p.bind_data->Cast<ICURangeBindData>();
153154
auto &state = data_p.local_state->Cast<ICURangeLocalState>();
154-
CalendarPtr calendar_ptr(bind_data.calendar->clone());
155-
auto calendar = calendar_ptr.get();
155+
TZCalendar calendar(*bind_data.calendar, bind_data.cal_setting);
156156
while (true) {
157157
if (!state.initialized_row) {
158158
// initialize for the current input row

0 commit comments

Comments
 (0)