duckdb 0.8.2-dev2320.0 → 0.8.2-dev2399.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/binding.gyp +7 -7
- package/package.json +1 -1
- package/src/duckdb/extension/icu/icu-datefunc.cpp +9 -0
- package/src/duckdb/extension/icu/icu-datepart.cpp +7 -5
- package/src/duckdb/extension/icu/icu-strptime.cpp +1 -20
- package/src/duckdb/extension/parquet/parquet_writer.cpp +1 -0
- package/src/duckdb/src/common/adbc/adbc.cpp +8 -3
- package/src/duckdb/src/common/arrow/arrow_appender.cpp +4 -4
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +27 -26
- package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +5 -5
- package/src/duckdb/src/common/types/list_segment.cpp +42 -134
- package/src/duckdb/src/common/types/vector.cpp +21 -0
- package/src/duckdb/src/core_functions/aggregate/holistic/mode.cpp +5 -7
- package/src/duckdb/src/core_functions/aggregate/holistic/quantile.cpp +17 -19
- package/src/duckdb/src/core_functions/aggregate/nested/list.cpp +80 -61
- package/src/duckdb/src/execution/aggregate_hashtable.cpp +6 -0
- package/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +11 -5
- package/src/duckdb/src/execution/window_executor.cpp +18 -20
- package/src/duckdb/src/function/aggregate/distributive/count.cpp +2 -2
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/arrow/appender/append_data.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/arrow/appender/varchar_data.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_appender.hpp +4 -3
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_converter.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_wrapper.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/types/list_segment.hpp +9 -11
- package/src/duckdb/src/include/duckdb/common/types/vector.hpp +7 -0
- package/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp +7 -2
- package/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +4 -2
- package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +0 -2
- package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +0 -1
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +1 -2
- package/src/duckdb/src/include/duckdb/main/client_config.hpp +0 -2
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/client_properties.hpp +25 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +1 -1
- package/src/duckdb/src/include/duckdb/main/query_result.hpp +1 -13
- package/src/duckdb/src/include/duckdb/storage/object_cache.hpp +1 -1
- package/src/duckdb/src/main/capi/arrow-c.cpp +1 -7
- package/src/duckdb/src/main/client_context.cpp +15 -2
- package/src/duckdb/src/main/database.cpp +0 -9
- package/src/duckdb/src/main/query_result.cpp +0 -8
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +3 -0
- package/src/duckdb/src/storage/serialization/serialize_constraint.cpp +2 -2
- package/src/duckdb/src/storage/serialization/serialize_create_info.cpp +2 -2
- package/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +2 -2
- package/src/duckdb/src/storage/serialization/serialize_tableref.cpp +2 -4
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +6 -6
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_options.hpp +0 -25
@@ -96,7 +96,7 @@ static uint16_t GetCapacityForNewSegment(uint16_t capacity) {
|
|
96
96
|
}
|
97
97
|
|
98
98
|
//===--------------------------------------------------------------------===//
|
99
|
-
// Create
|
99
|
+
// Create
|
100
100
|
//===--------------------------------------------------------------------===//
|
101
101
|
template <class T>
|
102
102
|
static ListSegment *CreatePrimitiveSegment(const ListSegmentFunctions &, ArenaAllocator &allocator, uint16_t capacity) {
|
@@ -174,56 +174,55 @@ static ListSegment *GetSegment(const ListSegmentFunctions &functions, ArenaAlloc
|
|
174
174
|
// Append
|
175
175
|
//===--------------------------------------------------------------------===//
|
176
176
|
template <class T>
|
177
|
-
static void WriteDataToPrimitiveSegment(const ListSegmentFunctions
|
178
|
-
|
177
|
+
static void WriteDataToPrimitiveSegment(const ListSegmentFunctions &, ArenaAllocator &, ListSegment *segment,
|
178
|
+
RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx) {
|
179
179
|
|
180
|
-
|
181
|
-
auto input_data = FlatVector::GetData(input);
|
180
|
+
auto sel_entry_idx = input_data.unified.sel->get_index(entry_idx);
|
182
181
|
|
183
182
|
// write null validity
|
184
183
|
auto null_mask = GetNullMask(segment);
|
185
|
-
auto
|
186
|
-
null_mask[segment->count] =
|
184
|
+
auto valid = input_data.unified.validity.RowIsValid(sel_entry_idx);
|
185
|
+
null_mask[segment->count] = !valid;
|
187
186
|
|
188
187
|
// write value
|
189
|
-
if (
|
190
|
-
auto
|
191
|
-
|
188
|
+
if (valid) {
|
189
|
+
auto segment_data = GetPrimitiveData<T>(segment);
|
190
|
+
auto input_data_ptr = UnifiedVectorFormat::GetData<T>(input_data.unified);
|
191
|
+
Store<T>(input_data_ptr[sel_entry_idx], data_ptr_cast(segment_data + segment->count));
|
192
192
|
}
|
193
193
|
}
|
194
194
|
|
195
195
|
static void WriteDataToVarcharSegment(const ListSegmentFunctions &functions, ArenaAllocator &allocator,
|
196
|
-
ListSegment *segment,
|
196
|
+
ListSegment *segment, RecursiveUnifiedVectorFormat &input_data,
|
197
|
+
idx_t &entry_idx) {
|
197
198
|
|
198
|
-
|
199
|
-
auto input_data = FlatVector::GetData<string_t>(input);
|
199
|
+
auto sel_entry_idx = input_data.unified.sel->get_index(entry_idx);
|
200
200
|
|
201
201
|
// write null validity
|
202
202
|
auto null_mask = GetNullMask(segment);
|
203
|
-
auto
|
204
|
-
null_mask[segment->count] =
|
203
|
+
auto valid = input_data.unified.validity.RowIsValid(sel_entry_idx);
|
204
|
+
null_mask[segment->count] = !valid;
|
205
205
|
|
206
206
|
// set the length of this string
|
207
207
|
auto str_length_data = GetListLengthData(segment);
|
208
208
|
uint64_t str_length = 0;
|
209
209
|
|
210
210
|
// get the string
|
211
|
-
string_t
|
212
|
-
if (
|
213
|
-
|
214
|
-
str_length =
|
211
|
+
string_t str_entry;
|
212
|
+
if (valid) {
|
213
|
+
str_entry = UnifiedVectorFormat::GetData<string_t>(input_data.unified)[sel_entry_idx];
|
214
|
+
str_length = str_entry.GetSize();
|
215
215
|
}
|
216
216
|
|
217
217
|
// we can reconstruct the offset from the length
|
218
218
|
Store<uint64_t>(str_length, data_ptr_cast(str_length_data + segment->count));
|
219
|
-
|
220
|
-
if (is_null) {
|
219
|
+
if (!valid) {
|
221
220
|
return;
|
222
221
|
}
|
223
222
|
|
224
223
|
// write the characters to the linked list of child segments
|
225
224
|
auto child_segments = Load<LinkedList>(data_ptr_cast(GetListChildData(segment)));
|
226
|
-
for (char &c :
|
225
|
+
for (char &c : str_entry.GetString()) {
|
227
226
|
auto child_segment = GetSegment(functions.child_functions.back(), allocator, child_segments);
|
228
227
|
auto data = GetPrimitiveData<char>(child_segment);
|
229
228
|
data[child_segment->count] = c;
|
@@ -236,37 +235,31 @@ static void WriteDataToVarcharSegment(const ListSegmentFunctions &functions, Are
|
|
236
235
|
}
|
237
236
|
|
238
237
|
static void WriteDataToListSegment(const ListSegmentFunctions &functions, ArenaAllocator &allocator,
|
239
|
-
ListSegment *segment,
|
238
|
+
ListSegment *segment, RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx) {
|
240
239
|
|
241
|
-
|
242
|
-
auto input_data = FlatVector::GetData<list_entry_t>(input);
|
240
|
+
auto sel_entry_idx = input_data.unified.sel->get_index(entry_idx);
|
243
241
|
|
244
242
|
// write null validity
|
245
243
|
auto null_mask = GetNullMask(segment);
|
246
|
-
auto
|
247
|
-
null_mask[segment->count] =
|
244
|
+
auto valid = input_data.unified.validity.RowIsValid(sel_entry_idx);
|
245
|
+
null_mask[segment->count] = !valid;
|
248
246
|
|
249
247
|
// set the length of this list
|
250
248
|
auto list_length_data = GetListLengthData(segment);
|
251
249
|
uint64_t list_length = 0;
|
252
250
|
|
253
|
-
if (
|
251
|
+
if (valid) {
|
254
252
|
// get list entry information
|
255
|
-
auto
|
256
|
-
const auto &list_entry = list_entries[entry_idx];
|
253
|
+
const auto &list_entry = UnifiedVectorFormat::GetData<list_entry_t>(input_data.unified)[sel_entry_idx];
|
257
254
|
list_length = list_entry.length;
|
258
255
|
|
259
|
-
// get the child vector and its data
|
260
|
-
auto lists_size = ListVector::GetListSize(input);
|
261
|
-
auto &child_vector = ListVector::GetEntry(input);
|
262
|
-
|
263
256
|
// loop over the child vector entries and recurse on them
|
264
257
|
auto child_segments = Load<LinkedList>(data_ptr_cast(GetListChildData(segment)));
|
265
258
|
D_ASSERT(functions.child_functions.size() == 1);
|
266
259
|
for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
|
267
260
|
auto source_idx_child = list_entry.offset + child_idx;
|
268
|
-
functions.child_functions[0].AppendRow(allocator, child_segments,
|
269
|
-
|
261
|
+
functions.child_functions[0].AppendRow(allocator, child_segments, input_data.children.back(),
|
262
|
+
source_idx_child);
|
270
263
|
}
|
271
264
|
// store the updated linked list
|
272
265
|
Store<LinkedList>(child_segments, data_ptr_cast(GetListChildData(segment)));
|
@@ -276,35 +269,34 @@ static void WriteDataToListSegment(const ListSegmentFunctions &functions, ArenaA
|
|
276
269
|
}
|
277
270
|
|
278
271
|
static void WriteDataToStructSegment(const ListSegmentFunctions &functions, ArenaAllocator &allocator,
|
279
|
-
ListSegment *segment,
|
272
|
+
ListSegment *segment, RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx) {
|
273
|
+
|
274
|
+
auto sel_entry_idx = input_data.unified.sel->get_index(entry_idx);
|
280
275
|
|
281
276
|
// write null validity
|
282
277
|
auto null_mask = GetNullMask(segment);
|
283
|
-
auto
|
284
|
-
null_mask[segment->count] =
|
278
|
+
auto valid = input_data.unified.validity.RowIsValid(sel_entry_idx);
|
279
|
+
null_mask[segment->count] = !valid;
|
285
280
|
|
286
281
|
// write value
|
287
|
-
|
288
|
-
D_ASSERT(children.size() == functions.child_functions.size());
|
282
|
+
D_ASSERT(input_data.children.size() == functions.child_functions.size());
|
289
283
|
auto child_list = GetStructData(segment);
|
290
284
|
|
291
285
|
// write the data of each of the children of the struct
|
292
|
-
for (idx_t
|
293
|
-
auto child_list_segment = Load<ListSegment *>(data_ptr_cast(child_list +
|
294
|
-
auto &child_function = functions.child_functions[
|
295
|
-
child_function.write_data(child_function, allocator, child_list_segment,
|
296
|
-
count);
|
286
|
+
for (idx_t i = 0; i < input_data.children.size(); i++) {
|
287
|
+
auto child_list_segment = Load<ListSegment *>(data_ptr_cast(child_list + i));
|
288
|
+
auto &child_function = functions.child_functions[i];
|
289
|
+
child_function.write_data(child_function, allocator, child_list_segment, input_data.children[i], entry_idx);
|
297
290
|
child_list_segment->count++;
|
298
291
|
}
|
299
292
|
}
|
300
293
|
|
301
|
-
void ListSegmentFunctions::AppendRow(ArenaAllocator &allocator, LinkedList &linked_list,
|
302
|
-
|
294
|
+
void ListSegmentFunctions::AppendRow(ArenaAllocator &allocator, LinkedList &linked_list,
|
295
|
+
RecursiveUnifiedVectorFormat &input_data, idx_t &entry_idx) const {
|
303
296
|
|
304
|
-
D_ASSERT(input.GetVectorType() == VectorType::FLAT_VECTOR);
|
305
297
|
auto &write_data_to_segment = *this;
|
306
298
|
auto segment = GetSegment(write_data_to_segment, allocator, linked_list);
|
307
|
-
write_data_to_segment.write_data(write_data_to_segment, allocator, segment,
|
299
|
+
write_data_to_segment.write_data(write_data_to_segment, allocator, segment, input_data, entry_idx);
|
308
300
|
|
309
301
|
linked_list.total_capacity++;
|
310
302
|
segment->count++;
|
@@ -458,86 +450,6 @@ void ListSegmentFunctions::BuildListVector(const LinkedList &linked_list, Vector
|
|
458
450
|
}
|
459
451
|
}
|
460
452
|
|
461
|
-
//===--------------------------------------------------------------------===//
|
462
|
-
// Copy
|
463
|
-
//===--------------------------------------------------------------------===//
|
464
|
-
template <class T>
|
465
|
-
static ListSegment *CopyDataFromPrimitiveSegment(const ListSegmentFunctions &, const ListSegment *source,
|
466
|
-
ArenaAllocator &allocator) {
|
467
|
-
|
468
|
-
auto target = (ListSegment *)AllocatePrimitiveData<T>(allocator, source->capacity);
|
469
|
-
memcpy(target, source, sizeof(ListSegment) + source->capacity * (sizeof(bool) + sizeof(T)));
|
470
|
-
target->next = nullptr;
|
471
|
-
return target;
|
472
|
-
}
|
473
|
-
|
474
|
-
static ListSegment *CopyDataFromListSegment(const ListSegmentFunctions &functions, const ListSegment *source,
|
475
|
-
ArenaAllocator &allocator) {
|
476
|
-
|
477
|
-
// create an empty linked list for the child vector of target
|
478
|
-
auto source_linked_child_list = Load<LinkedList>(const_data_ptr_cast(GetListChildData(source)));
|
479
|
-
|
480
|
-
// create the segment
|
481
|
-
auto target = reinterpret_cast<ListSegment *>(AllocateListData(allocator, source->capacity));
|
482
|
-
memcpy(target, source,
|
483
|
-
sizeof(ListSegment) + source->capacity * (sizeof(bool) + sizeof(uint64_t)) + sizeof(LinkedList));
|
484
|
-
target->next = nullptr;
|
485
|
-
|
486
|
-
auto target_linked_list = GetListChildData(target);
|
487
|
-
LinkedList linked_list(source_linked_child_list.total_capacity, nullptr, nullptr);
|
488
|
-
Store<LinkedList>(linked_list, data_ptr_cast(target_linked_list));
|
489
|
-
|
490
|
-
// recurse to copy the linked child list
|
491
|
-
auto target_linked_child_list = Load<LinkedList>(data_ptr_cast(GetListChildData(target)));
|
492
|
-
D_ASSERT(functions.child_functions.size() == 1);
|
493
|
-
functions.child_functions[0].CopyLinkedList(source_linked_child_list, target_linked_child_list, allocator);
|
494
|
-
|
495
|
-
// store the updated linked list
|
496
|
-
Store<LinkedList>(target_linked_child_list, data_ptr_cast(GetListChildData(target)));
|
497
|
-
return target;
|
498
|
-
}
|
499
|
-
|
500
|
-
static ListSegment *CopyDataFromStructSegment(const ListSegmentFunctions &functions, const ListSegment *source,
|
501
|
-
ArenaAllocator &allocator) {
|
502
|
-
|
503
|
-
auto source_child_count = functions.child_functions.size();
|
504
|
-
auto target = reinterpret_cast<ListSegment *>(AllocateStructData(allocator, source->capacity, source_child_count));
|
505
|
-
memcpy(target, source,
|
506
|
-
sizeof(ListSegment) + source->capacity * sizeof(bool) + source_child_count * sizeof(ListSegment *));
|
507
|
-
target->next = nullptr;
|
508
|
-
|
509
|
-
// recurse and copy the children
|
510
|
-
auto source_child_segments = GetStructData(source);
|
511
|
-
auto target_child_segments = GetStructData(target);
|
512
|
-
|
513
|
-
for (idx_t i = 0; i < functions.child_functions.size(); i++) {
|
514
|
-
auto child_function = functions.child_functions[i];
|
515
|
-
auto source_child_segment = Load<ListSegment *>(const_data_ptr_cast(source_child_segments + i));
|
516
|
-
auto target_child_segment = child_function.copy_data(child_function, source_child_segment, allocator);
|
517
|
-
Store<ListSegment *>(target_child_segment, data_ptr_cast(target_child_segments + i));
|
518
|
-
}
|
519
|
-
return target;
|
520
|
-
}
|
521
|
-
|
522
|
-
void ListSegmentFunctions::CopyLinkedList(const LinkedList &source_list, LinkedList &target_list,
|
523
|
-
ArenaAllocator &allocator) const {
|
524
|
-
auto ©_data_from_segment = *this;
|
525
|
-
auto source_segment = source_list.first_segment;
|
526
|
-
|
527
|
-
while (source_segment) {
|
528
|
-
auto target_segment = copy_data_from_segment.copy_data(copy_data_from_segment, source_segment, allocator);
|
529
|
-
source_segment = source_segment->next;
|
530
|
-
|
531
|
-
if (!target_list.first_segment) {
|
532
|
-
target_list.first_segment = target_segment;
|
533
|
-
}
|
534
|
-
if (target_list.last_segment) {
|
535
|
-
target_list.last_segment->next = target_segment;
|
536
|
-
}
|
537
|
-
target_list.last_segment = target_segment;
|
538
|
-
}
|
539
|
-
}
|
540
|
-
|
541
453
|
//===--------------------------------------------------------------------===//
|
542
454
|
// Functions
|
543
455
|
//===--------------------------------------------------------------------===//
|
@@ -546,7 +458,6 @@ void SegmentPrimitiveFunction(ListSegmentFunctions &functions) {
|
|
546
458
|
functions.create_segment = CreatePrimitiveSegment<T>;
|
547
459
|
functions.write_data = WriteDataToPrimitiveSegment<T>;
|
548
460
|
functions.read_data = ReadDataFromPrimitiveSegment<T>;
|
549
|
-
functions.copy_data = CopyDataFromPrimitiveSegment<T>;
|
550
461
|
}
|
551
462
|
|
552
463
|
void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType &type) {
|
@@ -597,7 +508,6 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType
|
|
597
508
|
functions.create_segment = CreateListSegment;
|
598
509
|
functions.write_data = WriteDataToVarcharSegment;
|
599
510
|
functions.read_data = ReadDataFromVarcharSegment;
|
600
|
-
functions.copy_data = CopyDataFromListSegment;
|
601
511
|
|
602
512
|
functions.child_functions.emplace_back();
|
603
513
|
SegmentPrimitiveFunction<char>(functions.child_functions.back());
|
@@ -607,7 +517,6 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType
|
|
607
517
|
functions.create_segment = CreateListSegment;
|
608
518
|
functions.write_data = WriteDataToListSegment;
|
609
519
|
functions.read_data = ReadDataFromListSegment;
|
610
|
-
functions.copy_data = CopyDataFromListSegment;
|
611
520
|
|
612
521
|
// recurse
|
613
522
|
functions.child_functions.emplace_back();
|
@@ -618,7 +527,6 @@ void GetSegmentDataFunctions(ListSegmentFunctions &functions, const LogicalType
|
|
618
527
|
functions.create_segment = CreateStructSegment;
|
619
528
|
functions.write_data = WriteDataToStructSegment;
|
620
529
|
functions.read_data = ReadDataFromStructSegment;
|
621
|
-
functions.copy_data = CopyDataFromStructSegment;
|
622
530
|
|
623
531
|
// recurse
|
624
532
|
auto child_types = StructType::GetChildTypes(type);
|
@@ -892,6 +892,27 @@ void Vector::ToUnifiedFormat(idx_t count, UnifiedVectorFormat &format) {
|
|
892
892
|
}
|
893
893
|
}
|
894
894
|
|
895
|
+
void Vector::RecursiveToUnifiedFormat(Vector &input, idx_t count, RecursiveUnifiedVectorFormat &data) {
|
896
|
+
|
897
|
+
input.ToUnifiedFormat(count, data.unified);
|
898
|
+
|
899
|
+
if (input.GetType().InternalType() == PhysicalType::LIST) {
|
900
|
+
auto &child = ListVector::GetEntry(input);
|
901
|
+
auto child_count = ListVector::GetListSize(input);
|
902
|
+
data.children.emplace_back();
|
903
|
+
Vector::RecursiveToUnifiedFormat(child, child_count, data.children.back());
|
904
|
+
|
905
|
+
} else if (input.GetType().InternalType() == PhysicalType::STRUCT) {
|
906
|
+
auto &children = StructVector::GetEntries(input);
|
907
|
+
for (idx_t i = 0; i < children.size(); i++) {
|
908
|
+
data.children.emplace_back();
|
909
|
+
}
|
910
|
+
for (idx_t i = 0; i < children.size(); i++) {
|
911
|
+
Vector::RecursiveToUnifiedFormat(*children[i], count, data.children[i]);
|
912
|
+
}
|
913
|
+
}
|
914
|
+
}
|
915
|
+
|
895
916
|
void Vector::Sequence(int64_t start, int64_t increment, idx_t count) {
|
896
917
|
this->vector_type = VectorType::SEQUENCE_VECTOR;
|
897
918
|
this->buffer = make_buffer<VectorBuffer>(sizeof(int64_t) * 3);
|
@@ -31,8 +31,6 @@ struct hash<duckdb::hugeint_t> {
|
|
31
31
|
|
32
32
|
namespace duckdb {
|
33
33
|
|
34
|
-
using FrameBounds = std::pair<idx_t, idx_t>;
|
35
|
-
|
36
34
|
template <class KEY_TYPE>
|
37
35
|
struct ModeState {
|
38
36
|
struct ModeAttr {
|
@@ -225,31 +223,31 @@ struct ModeFunction {
|
|
225
223
|
if (state.nonzero <= tau * state.frequency_map->size()) {
|
226
224
|
state.Reset();
|
227
225
|
// for f ∈ F do
|
228
|
-
for (auto f = frame.
|
226
|
+
for (auto f = frame.start; f < frame.end; ++f) {
|
229
227
|
if (included(f)) {
|
230
228
|
state.ModeAdd(KEY_TYPE(data[f]), f);
|
231
229
|
}
|
232
230
|
}
|
233
231
|
} else {
|
234
232
|
// for f ∈ P \ F do
|
235
|
-
for (auto p = prev.
|
233
|
+
for (auto p = prev.start; p < frame.start; ++p) {
|
236
234
|
if (included(p)) {
|
237
235
|
state.ModeRm(KEY_TYPE(data[p]), p);
|
238
236
|
}
|
239
237
|
}
|
240
|
-
for (auto p = frame.
|
238
|
+
for (auto p = frame.end; p < prev.end; ++p) {
|
241
239
|
if (included(p)) {
|
242
240
|
state.ModeRm(KEY_TYPE(data[p]), p);
|
243
241
|
}
|
244
242
|
}
|
245
243
|
|
246
244
|
// for f ∈ F \ P do
|
247
|
-
for (auto f = frame.
|
245
|
+
for (auto f = frame.start; f < prev.start; ++f) {
|
248
246
|
if (included(f)) {
|
249
247
|
state.ModeAdd(KEY_TYPE(data[f]), f);
|
250
248
|
}
|
251
249
|
}
|
252
|
-
for (auto f = prev.
|
250
|
+
for (auto f = prev.end; f < frame.end; ++f) {
|
253
251
|
if (included(f)) {
|
254
252
|
state.ModeAdd(KEY_TYPE(data[f]), f);
|
255
253
|
}
|
@@ -37,8 +37,6 @@ inline interval_t operator-(const interval_t &lhs, const interval_t &rhs) {
|
|
37
37
|
return Interval::FromMicro(Interval::GetMicro(lhs) - Interval::GetMicro(rhs));
|
38
38
|
}
|
39
39
|
|
40
|
-
using FrameBounds = std::pair<idx_t, idx_t>;
|
41
|
-
|
42
40
|
template <typename SAVE_TYPE>
|
43
41
|
struct QuantileState {
|
44
42
|
using SaveType = SAVE_TYPE;
|
@@ -89,7 +87,7 @@ void ReuseIndexes(idx_t *index, const FrameBounds &frame, const FrameBounds &pre
|
|
89
87
|
idx_t j = 0;
|
90
88
|
|
91
89
|
// Copy overlapping indices
|
92
|
-
for (idx_t p = 0; p < (prev.
|
90
|
+
for (idx_t p = 0; p < (prev.end - prev.start); ++p) {
|
93
91
|
auto idx = index[p];
|
94
92
|
|
95
93
|
// Shift down into any hole
|
@@ -98,7 +96,7 @@ void ReuseIndexes(idx_t *index, const FrameBounds &frame, const FrameBounds &pre
|
|
98
96
|
}
|
99
97
|
|
100
98
|
// Skip overlapping values
|
101
|
-
if (frame.
|
99
|
+
if (frame.start <= idx && idx < frame.end) {
|
102
100
|
++j;
|
103
101
|
}
|
104
102
|
}
|
@@ -106,15 +104,15 @@ void ReuseIndexes(idx_t *index, const FrameBounds &frame, const FrameBounds &pre
|
|
106
104
|
// Insert new indices
|
107
105
|
if (j > 0) {
|
108
106
|
// Overlap: append the new ends
|
109
|
-
for (auto f = frame.
|
107
|
+
for (auto f = frame.start; f < prev.start; ++f, ++j) {
|
110
108
|
index[j] = f;
|
111
109
|
}
|
112
|
-
for (auto f = prev.
|
110
|
+
for (auto f = prev.end; f < frame.end; ++f, ++j) {
|
113
111
|
index[j] = f;
|
114
112
|
}
|
115
113
|
} else {
|
116
114
|
// No overlap: overwrite with new values
|
117
|
-
for (auto f = frame.
|
115
|
+
for (auto f = frame.start; f < frame.end; ++f, ++j) {
|
118
116
|
index[j] = f;
|
119
117
|
}
|
120
118
|
}
|
@@ -124,17 +122,17 @@ static idx_t ReplaceIndex(idx_t *index, const FrameBounds &frame, const FrameBou
|
|
124
122
|
D_ASSERT(index);
|
125
123
|
|
126
124
|
idx_t j = 0;
|
127
|
-
for (idx_t p = 0; p < (prev.
|
125
|
+
for (idx_t p = 0; p < (prev.end - prev.start); ++p) {
|
128
126
|
auto idx = index[p];
|
129
127
|
if (j != p) {
|
130
128
|
break;
|
131
129
|
}
|
132
130
|
|
133
|
-
if (frame.
|
131
|
+
if (frame.start <= idx && idx < frame.end) {
|
134
132
|
++j;
|
135
133
|
}
|
136
134
|
}
|
137
|
-
index[j] = frame.
|
135
|
+
index[j] = frame.end - 1;
|
138
136
|
|
139
137
|
return j;
|
140
138
|
}
|
@@ -560,7 +558,7 @@ struct QuantileScalarOperation : public QuantileOperation {
|
|
560
558
|
|
561
559
|
// Lazily initialise frame state
|
562
560
|
auto prev_pos = state.pos;
|
563
|
-
state.SetPos(frame.
|
561
|
+
state.SetPos(frame.end - frame.start);
|
564
562
|
|
565
563
|
auto index = state.w.data();
|
566
564
|
D_ASSERT(index);
|
@@ -572,11 +570,11 @@ struct QuantileScalarOperation : public QuantileOperation {
|
|
572
570
|
const auto q = bind_data.quantiles[0];
|
573
571
|
|
574
572
|
bool replace = false;
|
575
|
-
if (frame.
|
573
|
+
if (frame.start == prev.start + 1 && frame.end == prev.end + 1) {
|
576
574
|
// Fixed frame size
|
577
575
|
const auto j = ReplaceIndex(index, frame, prev);
|
578
576
|
// We can only replace if the number of NULLs has not changed
|
579
|
-
if (included.AllValid() || included(prev.
|
577
|
+
if (included.AllValid() || included(prev.start) == included(prev.end)) {
|
580
578
|
Interpolator<DISCRETE> interp(q, prev_pos, false);
|
581
579
|
replace = CanReplace(index, data, j, interp.FRN, interp.CRN, included);
|
582
580
|
if (replace) {
|
@@ -720,7 +718,7 @@ struct QuantileListOperation : public QuantileOperation {
|
|
720
718
|
|
721
719
|
// Lazily initialise frame state
|
722
720
|
auto prev_pos = state.pos;
|
723
|
-
state.SetPos(frame.
|
721
|
+
state.SetPos(frame.end - frame.start);
|
724
722
|
|
725
723
|
auto index = state.w.data();
|
726
724
|
|
@@ -731,11 +729,11 @@ struct QuantileListOperation : public QuantileOperation {
|
|
731
729
|
// then Q25 must be recomputed, but Q50 and Q75 are unaffected.
|
732
730
|
// For a single element list, this reduces to the scalar case.
|
733
731
|
std::pair<idx_t, idx_t> replaceable {state.pos, 0};
|
734
|
-
if (frame.
|
732
|
+
if (frame.start == prev.start + 1 && frame.end == prev.end + 1) {
|
735
733
|
// Fixed frame size
|
736
734
|
const auto j = ReplaceIndex(index, frame, prev);
|
737
735
|
// We can only replace if the number of NULLs has not changed
|
738
|
-
if (included.AllValid() || included(prev.
|
736
|
+
if (included.AllValid() || included(prev.start) == included(prev.end)) {
|
739
737
|
for (const auto &q : bind_data.order) {
|
740
738
|
const auto &quantile = bind_data.quantiles[q];
|
741
739
|
Interpolator<DISCRETE> interp(quantile, prev_pos, false);
|
@@ -1062,7 +1060,7 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation {
|
|
1062
1060
|
|
1063
1061
|
// Lazily initialise frame state
|
1064
1062
|
auto prev_pos = state.pos;
|
1065
|
-
state.SetPos(frame.
|
1063
|
+
state.SetPos(frame.end - frame.start);
|
1066
1064
|
|
1067
1065
|
auto index = state.w.data();
|
1068
1066
|
D_ASSERT(index);
|
@@ -1085,11 +1083,11 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation {
|
|
1085
1083
|
const float q = 0.5;
|
1086
1084
|
|
1087
1085
|
bool replace = false;
|
1088
|
-
if (frame.
|
1086
|
+
if (frame.start == prev.start + 1 && frame.end == prev.end + 1) {
|
1089
1087
|
// Fixed frame size
|
1090
1088
|
const auto j = ReplaceIndex(index, frame, prev);
|
1091
1089
|
// We can only replace if the number of NULLs has not changed
|
1092
|
-
if (included.AllValid() || included(prev.
|
1090
|
+
if (included.AllValid() || included(prev.start) == included(prev.end)) {
|
1093
1091
|
Interpolator<false> interp(q, prev_pos, false);
|
1094
1092
|
replace = CanReplace(index, data, j, interp.FRN, interp.CRN, included);
|
1095
1093
|
if (replace) {
|