Skip to content

Commit 5c8d22d

Browse files
committed
bump to 1.3.1
1 parent c20ae10 commit 5c8d22d

File tree

178 files changed

+1582
-685
lines changed

Some content is hidden

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

178 files changed

+1582
-685
lines changed

src/duckdb/extension/core_functions/aggregate/distributive/arg_min_max.cpp

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ struct ArgMinMaxStateBase {
2121
}
2222

2323
template <class T>
24-
static inline void DestroyValue(T &value) {
25-
}
26-
27-
template <class T>
28-
static inline void AssignValue(T &target, T new_value) {
24+
static inline void AssignValue(T &target, T new_value, AggregateInputData &aggregate_input_data) {
2925
target = new_value;
3026
}
3127

@@ -45,23 +41,21 @@ void ArgMinMaxStateBase::CreateValue(string_t &value) {
4541
}
4642

4743
template <>
48-
void ArgMinMaxStateBase::DestroyValue(string_t &value) {
49-
if (!value.IsInlined()) {
50-
delete[] value.GetData();
51-
}
52-
}
53-
54-
template <>
55-
void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value) {
56-
DestroyValue(target);
44+
void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value, AggregateInputData &aggregate_input_data) {
5745
if (new_value.IsInlined()) {
5846
target = new_value;
5947
} else {
6048
// non-inlined string, need to allocate space for it
6149
auto len = new_value.GetSize();
62-
auto ptr = new char[len];
50+
char *ptr;
51+
if (!target.IsInlined() && target.GetSize() >= len) {
52+
// Target has enough space, reuse ptr
53+
ptr = target.GetPointer();
54+
} else {
55+
// Target might be too small, allocate
56+
ptr = reinterpret_cast<char *>(aggregate_input_data.allocator.Allocate(len));
57+
}
6358
memcpy(ptr, new_value.GetData(), len);
64-
6559
target = string_t(ptr, UnsafeNumericCast<uint32_t>(len));
6660
}
6761
}
@@ -83,14 +77,6 @@ struct ArgMinMaxState : public ArgMinMaxStateBase {
8377
CreateValue(arg);
8478
CreateValue(value);
8579
}
86-
87-
~ArgMinMaxState() {
88-
if (is_initialized) {
89-
DestroyValue(arg);
90-
DestroyValue(value);
91-
is_initialized = false;
92-
}
93-
}
9480
};
9581

9682
template <class COMPARATOR, bool IGNORE_NULL>
@@ -106,24 +92,25 @@ struct ArgMinMaxBase {
10692
}
10793

10894
template <class A_TYPE, class B_TYPE, class STATE>
109-
static void Assign(STATE &state, const A_TYPE &x, const B_TYPE &y, const bool x_null) {
95+
static void Assign(STATE &state, const A_TYPE &x, const B_TYPE &y, const bool x_null,
96+
AggregateInputData &aggregate_input_data) {
11097
if (IGNORE_NULL) {
111-
STATE::template AssignValue<A_TYPE>(state.arg, x);
112-
STATE::template AssignValue<B_TYPE>(state.value, y);
98+
STATE::template AssignValue<A_TYPE>(state.arg, x, aggregate_input_data);
99+
STATE::template AssignValue<B_TYPE>(state.value, y, aggregate_input_data);
113100
} else {
114101
state.arg_null = x_null;
115102
if (!state.arg_null) {
116-
STATE::template AssignValue<A_TYPE>(state.arg, x);
103+
STATE::template AssignValue<A_TYPE>(state.arg, x, aggregate_input_data);
117104
}
118-
STATE::template AssignValue<B_TYPE>(state.value, y);
105+
STATE::template AssignValue<B_TYPE>(state.value, y, aggregate_input_data);
119106
}
120107
}
121108

122109
template <class A_TYPE, class B_TYPE, class STATE, class OP>
123110
static void Operation(STATE &state, const A_TYPE &x, const B_TYPE &y, AggregateBinaryInput &binary) {
124111
if (!state.is_initialized) {
125112
if (IGNORE_NULL || binary.right_mask.RowIsValid(binary.ridx)) {
126-
Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx));
113+
Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx), binary.input);
127114
state.is_initialized = true;
128115
}
129116
} else {
@@ -134,17 +121,17 @@ struct ArgMinMaxBase {
134121
template <class A_TYPE, class B_TYPE, class STATE>
135122
static void Execute(STATE &state, A_TYPE x_data, B_TYPE y_data, AggregateBinaryInput &binary) {
136123
if ((IGNORE_NULL || binary.right_mask.RowIsValid(binary.ridx)) && COMPARATOR::Operation(y_data, state.value)) {
137-
Assign(state, x_data, y_data, !binary.left_mask.RowIsValid(binary.lidx));
124+
Assign(state, x_data, y_data, !binary.left_mask.RowIsValid(binary.lidx), binary.input);
138125
}
139126
}
140127

141128
template <class STATE, class OP>
142-
static void Combine(const STATE &source, STATE &target, AggregateInputData &) {
129+
static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) {
143130
if (!source.is_initialized) {
144131
return;
145132
}
146133
if (!target.is_initialized || COMPARATOR::Operation(source.value, target.value)) {
147-
Assign(target, source.arg, source.value, source.arg_null);
134+
Assign(target, source.arg, source.value, source.arg_null, aggregate_input_data);
148135
target.is_initialized = true;
149136
}
150137
}
@@ -201,7 +188,8 @@ template <typename COMPARATOR, bool IGNORE_NULL, OrderType ORDER_TYPE,
201188
class UPDATE_TYPE = SpecializedGenericArgMinMaxState>
202189
struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
203190
template <class STATE>
204-
static void Update(Vector inputs[], AggregateInputData &, idx_t input_count, Vector &state_vector, idx_t count) {
191+
static void Update(Vector inputs[], AggregateInputData &aggregate_input_data, idx_t input_count,
192+
Vector &state_vector, idx_t count) {
205193
auto &arg = inputs[0];
206194
UnifiedVectorFormat adata;
207195
arg.ToUnifiedFormat(count, adata);
@@ -238,7 +226,7 @@ struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
238226
const auto sidx = sdata.sel->get_index(i);
239227
auto &state = *states[sidx];
240228
if (!state.is_initialized || COMPARATOR::template Operation<BY_TYPE>(bval, state.value)) {
241-
STATE::template AssignValue<BY_TYPE>(state.value, bval);
229+
STATE::template AssignValue<BY_TYPE>(state.value, bval, aggregate_input_data);
242230
state.arg_null = arg_null;
243231
// micro-adaptivity: it is common we overwrite the same state repeatedly
244232
// e.g. when running arg_max(val, ts) and ts is sorted in ascending order
@@ -271,20 +259,20 @@ struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
271259
for (idx_t i = 0; i < assign_count; i++) {
272260
const auto sidx = sdata.sel->get_index(sel.get_index(i));
273261
auto &state = *states[sidx];
274-
STATE::template AssignValue<ARG_TYPE>(state.arg, sort_key_data[i]);
262+
STATE::template AssignValue<ARG_TYPE>(state.arg, sort_key_data[i], aggregate_input_data);
275263
}
276264
}
277265

278266
template <class STATE, class OP>
279-
static void Combine(const STATE &source, STATE &target, AggregateInputData &) {
267+
static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) {
280268
if (!source.is_initialized) {
281269
return;
282270
}
283271
if (!target.is_initialized || COMPARATOR::Operation(source.value, target.value)) {
284-
STATE::template AssignValue<typename STATE::BY_TYPE>(target.value, source.value);
272+
STATE::template AssignValue<typename STATE::BY_TYPE>(target.value, source.value, aggregate_input_data);
285273
target.arg_null = source.arg_null;
286274
if (!target.arg_null) {
287-
STATE::template AssignValue<typename STATE::ARG_TYPE>(target.arg, source.arg);
275+
STATE::template AssignValue<typename STATE::ARG_TYPE>(target.arg, source.arg, aggregate_input_data);
288276
}
289277
target.is_initialized = true;
290278
}

src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "duckdb/common/operator/abs.hpp"
77
#include "core_functions/aggregate/quantile_state.hpp"
88
#include "duckdb/common/types/timestamp.hpp"
9-
#include "duckdb/common/queue.hpp"
109
#include "duckdb/common/serializer/serializer.hpp"
1110
#include "duckdb/common/serializer/deserializer.hpp"
1211
#include "duckdb/function/aggregate/sort_key_helpers.hpp"
@@ -588,7 +587,7 @@ AggregateFunction GetContinuousQuantileList(const LogicalType &type) {
588587
//===--------------------------------------------------------------------===//
589588
// Quantile binding
590589
//===--------------------------------------------------------------------===//
591-
static const Value &CheckQuantile(const Value &quantile_val) {
590+
static Value CheckQuantile(const Value &quantile_val) {
592591
if (quantile_val.IsNull()) {
593592
throw BinderException("QUANTILE parameter cannot be NULL");
594593
}
@@ -820,7 +819,7 @@ struct ContinuousQuantileListFunction {
820819
};
821820

822821
template <class OP>
823-
AggregateFunction EmptyQuantileFunction(LogicalType input, LogicalType result, const LogicalType &extra_arg) {
822+
AggregateFunction EmptyQuantileFunction(LogicalType input, const LogicalType &result, const LogicalType &extra_arg) {
824823
AggregateFunction fun({std::move(input)}, std::move(result), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
825824
OP::Bind);
826825
if (extra_arg.id() != LogicalTypeId::INVALID) {

src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_sort_tree.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ struct QuantileCompare {
144144
const auto lval = accessor_l(lhs);
145145
const auto rval = accessor_r(rhs);
146146

147-
return desc ? (rval < lval) : (lval < rval);
147+
return desc ? LessThan::Operation(rval, lval) : LessThan::Operation(lval, rval);
148148
}
149149
};
150150

src/duckdb/extension/core_functions/lambda_functions.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -244,28 +244,30 @@ unique_ptr<FunctionData> ListLambdaBindData::Deserialize(Deserializer &deseriali
244244
//===--------------------------------------------------------------------===//
245245
// LambdaFunctions
246246
//===--------------------------------------------------------------------===//
247-
248-
LogicalType LambdaFunctions::BindBinaryLambda(const idx_t parameter_idx, const LogicalType &list_child_type) {
249-
switch (parameter_idx) {
250-
case 0:
251-
return list_child_type;
252-
case 1:
253-
return LogicalType::BIGINT;
254-
default:
255-
throw BinderException("This lambda function only supports up to two lambda parameters!");
247+
LogicalType LambdaFunctions::DetermineListChildType(const LogicalType &child_type) {
248+
if (child_type.id() != LogicalTypeId::SQLNULL && child_type.id() != LogicalTypeId::UNKNOWN) {
249+
if (child_type.id() == LogicalTypeId::ARRAY) {
250+
return ArrayType::GetChildType(child_type);
251+
} else if (child_type.id() == LogicalTypeId::LIST) {
252+
return ListType::GetChildType(child_type);
253+
}
254+
throw InternalException("The first argument must be a list or array type");
256255
}
256+
257+
return child_type;
257258
}
258259

259-
LogicalType LambdaFunctions::BindTernaryLambda(const idx_t parameter_idx, const LogicalType &list_child_type) {
260+
LogicalType LambdaFunctions::BindBinaryChildren(const vector<LogicalType> &function_child_types,
261+
const idx_t parameter_idx) {
262+
auto list_type = DetermineListChildType(function_child_types[0]);
263+
260264
switch (parameter_idx) {
261265
case 0:
262-
return list_child_type;
266+
return list_type;
263267
case 1:
264-
return list_child_type;
265-
case 2:
266268
return LogicalType::BIGINT;
267269
default:
268-
throw BinderException("This lambda function only supports up to three lambda parameters!");
270+
throw BinderException("This lambda function only supports up to two lambda parameters!");
269271
}
270272
}
271273

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ static unique_ptr<FunctionData> ListFilterBind(ClientContext &context, ScalarFun
3030
return LambdaFunctions::ListLambdaBind(context, bound_function, arguments, has_index);
3131
}
3232

33-
static LogicalType ListFilterBindLambda(const idx_t parameter_idx, const LogicalType &list_child_type) {
34-
return LambdaFunctions::BindBinaryLambda(parameter_idx, list_child_type);
33+
static LogicalType ListFilterBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
34+
const idx_t parameter_idx) {
35+
return LambdaFunctions::BindBinaryChildren(function_child_types, parameter_idx);
3536
}
3637

3738
ScalarFunction ListFilterFun::GetFunction() {

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

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "core_functions/scalar/list_functions.hpp"
22
#include "duckdb/function/lambda_functions.hpp"
33
#include "duckdb/planner/expression/bound_cast_expression.hpp"
4-
#include "duckdb/planner/expression/bound_function_expression.hpp"
54

65
namespace duckdb {
76

@@ -219,12 +218,6 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
219218

220219
arguments[0] = BoundCastExpression::AddArrayCastToList(context, std::move(arguments[0]));
221220

222-
auto &bound_lambda_expr = arguments[1]->Cast<BoundLambdaExpression>();
223-
if (bound_lambda_expr.parameter_count < 2 || bound_lambda_expr.parameter_count > 3) {
224-
throw BinderException("list_reduce expects a function with 2 or 3 arguments");
225-
}
226-
auto has_index = bound_lambda_expr.parameter_count == 3;
227-
228221
unique_ptr<FunctionData> bind_data = LambdaFunctions::ListLambdaPrepareBind(arguments, context, bound_function);
229222
if (bind_data) {
230223
return bind_data;
@@ -236,7 +229,7 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
236229
bool has_initial = arguments.size() == 3;
237230
if (has_initial) {
238231
const auto initial_value_type = arguments[2]->return_type;
239-
// Check if the initial value type is the same as the list child type and if not find the max logical type
232+
// Check if the initial value type is the same as the return type of the lambda expression
240233
if (list_child_type != initial_value_type) {
241234
LogicalType max_logical_type;
242235
const auto has_max_logical_type =
@@ -253,6 +246,12 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
253246
}
254247
}
255248

249+
auto &bound_lambda_expr = arguments[1]->Cast<BoundLambdaExpression>();
250+
if (bound_lambda_expr.parameter_count < 2 || bound_lambda_expr.parameter_count > 3) {
251+
throw BinderException("list_reduce expects a function with 2 or 3 arguments");
252+
}
253+
auto has_index = bound_lambda_expr.parameter_count == 3;
254+
256255
auto cast_lambda_expr =
257256
BoundCastExpression::AddCastToType(context, std::move(bound_lambda_expr.lambda_expr), list_child_type);
258257
if (!cast_lambda_expr) {
@@ -263,8 +262,45 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
263262
has_initial);
264263
}
265264

266-
static LogicalType ListReduceBindLambda(const idx_t parameter_idx, const LogicalType &list_child_type) {
267-
return LambdaFunctions::BindTernaryLambda(parameter_idx, list_child_type);
265+
LogicalType BindReduceChildren(ClientContext &context, const vector<LogicalType> &function_child_types,
266+
const idx_t parameter_idx) {
267+
auto list_child_type = LambdaFunctions::DetermineListChildType(function_child_types[0]);
268+
269+
// if there is an initial value, find the max logical type
270+
if (function_child_types.size() == 3) {
271+
// the initial value is the third child
272+
constexpr idx_t initial_idx = 2;
273+
274+
const LogicalType initial_value_type = function_child_types[initial_idx];
275+
if (initial_value_type != list_child_type) {
276+
// we need to check if the initial value type is the same as the return type of the lambda expression
277+
LogicalType max_logical_type;
278+
const auto has_max_logical_type =
279+
LogicalType::TryGetMaxLogicalType(context, list_child_type, initial_value_type, max_logical_type);
280+
if (!has_max_logical_type) {
281+
throw BinderException(
282+
"The initial value type must be the same as the list child type or a common super type");
283+
}
284+
285+
list_child_type = max_logical_type;
286+
}
287+
}
288+
289+
switch (parameter_idx) {
290+
case 0:
291+
return list_child_type;
292+
case 1:
293+
return list_child_type;
294+
case 2:
295+
return LogicalType::BIGINT;
296+
default:
297+
throw BinderException("This lambda function only supports up to three lambda parameters!");
298+
}
299+
}
300+
301+
static LogicalType ListReduceBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
302+
const idx_t parameter_idx) {
303+
return BindReduceChildren(context, function_child_types, parameter_idx);
268304
}
269305

270306
ScalarFunctionSet ListReduceFun::GetFunctions() {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ static unique_ptr<FunctionData> ListTransformBind(ClientContext &context, Scalar
2222
return LambdaFunctions::ListLambdaBind(context, bound_function, arguments, has_index);
2323
}
2424

25-
static LogicalType ListTransformBindLambda(const idx_t parameter_idx, const LogicalType &list_child_type) {
26-
return LambdaFunctions::BindBinaryLambda(parameter_idx, list_child_type);
25+
static LogicalType ListTransformBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
26+
const idx_t parameter_idx) {
27+
return LambdaFunctions::BindBinaryChildren(function_child_types, parameter_idx);
2728
}
2829

2930
ScalarFunction ListTransformFun::GetFunction() {

src/duckdb/extension/core_functions/scalar/random/random.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ struct ExtractTimestampUuidOperator {
2929
}
3030

3131
// UUID v7 begins with a 48 bit big-endian Unix Epoch timestamp with millisecond granularity.
32-
const int64_t upper = input.upper;
32+
int64_t upper = input.upper;
33+
// flip the top byte
34+
upper ^= NumericLimits<int64_t>::Minimum();
3335
int64_t unix_ts_milli = upper;
3436
unix_ts_milli = unix_ts_milli >> 16;
3537

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ bool ICUDateFunc::TrySetTimeZone(icu::Calendar *calendar, const string_t &tz_id)
8282
return true;
8383
}
8484

85-
void ICUDateFunc::SetTimeZone(icu::Calendar *calendar, const string_t &tz_id) {
85+
void ICUDateFunc::SetTimeZone(icu::Calendar *calendar, const string_t &tz_id, string *error_message) {
8686
string tz_str = tz_id.GetString();
87-
auto tz = ICUHelpers::GetTimeZone(tz_str);
88-
calendar->adoptTimeZone(tz.release());
87+
auto tz = ICUHelpers::GetTimeZone(tz_str, error_message);
88+
if (tz) {
89+
calendar->adoptTimeZone(tz.release());
90+
}
8991
}
9092

9193
timestamp_t ICUDateFunc::GetTimeUnsafe(icu::Calendar *calendar, uint64_t micros) {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,12 @@ struct ICUStrptime : public ICUDateFunc {
293293

294294
// Change TZ if one was provided.
295295
if (tz.GetSize()) {
296-
SetTimeZone(calendar, tz);
296+
string error_msg;
297+
SetTimeZone(calendar, tz, &error_msg);
298+
if (!error_msg.empty()) {
299+
HandleCastError::AssignError(error_msg, parameters);
300+
mask.SetInvalid(idx);
301+
}
297302
}
298303

299304
// Now get the parts in the given time zone

0 commit comments

Comments
 (0)