Skip to content

Commit a861326

Browse files
authored
Merge branch 'main' into main
2 parents 929e85a + ad63b51 commit a861326

File tree

101 files changed

+1902
-879
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1902
-879
lines changed

src/duckdb/extension/core_functions/scalar/date/epoch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct EpochSecOperator {
1111
static RESULT_TYPE Operation(INPUT_TYPE sec) {
1212
int64_t result;
1313
if (!TryCast::Operation(sec * Interval::MICROS_PER_SEC, result)) {
14-
throw ConversionException("Could not convert epoch seconds to TIMESTAMP WITH TIME ZONE");
14+
throw ConversionException("Epoch seconds out of range for TIMESTAMP WITH TIME ZONE");
1515
}
1616
return timestamp_t(result);
1717
}

src/duckdb/extension/core_functions/scalar/date/make_date.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ struct MakeTimestampOperator {
103103

104104
template <typename T, typename RESULT_TYPE>
105105
static RESULT_TYPE Operation(T value) {
106+
const auto result = RESULT_TYPE(value);
107+
if (!Timestamp::IsFinite(result)) {
108+
throw ConversionException("Timestamp microseconds out of range: %ld", value);
109+
}
106110
return RESULT_TYPE(value);
107111
}
108112
};

src/duckdb/extension/core_functions/scalar/list/list_reduce.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static bool ExecuteReduce(idx_t loops, ReduceExecuteInfo &execute_info, LambdaFu
101101
}
102102

103103
// create the index vector
104-
Vector index_vector(Value::BIGINT(UnsafeNumericCast<int64_t>(loops + 1)));
104+
Vector index_vector(Value::BIGINT(UnsafeNumericCast<int64_t>(loops + 2)));
105105

106106
// slice the left and right slice
107107
execute_info.left_slice->Slice(*execute_info.left_slice, execute_info.left_sel, reduced_row_idx);

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ timestamp_t ICUCalendarSub::Operation(timestamp_t timestamp, interval_t interval
132132

133133
template <>
134134
interval_t ICUCalendarSub::Operation(timestamp_t end_date, timestamp_t start_date, icu::Calendar *calendar) {
135+
if (!Timestamp::IsFinite(end_date) || !Timestamp::IsFinite(start_date)) {
136+
throw InvalidInputException("Cannot subtract infinite timestamps");
137+
}
135138
if (start_date > end_date) {
136139
auto negated = Operation<timestamp_t, timestamp_t, interval_t>(start_date, end_date, calendar);
137140
return {-negated.months, -negated.days, -negated.micros};
@@ -156,7 +159,7 @@ interval_t ICUCalendarSub::Operation(timestamp_t end_date, timestamp_t start_dat
156159
auto min_diff = SubtractField(calendar, UCAL_MINUTE, end_date);
157160
auto sec_diff = SubtractField(calendar, UCAL_SECOND, end_date);
158161
auto ms_diff = SubtractField(calendar, UCAL_MILLISECOND, end_date);
159-
auto micros_diff = ms_diff * Interval::MICROS_PER_MSEC + (end_micros - start_micros);
162+
auto micros_diff = UnsafeNumericCast<int32_t>(ms_diff * Interval::MICROS_PER_MSEC + (end_micros - start_micros));
160163
result.micros = Time::FromTime(hour_diff, min_diff, sec_diff, micros_diff).micros;
161164

162165
return result;
@@ -188,7 +191,7 @@ interval_t ICUCalendarAge::Operation(timestamp_t end_date, timestamp_t start_dat
188191
auto min_diff = SubtractField(calendar, UCAL_MINUTE, end_date);
189192
auto sec_diff = SubtractField(calendar, UCAL_SECOND, end_date);
190193
auto ms_diff = SubtractField(calendar, UCAL_MILLISECOND, end_date);
191-
auto micros_diff = ms_diff * Interval::MICROS_PER_MSEC + (end_micros - start_micros);
194+
auto micros_diff = UnsafeNumericCast<int32_t>(ms_diff * Interval::MICROS_PER_MSEC + (end_micros - start_micros));
192195
result.micros = Time::FromTime(hour_diff, min_diff, sec_diff, micros_diff).micros;
193196

194197
return result;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ bool ICUDateFunc::TryGetTime(icu::Calendar *calendar, uint64_t micros, timestamp
117117
timestamp_t ICUDateFunc::GetTime(icu::Calendar *calendar, uint64_t micros) {
118118
timestamp_t result;
119119
if (!TryGetTime(calendar, micros, result)) {
120-
throw ConversionException("Unable to convert ICU date to timestamp");
120+
throw ConversionException("ICU date overflows timestamp range");
121121
}
122122
return result;
123123
}
@@ -148,7 +148,7 @@ int32_t ICUDateFunc::ExtractField(icu::Calendar *calendar, UCalendarDateFields f
148148
return result;
149149
}
150150

151-
int64_t ICUDateFunc::SubtractField(icu::Calendar *calendar, UCalendarDateFields field, timestamp_t end_date) {
151+
int32_t ICUDateFunc::SubtractField(icu::Calendar *calendar, UCalendarDateFields field, timestamp_t end_date) {
152152
const int64_t millis = end_date.value / Interval::MICROS_PER_MSEC;
153153
const auto when = UDate(millis);
154154
UErrorCode status = U_ZERO_ERROR;

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ struct ICUMakeTimestampTZFunc : public ICUDateFunc {
9494

9595
template <typename T>
9696
static void FromMicros(DataChunk &input, ExpressionState &state, Vector &result) {
97-
UnaryExecutor::Execute<T, timestamp_t>(input.data[0], result, input.size(),
98-
[&](T micros) { return timestamp_t(micros); });
97+
UnaryExecutor::Execute<T, timestamp_t>(input.data[0], result, input.size(), [&](T micros) {
98+
const auto result = timestamp_t(micros);
99+
if (!Timestamp::IsFinite(result)) {
100+
throw ConversionException("Timestamp microseconds out of range: %ld", micros);
101+
}
102+
return result;
103+
});
99104
}
100105

101106
template <typename T>

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,14 @@ struct ICUStrptime : public ICUDateFunc {
258258
const auto len = input.GetSize();
259259
string_t tz(nullptr, 0);
260260
bool has_offset = false;
261-
if (!Timestamp::TryConvertTimestampTZ(str, len, result, has_offset, tz)) {
262-
auto msg = Timestamp::ConversionError(string(str, len));
261+
auto success = Timestamp::TryConvertTimestampTZ(str, len, result, has_offset, tz);
262+
if (success != TimestampCastResult::SUCCESS) {
263+
string msg;
264+
if (success == TimestampCastResult::ERROR_RANGE) {
265+
msg = Timestamp::RangeError(string(str, len));
266+
} else {
267+
msg = Timestamp::FormatError(string(str, len));
268+
}
263269
HandleCastError::AssignError(msg, parameters);
264270
mask.SetInvalid(idx);
265271
} else if (!has_offset) {

src/duckdb/extension/icu/include/icu-datefunc.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct ICUDateFunc {
6262
//! Extracts the field from the calendar
6363
static int32_t ExtractField(icu::Calendar *calendar, UCalendarDateFields field);
6464
//! Subtracts the field of the given date from the calendar
65-
static int64_t SubtractField(icu::Calendar *calendar, UCalendarDateFields field, timestamp_t end_date);
65+
static int32_t SubtractField(icu::Calendar *calendar, UCalendarDateFields field, timestamp_t end_date);
6666
//! Adds the timestamp and the interval using the calendar
6767
static timestamp_t Add(icu::Calendar *calendar, timestamp_t timestamp, interval_t interval);
6868
//! Subtracts the interval from the timestamp using the calendar

src/duckdb/extension/json/include/json_scan.hpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ struct JSONString {
4141
};
4242

4343
struct DateFormatMap {
44+
public:
45+
DateFormatMap() {
46+
}
47+
48+
DateFormatMap(DateFormatMap &&other) noexcept {
49+
candidate_formats = other.candidate_formats;
50+
}
51+
52+
DateFormatMap &operator=(DateFormatMap &&other) noexcept {
53+
candidate_formats = other.candidate_formats;
54+
return *this;
55+
}
56+
4457
public:
4558
void Initialize(const type_id_map_t<vector<const char *>> &format_templates) {
4659
for (const auto &entry : format_templates) {
@@ -51,6 +64,12 @@ struct DateFormatMap {
5164
}
5265
}
5366

67+
DateFormatMap Copy() const {
68+
DateFormatMap result;
69+
result.candidate_formats = candidate_formats;
70+
return result;
71+
}
72+
5473
void AddFormat(LogicalTypeId type, const string &format_string) {
5574
auto &formats = candidate_formats[type];
5675
formats.emplace_back();
@@ -59,25 +78,47 @@ struct DateFormatMap {
5978
}
6079

6180
bool HasFormats(LogicalTypeId type) const {
81+
lock_guard<mutex> guard(lock);
6282
return candidate_formats.find(type) != candidate_formats.end();
6383
}
6484

65-
vector<StrpTimeFormat> &GetCandidateFormats(LogicalTypeId type) {
66-
D_ASSERT(HasFormats(type));
67-
return candidate_formats[type];
85+
idx_t NumberOfFormats(LogicalTypeId type) {
86+
lock_guard<mutex> guard(lock);
87+
return candidate_formats[type].size();
88+
}
89+
90+
bool GetFormatAtIndex(LogicalTypeId type, idx_t index, StrpTimeFormat &format) {
91+
lock_guard<mutex> guard(lock);
92+
auto &formats = candidate_formats[type];
93+
if (index >= formats.size()) {
94+
return false;
95+
}
96+
format = formats[index];
97+
return true;
98+
}
99+
100+
void ShrinkFormatsToSize(LogicalTypeId type, idx_t size) {
101+
lock_guard<mutex> guard(lock);
102+
auto &formats = candidate_formats[type];
103+
while (formats.size() > size) {
104+
formats.pop_back();
105+
}
68106
}
69107

70108
StrpTimeFormat &GetFormat(LogicalTypeId type) {
109+
lock_guard<mutex> guard(lock);
71110
D_ASSERT(candidate_formats.find(type) != candidate_formats.end());
72111
return candidate_formats.find(type)->second.back();
73112
}
74113

75114
const StrpTimeFormat &GetFormat(LogicalTypeId type) const {
115+
lock_guard<mutex> guard(lock);
76116
D_ASSERT(candidate_formats.find(type) != candidate_formats.end());
77117
return candidate_formats.find(type)->second.back();
78118
}
79119

80120
private:
121+
mutable mutex lock;
81122
type_id_map_t<vector<StrpTimeFormat>> candidate_formats;
82123
};
83124

src/duckdb/extension/json/include/json_structure.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct JSONStructureNode {
4545
DateFormatMap &date_format_map);
4646
void EliminateCandidateTypes(idx_t vec_count, Vector &string_vector, DateFormatMap &date_format_map);
4747
bool EliminateCandidateFormats(idx_t vec_count, Vector &string_vector, const Vector &result_vector,
48-
vector<StrpTimeFormat> &formats);
48+
DateFormatMap &date_format_map);
4949

5050
public:
5151
unique_ptr<string> key;
@@ -84,6 +84,7 @@ struct JSONStructureDescription {
8484
struct JSONStructure {
8585
public:
8686
static void ExtractStructure(yyjson_val *val, JSONStructureNode &node, bool ignore_errors);
87+
static void MergeNodes(JSONStructureNode &merged, const JSONStructureNode &node);
8788
static LogicalType StructureToType(ClientContext &context, const JSONStructureNode &node, idx_t max_depth,
8889
double field_appearance_threshold, idx_t map_inference_threshold,
8990
idx_t depth = 0, const LogicalType &null_type = LogicalType::JSON());

0 commit comments

Comments
 (0)