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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.3.5-dev22.0",
4
+ "version": "0.3.5-dev46.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
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
- tmask.Set(target_offset + i, smask.RowIsValid(idx));
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 T>
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<T, timestamp_t>(type, date_arg, result, args.size());
85415
+ DateTruncUnaryExecutor<TA, TR>(type, date_arg, result, args.size());
85306
85416
  }
85307
85417
  } else {
85308
- BinaryExecutor::ExecuteStandard<string_t, T, timestamp_t, DateTruncBinaryOperator>(part_arg, date_arg, result,
85309
- args.size());
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
- ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::TIMESTAMP, DateTruncFunction<date_t>));
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 "339bd4003"
15
- #define DUCKDB_VERSION "v0.3.5-dev22"
14
+ #define DUCKDB_SOURCE_ID "0b96d12d4"
15
+ #define DUCKDB_VERSION "v0.3.5-dev46"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //