duckdb 0.3.5-dev22.0 → 0.3.5-dev46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +490 -12
- package/src/duckdb.hpp +2 -2
- package/src/parquet-amalgamation.cpp +36646 -36646
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -41290,7 +41290,7 @@ void Vector::Normalify(idx_t count) {
|
|
|
41290
41290
|
break;
|
|
41291
41291
|
case VectorType::DICTIONARY_VECTOR: {
|
|
41292
41292
|
// create a new flat vector of this type
|
|
41293
|
-
Vector other(GetType());
|
|
41293
|
+
Vector other(GetType(), count);
|
|
41294
41294
|
// now copy the data of this vector to the other vector, removing the selection vector in the process
|
|
41295
41295
|
VectorOperations::Copy(*this, other, count, 0, 0);
|
|
41296
41296
|
// create a reference to the data in the other vector
|
|
@@ -47105,7 +47105,20 @@ void VectorOperations::Copy(const Vector &source, Vector &target, const Selectio
|
|
|
47105
47105
|
if (smask.IsMaskSet()) {
|
|
47106
47106
|
for (idx_t i = 0; i < copy_count; i++) {
|
|
47107
47107
|
auto idx = sel->get_index(source_offset + i);
|
|
47108
|
-
|
|
47108
|
+
|
|
47109
|
+
if (smask.RowIsValid(idx)) {
|
|
47110
|
+
// set valid
|
|
47111
|
+
if (!tmask.AllValid()) {
|
|
47112
|
+
tmask.SetValidUnsafe(target_offset + i);
|
|
47113
|
+
}
|
|
47114
|
+
} else {
|
|
47115
|
+
// set invalid
|
|
47116
|
+
if (tmask.AllValid()) {
|
|
47117
|
+
auto init_size = MaxValue<idx_t>(STANDARD_VECTOR_SIZE, target_offset + copy_count);
|
|
47118
|
+
tmask.Initialize(init_size);
|
|
47119
|
+
}
|
|
47120
|
+
tmask.SetInvalidUnsafe(target_offset + i);
|
|
47121
|
+
}
|
|
47109
47122
|
}
|
|
47110
47123
|
}
|
|
47111
47124
|
}
|
|
@@ -79724,6 +79737,11 @@ struct ListAggregateFun {
|
|
|
79724
79737
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
79725
79738
|
};
|
|
79726
79739
|
|
|
79740
|
+
struct ListSortFun {
|
|
79741
|
+
static ScalarFunction GetFunction();
|
|
79742
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
79743
|
+
};
|
|
79744
|
+
|
|
79727
79745
|
struct CardinalityFun {
|
|
79728
79746
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
79729
79747
|
};
|
|
@@ -84973,9 +84991,6 @@ void DateSubFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
84973
84991
|
|
|
84974
84992
|
|
|
84975
84993
|
|
|
84976
|
-
// TODO date_trunc function should also handle interval data type when it is implemented. See
|
|
84977
|
-
// https://www.postgresql.org/docs/9.1/functions-datetime.html
|
|
84978
|
-
|
|
84979
84994
|
namespace duckdb {
|
|
84980
84995
|
|
|
84981
84996
|
struct DateTrunc {
|
|
@@ -85186,6 +85201,101 @@ timestamp_t DateTrunc::MicrosecondOperator::Operation(date_t input) {
|
|
|
85186
85201
|
return DayOperator::Operation<date_t, timestamp_t>(input);
|
|
85187
85202
|
}
|
|
85188
85203
|
|
|
85204
|
+
// INTERVAL specialisations
|
|
85205
|
+
template <>
|
|
85206
|
+
interval_t DateTrunc::MillenniumOperator::Operation(interval_t input) {
|
|
85207
|
+
input.days = 0;
|
|
85208
|
+
input.micros = 0;
|
|
85209
|
+
input.months = (input.months / Interval::MONTHS_PER_MILLENIUM) * Interval::MONTHS_PER_MILLENIUM;
|
|
85210
|
+
return input;
|
|
85211
|
+
}
|
|
85212
|
+
|
|
85213
|
+
template <>
|
|
85214
|
+
interval_t DateTrunc::CenturyOperator::Operation(interval_t input) {
|
|
85215
|
+
input.days = 0;
|
|
85216
|
+
input.micros = 0;
|
|
85217
|
+
input.months = (input.months / Interval::MONTHS_PER_CENTURY) * Interval::MONTHS_PER_CENTURY;
|
|
85218
|
+
return input;
|
|
85219
|
+
}
|
|
85220
|
+
|
|
85221
|
+
template <>
|
|
85222
|
+
interval_t DateTrunc::DecadeOperator::Operation(interval_t input) {
|
|
85223
|
+
input.days = 0;
|
|
85224
|
+
input.micros = 0;
|
|
85225
|
+
input.months = (input.months / Interval::MONTHS_PER_DECADE) * Interval::MONTHS_PER_DECADE;
|
|
85226
|
+
return input;
|
|
85227
|
+
}
|
|
85228
|
+
|
|
85229
|
+
template <>
|
|
85230
|
+
interval_t DateTrunc::YearOperator::Operation(interval_t input) {
|
|
85231
|
+
input.days = 0;
|
|
85232
|
+
input.micros = 0;
|
|
85233
|
+
input.months = (input.months / Interval::MONTHS_PER_YEAR) * Interval::MONTHS_PER_YEAR;
|
|
85234
|
+
return input;
|
|
85235
|
+
}
|
|
85236
|
+
|
|
85237
|
+
template <>
|
|
85238
|
+
interval_t DateTrunc::QuarterOperator::Operation(interval_t input) {
|
|
85239
|
+
input.days = 0;
|
|
85240
|
+
input.micros = 0;
|
|
85241
|
+
input.months = (input.months / Interval::MONTHS_PER_QUARTER) * Interval::MONTHS_PER_QUARTER;
|
|
85242
|
+
return input;
|
|
85243
|
+
}
|
|
85244
|
+
|
|
85245
|
+
template <>
|
|
85246
|
+
interval_t DateTrunc::MonthOperator::Operation(interval_t input) {
|
|
85247
|
+
input.days = 0;
|
|
85248
|
+
input.micros = 0;
|
|
85249
|
+
return input;
|
|
85250
|
+
}
|
|
85251
|
+
|
|
85252
|
+
template <>
|
|
85253
|
+
interval_t DateTrunc::WeekOperator::Operation(interval_t input) {
|
|
85254
|
+
input.micros = 0;
|
|
85255
|
+
input.days = (input.days / Interval::DAYS_PER_WEEK) * Interval::DAYS_PER_WEEK;
|
|
85256
|
+
return input;
|
|
85257
|
+
}
|
|
85258
|
+
|
|
85259
|
+
template <>
|
|
85260
|
+
interval_t DateTrunc::ISOYearOperator::Operation(interval_t input) {
|
|
85261
|
+
return YearOperator::Operation<interval_t, interval_t>(input);
|
|
85262
|
+
}
|
|
85263
|
+
|
|
85264
|
+
template <>
|
|
85265
|
+
interval_t DateTrunc::DayOperator::Operation(interval_t input) {
|
|
85266
|
+
input.micros = 0;
|
|
85267
|
+
return input;
|
|
85268
|
+
}
|
|
85269
|
+
|
|
85270
|
+
template <>
|
|
85271
|
+
interval_t DateTrunc::HourOperator::Operation(interval_t input) {
|
|
85272
|
+
input.micros = (input.micros / Interval::MICROS_PER_HOUR) * Interval::MICROS_PER_HOUR;
|
|
85273
|
+
return input;
|
|
85274
|
+
}
|
|
85275
|
+
|
|
85276
|
+
template <>
|
|
85277
|
+
interval_t DateTrunc::MinuteOperator::Operation(interval_t input) {
|
|
85278
|
+
input.micros = (input.micros / Interval::MICROS_PER_MINUTE) * Interval::MICROS_PER_MINUTE;
|
|
85279
|
+
return input;
|
|
85280
|
+
}
|
|
85281
|
+
|
|
85282
|
+
template <>
|
|
85283
|
+
interval_t DateTrunc::SecondOperator::Operation(interval_t input) {
|
|
85284
|
+
input.micros = (input.micros / Interval::MICROS_PER_SEC) * Interval::MICROS_PER_SEC;
|
|
85285
|
+
return input;
|
|
85286
|
+
}
|
|
85287
|
+
|
|
85288
|
+
template <>
|
|
85289
|
+
interval_t DateTrunc::MillisecondOperator::Operation(interval_t input) {
|
|
85290
|
+
input.micros = (input.micros / Interval::MICROS_PER_MSEC) * Interval::MICROS_PER_MSEC;
|
|
85291
|
+
return input;
|
|
85292
|
+
}
|
|
85293
|
+
|
|
85294
|
+
template <>
|
|
85295
|
+
interval_t DateTrunc::MicrosecondOperator::Operation(interval_t input) {
|
|
85296
|
+
return input;
|
|
85297
|
+
}
|
|
85298
|
+
|
|
85189
85299
|
template <class TA, class TR>
|
|
85190
85300
|
static TR TruncateElement(DatePartSpecifier type, TA element) {
|
|
85191
85301
|
switch (type) {
|
|
@@ -85289,7 +85399,7 @@ static void DateTruncUnaryExecutor(DatePartSpecifier type, Vector &left, Vector
|
|
|
85289
85399
|
}
|
|
85290
85400
|
}
|
|
85291
85401
|
|
|
85292
|
-
template <typename
|
|
85402
|
+
template <typename TA, typename TR>
|
|
85293
85403
|
static void DateTruncFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
85294
85404
|
D_ASSERT(args.ColumnCount() == 2);
|
|
85295
85405
|
auto &part_arg = args.data[0];
|
|
@@ -85302,20 +85412,22 @@ static void DateTruncFunction(DataChunk &args, ExpressionState &state, Vector &r
|
|
|
85302
85412
|
ConstantVector::SetNull(result, true);
|
|
85303
85413
|
} else {
|
|
85304
85414
|
const auto type = GetDatePartSpecifier(ConstantVector::GetData<string_t>(part_arg)->GetString());
|
|
85305
|
-
DateTruncUnaryExecutor<
|
|
85415
|
+
DateTruncUnaryExecutor<TA, TR>(type, date_arg, result, args.size());
|
|
85306
85416
|
}
|
|
85307
85417
|
} else {
|
|
85308
|
-
BinaryExecutor::ExecuteStandard<string_t,
|
|
85309
|
-
|
|
85418
|
+
BinaryExecutor::ExecuteStandard<string_t, TA, TR, DateTruncBinaryOperator>(part_arg, date_arg, result,
|
|
85419
|
+
args.size());
|
|
85310
85420
|
}
|
|
85311
85421
|
}
|
|
85312
85422
|
|
|
85313
85423
|
void DateTruncFun::RegisterFunction(BuiltinFunctions &set) {
|
|
85314
85424
|
ScalarFunctionSet date_trunc("date_trunc");
|
|
85315
85425
|
date_trunc.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::TIMESTAMP,
|
|
85316
|
-
DateTruncFunction<timestamp_t>));
|
|
85317
|
-
date_trunc.AddFunction(
|
|
85318
|
-
|
|
85426
|
+
DateTruncFunction<timestamp_t, timestamp_t>));
|
|
85427
|
+
date_trunc.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::TIMESTAMP,
|
|
85428
|
+
DateTruncFunction<date_t, timestamp_t>));
|
|
85429
|
+
date_trunc.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTERVAL}, LogicalType::INTERVAL,
|
|
85430
|
+
DateTruncFunction<interval_t, interval_t>));
|
|
85319
85431
|
set.AddFunction(date_trunc);
|
|
85320
85432
|
date_trunc.name = "datetrunc";
|
|
85321
85433
|
set.AddFunction(date_trunc);
|
|
@@ -88774,6 +88886,371 @@ void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
88774
88886
|
|
|
88775
88887
|
|
|
88776
88888
|
|
|
88889
|
+
namespace duckdb {
|
|
88890
|
+
|
|
88891
|
+
struct ListSortBindData : public FunctionData {
|
|
88892
|
+
ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, LogicalType &return_type_p,
|
|
88893
|
+
LogicalType &child_type_p, ClientContext &context_p);
|
|
88894
|
+
~ListSortBindData() override;
|
|
88895
|
+
|
|
88896
|
+
OrderType order_type;
|
|
88897
|
+
OrderByNullType null_order;
|
|
88898
|
+
LogicalType return_type;
|
|
88899
|
+
LogicalType child_type;
|
|
88900
|
+
|
|
88901
|
+
vector<LogicalType> types;
|
|
88902
|
+
vector<LogicalType> payload_types;
|
|
88903
|
+
|
|
88904
|
+
ClientContext &context;
|
|
88905
|
+
unique_ptr<GlobalSortState> global_sort_state;
|
|
88906
|
+
RowLayout payload_layout;
|
|
88907
|
+
vector<BoundOrderByNode> orders;
|
|
88908
|
+
|
|
88909
|
+
unique_ptr<FunctionData> Copy() override;
|
|
88910
|
+
};
|
|
88911
|
+
|
|
88912
|
+
ListSortBindData::ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, LogicalType &return_type_p,
|
|
88913
|
+
LogicalType &child_type_p, ClientContext &context_p)
|
|
88914
|
+
: order_type(order_type_p), null_order(null_order_p), return_type(return_type_p), child_type(child_type_p),
|
|
88915
|
+
context(context_p) {
|
|
88916
|
+
|
|
88917
|
+
// get the vector types
|
|
88918
|
+
types.emplace_back(LogicalType::USMALLINT);
|
|
88919
|
+
types.emplace_back(child_type);
|
|
88920
|
+
D_ASSERT(types.size() == 2);
|
|
88921
|
+
|
|
88922
|
+
// get the payload types
|
|
88923
|
+
payload_types.emplace_back(LogicalType::UINTEGER);
|
|
88924
|
+
D_ASSERT(payload_types.size() == 1);
|
|
88925
|
+
|
|
88926
|
+
// initialize the payload layout
|
|
88927
|
+
payload_layout.Initialize(payload_types);
|
|
88928
|
+
|
|
88929
|
+
// get the BoundOrderByNode
|
|
88930
|
+
auto idx_col_expr = make_unique_base<Expression, BoundReferenceExpression>(LogicalType::USMALLINT, 0);
|
|
88931
|
+
auto lists_col_expr = make_unique_base<Expression, BoundReferenceExpression>(child_type, 1);
|
|
88932
|
+
orders.emplace_back(OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, move(idx_col_expr));
|
|
88933
|
+
orders.emplace_back(order_type, null_order, move(lists_col_expr));
|
|
88934
|
+
}
|
|
88935
|
+
|
|
88936
|
+
unique_ptr<FunctionData> ListSortBindData::Copy() {
|
|
88937
|
+
return make_unique<ListSortBindData>(order_type, null_order, return_type, child_type, context);
|
|
88938
|
+
}
|
|
88939
|
+
|
|
88940
|
+
ListSortBindData::~ListSortBindData() {
|
|
88941
|
+
}
|
|
88942
|
+
|
|
88943
|
+
// create the key_chunk and the payload_chunk and sink them into the local_sort_state
|
|
88944
|
+
void SinkDataChunk(Vector *child_vector, SelectionVector &sel, idx_t offset_lists_indices, vector<LogicalType> &types,
|
|
88945
|
+
vector<LogicalType> &payload_types, Vector &payload_vector, LocalSortState &local_sort_state,
|
|
88946
|
+
bool &data_to_sort, Vector &lists_indices) {
|
|
88947
|
+
|
|
88948
|
+
// slice the child vector
|
|
88949
|
+
Vector slice(*child_vector, sel, offset_lists_indices);
|
|
88950
|
+
|
|
88951
|
+
// initialize and fill key_chunk
|
|
88952
|
+
DataChunk key_chunk;
|
|
88953
|
+
key_chunk.InitializeEmpty(types);
|
|
88954
|
+
key_chunk.data[0].Reference(lists_indices);
|
|
88955
|
+
key_chunk.data[1].Reference(slice);
|
|
88956
|
+
key_chunk.SetCardinality(offset_lists_indices);
|
|
88957
|
+
|
|
88958
|
+
// initialize and fill key_chunk and payload_chunk
|
|
88959
|
+
DataChunk payload_chunk;
|
|
88960
|
+
payload_chunk.InitializeEmpty(payload_types);
|
|
88961
|
+
payload_chunk.data[0].Reference(payload_vector);
|
|
88962
|
+
payload_chunk.SetCardinality(offset_lists_indices);
|
|
88963
|
+
|
|
88964
|
+
// sink
|
|
88965
|
+
local_sort_state.SinkChunk(key_chunk, payload_chunk);
|
|
88966
|
+
data_to_sort = true;
|
|
88967
|
+
}
|
|
88968
|
+
|
|
88969
|
+
static void ListSortFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
88970
|
+
|
|
88971
|
+
D_ASSERT(args.ColumnCount() >= 1 && args.ColumnCount() <= 3);
|
|
88972
|
+
auto count = args.size();
|
|
88973
|
+
Vector &lists = args.data[0];
|
|
88974
|
+
|
|
88975
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
88976
|
+
auto &result_validity = FlatVector::Validity(result);
|
|
88977
|
+
|
|
88978
|
+
if (lists.GetType().id() == LogicalTypeId::SQLNULL) {
|
|
88979
|
+
result_validity.SetInvalid(0);
|
|
88980
|
+
return;
|
|
88981
|
+
}
|
|
88982
|
+
|
|
88983
|
+
auto &func_expr = (BoundFunctionExpression &)state.expr;
|
|
88984
|
+
auto &info = (ListSortBindData &)*func_expr.bind_info;
|
|
88985
|
+
|
|
88986
|
+
// initialize the global and local sorting state
|
|
88987
|
+
auto &buffer_manager = BufferManager::GetBufferManager(info.context);
|
|
88988
|
+
info.global_sort_state = make_unique<GlobalSortState>(buffer_manager, info.orders, info.payload_layout);
|
|
88989
|
+
auto &global_sort_state = *info.global_sort_state;
|
|
88990
|
+
LocalSortState local_sort_state;
|
|
88991
|
+
local_sort_state.Initialize(global_sort_state, buffer_manager);
|
|
88992
|
+
|
|
88993
|
+
// get the child vector
|
|
88994
|
+
auto lists_size = ListVector::GetListSize(lists);
|
|
88995
|
+
auto &child_vector = ListVector::GetEntry(lists);
|
|
88996
|
+
VectorData child_data;
|
|
88997
|
+
child_vector.Orrify(lists_size, child_data);
|
|
88998
|
+
|
|
88999
|
+
// get the lists data
|
|
89000
|
+
VectorData lists_data;
|
|
89001
|
+
lists.Orrify(count, lists_data);
|
|
89002
|
+
auto list_entries = (list_entry_t *)lists_data.data;
|
|
89003
|
+
|
|
89004
|
+
// create the lists_indices vector, this contains an element for each list's entry,
|
|
89005
|
+
// the element corresponds to the list's index, e.g. for [1, 2, 4], [5, 4]
|
|
89006
|
+
// lists_indices contains [0, 0, 0, 1, 1]
|
|
89007
|
+
Vector lists_indices(LogicalType::USMALLINT);
|
|
89008
|
+
auto lists_indices_data = FlatVector::GetData<uint16_t>(lists_indices);
|
|
89009
|
+
|
|
89010
|
+
// create the payload_vector, this is just a vector containing incrementing integers
|
|
89011
|
+
// this will later be used as the 'new' selection vector of the child_vector, after
|
|
89012
|
+
// rearranging the payload according to the sorting order
|
|
89013
|
+
Vector payload_vector(LogicalType::UINTEGER);
|
|
89014
|
+
auto payload_vector_data = FlatVector::GetData<uint32_t>(payload_vector);
|
|
89015
|
+
|
|
89016
|
+
// selection vector pointing to the data of the child vector,
|
|
89017
|
+
// used for slicing the child_vector correctly
|
|
89018
|
+
SelectionVector sel(STANDARD_VECTOR_SIZE);
|
|
89019
|
+
|
|
89020
|
+
idx_t offset_lists_indices = 0;
|
|
89021
|
+
uint32_t incr_payload_count = 0;
|
|
89022
|
+
bool data_to_sort = false;
|
|
89023
|
+
|
|
89024
|
+
for (idx_t i = 0; i < count; i++) {
|
|
89025
|
+
|
|
89026
|
+
auto lists_index = lists_data.sel->get_index(i);
|
|
89027
|
+
const auto &list_entry = list_entries[lists_index];
|
|
89028
|
+
|
|
89029
|
+
// nothing to do for this list
|
|
89030
|
+
if (!lists_data.validity.RowIsValid(lists_index)) {
|
|
89031
|
+
result_validity.SetInvalid(i);
|
|
89032
|
+
continue;
|
|
89033
|
+
}
|
|
89034
|
+
|
|
89035
|
+
// empty list, no sorting required
|
|
89036
|
+
if (list_entry.length == 0) {
|
|
89037
|
+
continue;
|
|
89038
|
+
}
|
|
89039
|
+
|
|
89040
|
+
for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
|
|
89041
|
+
|
|
89042
|
+
// lists_indices vector is full, sink
|
|
89043
|
+
if (offset_lists_indices == STANDARD_VECTOR_SIZE) {
|
|
89044
|
+
SinkDataChunk(&child_vector, sel, offset_lists_indices, info.types, info.payload_types, payload_vector,
|
|
89045
|
+
local_sort_state, data_to_sort, lists_indices);
|
|
89046
|
+
offset_lists_indices = 0;
|
|
89047
|
+
}
|
|
89048
|
+
|
|
89049
|
+
auto source_idx = child_data.sel->get_index(list_entry.offset + child_idx);
|
|
89050
|
+
sel.set_index(offset_lists_indices, source_idx);
|
|
89051
|
+
lists_indices_data[offset_lists_indices] = (uint32_t)i;
|
|
89052
|
+
payload_vector_data[offset_lists_indices] = incr_payload_count;
|
|
89053
|
+
offset_lists_indices++;
|
|
89054
|
+
incr_payload_count++;
|
|
89055
|
+
}
|
|
89056
|
+
}
|
|
89057
|
+
|
|
89058
|
+
if (offset_lists_indices != 0) {
|
|
89059
|
+
SinkDataChunk(&child_vector, sel, offset_lists_indices, info.types, info.payload_types, payload_vector,
|
|
89060
|
+
local_sort_state, data_to_sort, lists_indices);
|
|
89061
|
+
}
|
|
89062
|
+
|
|
89063
|
+
if (data_to_sort) {
|
|
89064
|
+
|
|
89065
|
+
// add local state to global state, which sorts the data
|
|
89066
|
+
global_sort_state.AddLocalState(local_sort_state);
|
|
89067
|
+
global_sort_state.PrepareMergePhase();
|
|
89068
|
+
|
|
89069
|
+
// selection vector that is to be filled with the 'sorted' payload
|
|
89070
|
+
SelectionVector sel_sorted(incr_payload_count);
|
|
89071
|
+
idx_t sel_sorted_idx = 0;
|
|
89072
|
+
|
|
89073
|
+
// scan the sorted row data
|
|
89074
|
+
PayloadScanner scanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state);
|
|
89075
|
+
for (;;) {
|
|
89076
|
+
DataChunk result_chunk;
|
|
89077
|
+
result_chunk.Initialize(info.payload_types);
|
|
89078
|
+
result_chunk.SetCardinality(0);
|
|
89079
|
+
scanner.Scan(result_chunk);
|
|
89080
|
+
if (result_chunk.size() == 0) {
|
|
89081
|
+
break;
|
|
89082
|
+
}
|
|
89083
|
+
|
|
89084
|
+
// construct the selection vector with the new order from the result vectors
|
|
89085
|
+
Vector result_vector(result_chunk.data[0]);
|
|
89086
|
+
auto result_data = FlatVector::GetData<uint32_t>(result_vector);
|
|
89087
|
+
auto row_count = result_chunk.size();
|
|
89088
|
+
|
|
89089
|
+
for (idx_t i = 0; i < row_count; i++) {
|
|
89090
|
+
sel_sorted.set_index(sel_sorted_idx, result_data[i]);
|
|
89091
|
+
sel_sorted_idx++;
|
|
89092
|
+
}
|
|
89093
|
+
}
|
|
89094
|
+
|
|
89095
|
+
D_ASSERT(sel_sorted_idx == incr_payload_count);
|
|
89096
|
+
child_vector.Slice(sel_sorted, sel_sorted_idx);
|
|
89097
|
+
child_vector.Normalify(sel_sorted_idx);
|
|
89098
|
+
}
|
|
89099
|
+
|
|
89100
|
+
result.Reference(lists);
|
|
89101
|
+
}
|
|
89102
|
+
|
|
89103
|
+
static unique_ptr<FunctionData> ListSortBind(ClientContext &context, ScalarFunction &bound_function,
|
|
89104
|
+
vector<unique_ptr<Expression>> &arguments, OrderType &order,
|
|
89105
|
+
OrderByNullType &null_order) {
|
|
89106
|
+
|
|
89107
|
+
if (arguments[0]->return_type.id() == LogicalTypeId::SQLNULL) {
|
|
89108
|
+
bound_function.arguments[0] = LogicalType::SQLNULL;
|
|
89109
|
+
bound_function.return_type = LogicalType::SQLNULL;
|
|
89110
|
+
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
|
89111
|
+
}
|
|
89112
|
+
|
|
89113
|
+
bound_function.arguments[0] = arguments[0]->return_type;
|
|
89114
|
+
bound_function.return_type = arguments[0]->return_type;
|
|
89115
|
+
auto child_type = ListType::GetChildType(arguments[0]->return_type);
|
|
89116
|
+
|
|
89117
|
+
return make_unique<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
|
|
89118
|
+
}
|
|
89119
|
+
|
|
89120
|
+
OrderByNullType GetNullOrder(vector<unique_ptr<Expression>> &arguments, idx_t idx) {
|
|
89121
|
+
|
|
89122
|
+
if (!arguments[idx]->IsFoldable()) {
|
|
89123
|
+
throw InvalidInputException("Null sorting order must be a constant");
|
|
89124
|
+
}
|
|
89125
|
+
Value null_order_value = ExpressionExecutor::EvaluateScalar(*arguments[idx]);
|
|
89126
|
+
auto null_order_name = null_order_value.ToString();
|
|
89127
|
+
std::transform(null_order_name.begin(), null_order_name.end(), null_order_name.begin(), ::toupper);
|
|
89128
|
+
if (null_order_name != "NULLS FIRST" && null_order_name != "NULLS LAST") {
|
|
89129
|
+
throw InvalidInputException("Null sorting order must be either NULLS FIRST or NULLS LAST");
|
|
89130
|
+
}
|
|
89131
|
+
|
|
89132
|
+
if (null_order_name == "NULLS LAST") {
|
|
89133
|
+
return OrderByNullType::NULLS_LAST;
|
|
89134
|
+
}
|
|
89135
|
+
return OrderByNullType::NULLS_FIRST;
|
|
89136
|
+
}
|
|
89137
|
+
|
|
89138
|
+
static unique_ptr<FunctionData> ListNormalSortBind(ClientContext &context, ScalarFunction &bound_function,
|
|
89139
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
89140
|
+
|
|
89141
|
+
D_ASSERT(bound_function.arguments.size() >= 1 && bound_function.arguments.size() <= 3);
|
|
89142
|
+
D_ASSERT(arguments.size() >= 1 && arguments.size() <= 3);
|
|
89143
|
+
|
|
89144
|
+
// set default values
|
|
89145
|
+
auto &config = DBConfig::GetConfig(context);
|
|
89146
|
+
auto order = config.default_order_type;
|
|
89147
|
+
auto null_order = config.default_null_order;
|
|
89148
|
+
|
|
89149
|
+
// get the sorting order
|
|
89150
|
+
if (arguments.size() >= 2) {
|
|
89151
|
+
|
|
89152
|
+
if (!arguments[1]->IsFoldable()) {
|
|
89153
|
+
throw InvalidInputException("Sorting order must be a constant");
|
|
89154
|
+
}
|
|
89155
|
+
Value order_value = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
89156
|
+
auto order_name = order_value.ToString();
|
|
89157
|
+
std::transform(order_name.begin(), order_name.end(), order_name.begin(), ::toupper);
|
|
89158
|
+
if (order_name != "DESC" && order_name != "ASC") {
|
|
89159
|
+
throw InvalidInputException("Sorting order must be either ASC or DESC");
|
|
89160
|
+
}
|
|
89161
|
+
if (order_name == "DESC") {
|
|
89162
|
+
order = OrderType::DESCENDING;
|
|
89163
|
+
} else {
|
|
89164
|
+
order = OrderType::ASCENDING;
|
|
89165
|
+
}
|
|
89166
|
+
}
|
|
89167
|
+
|
|
89168
|
+
// get the null sorting order
|
|
89169
|
+
if (arguments.size() == 3) {
|
|
89170
|
+
null_order = GetNullOrder(arguments, 2);
|
|
89171
|
+
}
|
|
89172
|
+
|
|
89173
|
+
return ListSortBind(context, bound_function, arguments, order, null_order);
|
|
89174
|
+
}
|
|
89175
|
+
|
|
89176
|
+
static unique_ptr<FunctionData> ListReverseSortBind(ClientContext &context, ScalarFunction &bound_function,
|
|
89177
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
89178
|
+
|
|
89179
|
+
D_ASSERT(bound_function.arguments.size() == 1 || bound_function.arguments.size() == 2);
|
|
89180
|
+
D_ASSERT(arguments.size() == 1 || arguments.size() == 2);
|
|
89181
|
+
|
|
89182
|
+
// set (reverse) default values
|
|
89183
|
+
auto &config = DBConfig::GetConfig(context);
|
|
89184
|
+
auto order = (config.default_order_type == OrderType::ASCENDING) ? OrderType::DESCENDING : OrderType::ASCENDING;
|
|
89185
|
+
auto null_order = config.default_null_order;
|
|
89186
|
+
|
|
89187
|
+
// get the null sorting order
|
|
89188
|
+
if (arguments.size() == 2) {
|
|
89189
|
+
null_order = GetNullOrder(arguments, 1);
|
|
89190
|
+
}
|
|
89191
|
+
|
|
89192
|
+
return ListSortBind(context, bound_function, arguments, order, null_order);
|
|
89193
|
+
}
|
|
89194
|
+
|
|
89195
|
+
void ListSortFun::RegisterFunction(BuiltinFunctions &set) {
|
|
89196
|
+
|
|
89197
|
+
// normal sort
|
|
89198
|
+
|
|
89199
|
+
// one parameter: list
|
|
89200
|
+
ScalarFunction sort({LogicalType::LIST(LogicalType::ANY)}, LogicalType::LIST(LogicalType::ANY), ListSortFunction,
|
|
89201
|
+
false, false, ListNormalSortBind);
|
|
89202
|
+
|
|
89203
|
+
// two parameters: list, order
|
|
89204
|
+
ScalarFunction sort_order({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR},
|
|
89205
|
+
LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false, ListNormalSortBind);
|
|
89206
|
+
|
|
89207
|
+
// three parameters: list, order, null order
|
|
89208
|
+
ScalarFunction sort_orders({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR, LogicalType::VARCHAR},
|
|
89209
|
+
LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false, ListNormalSortBind);
|
|
89210
|
+
|
|
89211
|
+
ScalarFunctionSet list_sort("list_sort");
|
|
89212
|
+
list_sort.AddFunction(sort);
|
|
89213
|
+
list_sort.AddFunction(sort_order);
|
|
89214
|
+
list_sort.AddFunction(sort_orders);
|
|
89215
|
+
set.AddFunction(list_sort);
|
|
89216
|
+
|
|
89217
|
+
ScalarFunctionSet array_sort("array_sort");
|
|
89218
|
+
array_sort.AddFunction(sort);
|
|
89219
|
+
array_sort.AddFunction(sort_order);
|
|
89220
|
+
array_sort.AddFunction(sort_orders);
|
|
89221
|
+
set.AddFunction(array_sort);
|
|
89222
|
+
|
|
89223
|
+
// reverse sort
|
|
89224
|
+
|
|
89225
|
+
// one parameter: list
|
|
89226
|
+
ScalarFunction sort_reverse({LogicalType::LIST(LogicalType::ANY)}, LogicalType::LIST(LogicalType::ANY),
|
|
89227
|
+
ListSortFunction, false, false, ListReverseSortBind);
|
|
89228
|
+
|
|
89229
|
+
// two parameters: list, null order
|
|
89230
|
+
ScalarFunction sort_reverse_null_order({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR},
|
|
89231
|
+
LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false,
|
|
89232
|
+
ListReverseSortBind);
|
|
89233
|
+
|
|
89234
|
+
ScalarFunctionSet list_reverse_sort("list_reverse_sort");
|
|
89235
|
+
list_reverse_sort.AddFunction(sort_reverse);
|
|
89236
|
+
list_reverse_sort.AddFunction(sort_reverse_null_order);
|
|
89237
|
+
set.AddFunction(list_reverse_sort);
|
|
89238
|
+
|
|
89239
|
+
ScalarFunctionSet array_reverse_sort("array_reverse_sort");
|
|
89240
|
+
array_reverse_sort.AddFunction(sort_reverse);
|
|
89241
|
+
array_reverse_sort.AddFunction(sort_reverse_null_order);
|
|
89242
|
+
set.AddFunction(array_reverse_sort);
|
|
89243
|
+
}
|
|
89244
|
+
|
|
89245
|
+
} // namespace duckdb
|
|
89246
|
+
|
|
89247
|
+
|
|
89248
|
+
|
|
89249
|
+
|
|
89250
|
+
|
|
89251
|
+
|
|
89252
|
+
|
|
89253
|
+
|
|
88777
89254
|
namespace duckdb {
|
|
88778
89255
|
|
|
88779
89256
|
static void ListValueFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
@@ -90668,6 +91145,7 @@ void BuiltinFunctions::RegisterNestedFunctions() {
|
|
|
90668
91145
|
Register<ListAggregateFun>();
|
|
90669
91146
|
Register<ListValueFun>();
|
|
90670
91147
|
Register<ListExtractFun>();
|
|
91148
|
+
Register<ListSortFun>();
|
|
90671
91149
|
Register<ListRangeFun>();
|
|
90672
91150
|
Register<ListFlattenFun>();
|
|
90673
91151
|
Register<MapFun>();
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.3.5-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "0b96d12d4"
|
|
15
|
+
#define DUCKDB_VERSION "v0.3.5-dev46"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|