duckdb 0.8.2-dev1791.0 → 0.8.2-dev1862.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 +1 -0
- package/package.json +1 -1
- package/src/duckdb/src/common/constants.cpp +2 -1
- package/src/duckdb/src/common/enum_util.cpp +5 -5
- package/src/duckdb/src/core_functions/function_list.cpp +2 -0
- package/src/duckdb/src/core_functions/scalar/debug/vector_type.cpp +23 -0
- package/src/duckdb/src/execution/index/art/art.cpp +49 -108
- package/src/duckdb/src/execution/index/art/art_key.cpp +0 -11
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +10 -14
- package/src/duckdb/src/execution/index/art/iterator.cpp +13 -19
- package/src/duckdb/src/execution/index/art/leaf.cpp +290 -241
- package/src/duckdb/src/execution/index/art/node.cpp +104 -95
- package/src/duckdb/src/execution/index/art/node16.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node256.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node4.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node48.cpp +6 -6
- package/src/duckdb/src/execution/index/art/prefix.cpp +49 -39
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +34 -1175
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +4 -14
- package/src/duckdb/src/execution/window_executor.cpp +1280 -0
- package/src/duckdb/src/execution/window_segment_tree.cpp +224 -117
- package/src/duckdb/src/function/table/read_csv.cpp +4 -3
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/constants.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/type_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/typedefs.hpp +8 -0
- package/src/duckdb/src/include/duckdb/core_functions/scalar/debug_functions.hpp +27 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +0 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +22 -24
- package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +43 -40
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +119 -40
- package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +4 -2
- package/src/duckdb/src/include/duckdb/execution/window_executor.hpp +313 -0
- package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +60 -53
- package/src/duckdb/src/storage/compression/rle.cpp +52 -12
- package/src/duckdb/ub_src_core_functions_scalar_debug.cpp +2 -0
- package/src/duckdb/ub_src_execution.cpp +2 -0
- package/src/duckdb/ub_src_execution_index_art.cpp +0 -4
- package/src/duckdb/src/execution/index/art/leaf_segment.cpp +0 -52
- package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +0 -22
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +0 -38
- package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +0 -58
package/binding.gyp
CHANGED
@@ -45,6 +45,7 @@
|
|
45
45
|
"src/duckdb/ub_src_core_functions_scalar_bit.cpp",
|
46
46
|
"src/duckdb/ub_src_core_functions_scalar_blob.cpp",
|
47
47
|
"src/duckdb/ub_src_core_functions_scalar_date.cpp",
|
48
|
+
"src/duckdb/ub_src_core_functions_scalar_debug.cpp",
|
48
49
|
"src/duckdb/ub_src_core_functions_scalar_enum.cpp",
|
49
50
|
"src/duckdb/ub_src_core_functions_scalar_generic.cpp",
|
50
51
|
"src/duckdb/ub_src_core_functions_scalar_list.cpp",
|
package/package.json
CHANGED
@@ -7,7 +7,8 @@
|
|
7
7
|
namespace duckdb {
|
8
8
|
|
9
9
|
constexpr const idx_t DConstants::INVALID_INDEX;
|
10
|
-
const row_t MAX_ROW_ID =
|
10
|
+
const row_t MAX_ROW_ID = 36028797018960000ULL; // 2^55
|
11
|
+
const row_t MAX_ROW_ID_LOCAL = 72057594037920000ULL; // 2^56
|
11
12
|
const column_t COLUMN_IDENTIFIER_ROW_ID = (column_t)-1;
|
12
13
|
const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE] = {0};
|
13
14
|
const double PI = 3.141592653589793;
|
@@ -3112,8 +3112,6 @@ const char* EnumUtil::ToChars<NType>(NType value) {
|
|
3112
3112
|
switch(value) {
|
3113
3113
|
case NType::PREFIX:
|
3114
3114
|
return "PREFIX";
|
3115
|
-
case NType::LEAF_SEGMENT:
|
3116
|
-
return "LEAF_SEGMENT";
|
3117
3115
|
case NType::LEAF:
|
3118
3116
|
return "LEAF";
|
3119
3117
|
case NType::NODE_4:
|
@@ -3124,6 +3122,8 @@ const char* EnumUtil::ToChars<NType>(NType value) {
|
|
3124
3122
|
return "NODE_48";
|
3125
3123
|
case NType::NODE_256:
|
3126
3124
|
return "NODE_256";
|
3125
|
+
case NType::LEAF_INLINED:
|
3126
|
+
return "LEAF_INLINED";
|
3127
3127
|
default:
|
3128
3128
|
throw NotImplementedException(StringUtil::Format("Enum value: '%d' not implemented", value));
|
3129
3129
|
}
|
@@ -3134,9 +3134,6 @@ NType EnumUtil::FromString<NType>(const char *value) {
|
|
3134
3134
|
if (StringUtil::Equals(value, "PREFIX")) {
|
3135
3135
|
return NType::PREFIX;
|
3136
3136
|
}
|
3137
|
-
if (StringUtil::Equals(value, "LEAF_SEGMENT")) {
|
3138
|
-
return NType::LEAF_SEGMENT;
|
3139
|
-
}
|
3140
3137
|
if (StringUtil::Equals(value, "LEAF")) {
|
3141
3138
|
return NType::LEAF;
|
3142
3139
|
}
|
@@ -3152,6 +3149,9 @@ NType EnumUtil::FromString<NType>(const char *value) {
|
|
3152
3149
|
if (StringUtil::Equals(value, "NODE_256")) {
|
3153
3150
|
return NType::NODE_256;
|
3154
3151
|
}
|
3152
|
+
if (StringUtil::Equals(value, "LEAF_INLINED")) {
|
3153
|
+
return NType::LEAF_INLINED;
|
3154
|
+
}
|
3155
3155
|
throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented", value));
|
3156
3156
|
}
|
3157
3157
|
|
@@ -17,6 +17,7 @@
|
|
17
17
|
#include "duckdb/core_functions/scalar/string_functions.hpp"
|
18
18
|
#include "duckdb/core_functions/scalar/struct_functions.hpp"
|
19
19
|
#include "duckdb/core_functions/scalar/union_functions.hpp"
|
20
|
+
#include "duckdb/core_functions/scalar/debug_functions.hpp"
|
20
21
|
|
21
22
|
namespace duckdb {
|
22
23
|
|
@@ -339,6 +340,7 @@ static StaticFunctionDefinition internal_functions[] = {
|
|
339
340
|
DUCKDB_AGGREGATE_FUNCTION(VarPopFun),
|
340
341
|
DUCKDB_AGGREGATE_FUNCTION(VarSampFun),
|
341
342
|
DUCKDB_AGGREGATE_FUNCTION_ALIAS(VarianceFun),
|
343
|
+
DUCKDB_SCALAR_FUNCTION(VectorTypeFun),
|
342
344
|
DUCKDB_SCALAR_FUNCTION(VersionFun),
|
343
345
|
DUCKDB_SCALAR_FUNCTION_SET(WeekFun),
|
344
346
|
DUCKDB_SCALAR_FUNCTION_SET(WeekDayFun),
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#include "duckdb/core_functions/scalar/debug_functions.hpp"
|
2
|
+
|
3
|
+
#include "duckdb/common/exception.hpp"
|
4
|
+
#include "duckdb/common/vector_operations/vector_operations.hpp"
|
5
|
+
#include "duckdb/planner/expression/bound_function_expression.hpp"
|
6
|
+
#include "duckdb/common/enum_util.hpp"
|
7
|
+
|
8
|
+
namespace duckdb {
|
9
|
+
|
10
|
+
static void VectorTypeFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
11
|
+
result.SetVectorType(VectorType::CONSTANT_VECTOR);
|
12
|
+
auto data = ConstantVector::GetData<string_t>(result);
|
13
|
+
data[0] = StringVector::AddString(result, EnumUtil::ToString(input.data[0].GetVectorType()));
|
14
|
+
}
|
15
|
+
|
16
|
+
ScalarFunction VectorTypeFun::GetFunction() {
|
17
|
+
return ScalarFunction("vector_type", // name of the function
|
18
|
+
{LogicalType::ANY}, // argument list
|
19
|
+
LogicalType::VARCHAR, // return type
|
20
|
+
VectorTypeFunction);
|
21
|
+
}
|
22
|
+
|
23
|
+
} // namespace duckdb
|
@@ -5,7 +5,6 @@
|
|
5
5
|
#include "duckdb/execution/expression_executor.hpp"
|
6
6
|
#include "duckdb/storage/arena_allocator.hpp"
|
7
7
|
#include "duckdb/execution/index/art/art_key.hpp"
|
8
|
-
#include "duckdb/execution/index/art/leaf_segment.hpp"
|
9
8
|
#include "duckdb/execution/index/art/prefix.hpp"
|
10
9
|
#include "duckdb/execution/index/art/leaf.hpp"
|
11
10
|
#include "duckdb/execution/index/art/node4.hpp"
|
@@ -44,7 +43,6 @@ ART::ART(const vector<column_t> &column_ids, TableIOManager &table_io_manager,
|
|
44
43
|
|
45
44
|
// initialize all allocators
|
46
45
|
allocators.emplace_back(make_uniq<FixedSizeAllocator>(sizeof(Prefix), buffer_manager.GetBufferAllocator()));
|
47
|
-
allocators.emplace_back(make_uniq<FixedSizeAllocator>(sizeof(LeafSegment), buffer_manager.GetBufferAllocator()));
|
48
46
|
allocators.emplace_back(make_uniq<FixedSizeAllocator>(sizeof(Leaf), buffer_manager.GetBufferAllocator()));
|
49
47
|
allocators.emplace_back(make_uniq<FixedSizeAllocator>(sizeof(Node4), buffer_manager.GetBufferAllocator()));
|
50
48
|
allocators.emplace_back(make_uniq<FixedSizeAllocator>(sizeof(Node16), buffer_manager.GetBufferAllocator()));
|
@@ -54,8 +52,8 @@ ART::ART(const vector<column_t> &column_ids, TableIOManager &table_io_manager,
|
|
54
52
|
// set the root node of the tree
|
55
53
|
tree = make_uniq<Node>();
|
56
54
|
if (block_id != DConstants::INVALID_INDEX) {
|
57
|
-
tree->
|
58
|
-
tree->
|
55
|
+
tree->SetSerialized();
|
56
|
+
tree->SetPtr(block_id, block_offset);
|
59
57
|
tree->Deserialize(*this);
|
60
58
|
}
|
61
59
|
serialized_data_pointer = BlockPointer(block_id, block_offset);
|
@@ -308,7 +306,7 @@ bool Construct(ART &art, vector<ARTKey> &keys, row_t *row_ids, Node &node, KeySe
|
|
308
306
|
reference<Node> ref_node(node);
|
309
307
|
Prefix::New(art, ref_node, start_key, prefix_start, start_key.len - prefix_start);
|
310
308
|
if (single_row_id) {
|
311
|
-
Leaf::New(
|
309
|
+
Leaf::New(ref_node, row_ids[key_section.start]);
|
312
310
|
} else {
|
313
311
|
Leaf::New(art, ref_node, row_ids + key_section.start, num_row_ids);
|
314
312
|
}
|
@@ -358,19 +356,9 @@ bool ART::ConstructFromSorted(idx_t count, vector<ARTKey> &keys, Vector &row_ide
|
|
358
356
|
D_ASSERT(!VerifyAndToStringInternal(true).empty());
|
359
357
|
for (idx_t i = 0; i < count; i++) {
|
360
358
|
D_ASSERT(!keys[i].Empty());
|
361
|
-
auto
|
362
|
-
D_ASSERT(
|
363
|
-
|
364
|
-
|
365
|
-
if (leaf.IsInlined()) {
|
366
|
-
D_ASSERT(row_ids[i] == leaf.row_ids.inlined);
|
367
|
-
continue;
|
368
|
-
}
|
369
|
-
|
370
|
-
D_ASSERT(leaf.row_ids.ptr.IsSet());
|
371
|
-
Node leaf_segment = leaf.row_ids.ptr;
|
372
|
-
auto position = leaf.FindRowId(*this, leaf_segment, row_ids[i]);
|
373
|
-
D_ASSERT(position != (uint32_t)DConstants::INVALID_INDEX);
|
359
|
+
auto leaf = Lookup(*tree, keys[i], 0);
|
360
|
+
D_ASSERT(leaf.IsSet());
|
361
|
+
D_ASSERT(Leaf::ContainsRowId(*this, leaf, row_ids[i]));
|
374
362
|
}
|
375
363
|
#endif
|
376
364
|
|
@@ -431,19 +419,9 @@ PreservedError ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) {
|
|
431
419
|
continue;
|
432
420
|
}
|
433
421
|
|
434
|
-
auto
|
435
|
-
D_ASSERT(
|
436
|
-
|
437
|
-
|
438
|
-
if (leaf.IsInlined()) {
|
439
|
-
D_ASSERT(row_identifiers[i] == leaf.row_ids.inlined);
|
440
|
-
continue;
|
441
|
-
}
|
442
|
-
|
443
|
-
D_ASSERT(leaf.row_ids.ptr.IsSet());
|
444
|
-
Node leaf_segment = leaf.row_ids.ptr;
|
445
|
-
auto position = leaf.FindRowId(*this, leaf_segment, row_identifiers[i]);
|
446
|
-
D_ASSERT(position != (uint32_t)DConstants::INVALID_INDEX);
|
422
|
+
auto leaf = Lookup(*tree, keys[i], 0);
|
423
|
+
D_ASSERT(leaf.IsSet());
|
424
|
+
D_ASSERT(Leaf::ContainsRowId(*this, leaf, row_identifiers[i]));
|
447
425
|
}
|
448
426
|
#endif
|
449
427
|
|
@@ -471,19 +449,13 @@ void ART::VerifyAppend(DataChunk &chunk, ConflictManager &conflict_manager) {
|
|
471
449
|
CheckConstraintsForChunk(chunk, conflict_manager);
|
472
450
|
}
|
473
451
|
|
474
|
-
bool ART::InsertToLeaf(Node &
|
452
|
+
bool ART::InsertToLeaf(Node &leaf, const row_t &row_id) {
|
475
453
|
|
476
|
-
|
477
|
-
|
478
|
-
#ifdef DEBUG
|
479
|
-
for (idx_t k = 0; k < leaf.count; k++) {
|
480
|
-
D_ASSERT(leaf.GetRowId(*this, k) != row_id);
|
481
|
-
}
|
482
|
-
#endif
|
483
|
-
if (IsUnique() && leaf.count != 0) {
|
454
|
+
if (IsUnique()) {
|
484
455
|
return false;
|
485
456
|
}
|
486
|
-
|
457
|
+
|
458
|
+
Leaf::Insert(*this, leaf, row_id);
|
487
459
|
return true;
|
488
460
|
}
|
489
461
|
|
@@ -494,14 +466,14 @@ bool ART::Insert(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id
|
|
494
466
|
D_ASSERT(depth <= key.len);
|
495
467
|
reference<Node> ref_node(node);
|
496
468
|
Prefix::New(*this, ref_node, key, depth, key.len - depth);
|
497
|
-
Leaf::New(
|
469
|
+
Leaf::New(ref_node, row_id);
|
498
470
|
return true;
|
499
471
|
}
|
500
472
|
|
501
|
-
auto node_type = node.
|
473
|
+
auto node_type = node.GetType();
|
502
474
|
|
503
475
|
// insert the row ID into this leaf
|
504
|
-
if (node_type == NType::LEAF) {
|
476
|
+
if (node_type == NType::LEAF || node_type == NType::LEAF_INLINED) {
|
505
477
|
return InsertToLeaf(node, row_id);
|
506
478
|
}
|
507
479
|
|
@@ -518,13 +490,11 @@ bool ART::Insert(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id
|
|
518
490
|
|
519
491
|
// insert a new leaf node at key[depth]
|
520
492
|
Node leaf_node;
|
493
|
+
reference<Node> ref_node(leaf_node);
|
521
494
|
if (depth + 1 < key.len) {
|
522
|
-
reference<Node> ref_node(leaf_node);
|
523
495
|
Prefix::New(*this, ref_node, key, depth + 1, key.len - depth - 1);
|
524
|
-
Leaf::New(*this, ref_node, row_id);
|
525
|
-
} else {
|
526
|
-
Leaf::New(*this, leaf_node, row_id);
|
527
496
|
}
|
497
|
+
Leaf::New(ref_node, row_id);
|
528
498
|
Node::InsertChild(*this, node, key[depth], leaf_node);
|
529
499
|
return true;
|
530
500
|
}
|
@@ -534,7 +504,7 @@ bool ART::Insert(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id
|
|
534
504
|
auto mismatch_position = Prefix::Traverse(*this, next_node, key, depth);
|
535
505
|
|
536
506
|
// prefix matches key
|
537
|
-
if (next_node.get().
|
507
|
+
if (next_node.get().GetType() != NType::PREFIX) {
|
538
508
|
return Insert(next_node, key, depth, row_id);
|
539
509
|
}
|
540
510
|
|
@@ -550,13 +520,11 @@ bool ART::Insert(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id
|
|
550
520
|
|
551
521
|
// insert new leaf
|
552
522
|
Node leaf_node;
|
523
|
+
reference<Node> ref_node(leaf_node);
|
553
524
|
if (depth + 1 < key.len) {
|
554
|
-
reference<Node> ref_node(leaf_node);
|
555
525
|
Prefix::New(*this, ref_node, key, depth + 1, key.len - depth - 1);
|
556
|
-
Leaf::New(*this, ref_node, row_id);
|
557
|
-
} else {
|
558
|
-
Leaf::New(*this, leaf_node, row_id);
|
559
526
|
}
|
527
|
+
Leaf::New(ref_node, row_id);
|
560
528
|
Node4::InsertChild(*this, next_node, key[depth], leaf_node);
|
561
529
|
return true;
|
562
530
|
}
|
@@ -596,19 +564,9 @@ void ART::Delete(IndexLock &state, DataChunk &input, Vector &row_ids) {
|
|
596
564
|
continue;
|
597
565
|
}
|
598
566
|
|
599
|
-
auto
|
600
|
-
if (
|
601
|
-
|
602
|
-
|
603
|
-
if (leaf.IsInlined()) {
|
604
|
-
D_ASSERT(row_identifiers[i] != leaf.row_ids.inlined);
|
605
|
-
continue;
|
606
|
-
}
|
607
|
-
|
608
|
-
D_ASSERT(leaf.row_ids.ptr.IsSet());
|
609
|
-
Node leaf_segment = leaf.row_ids.ptr;
|
610
|
-
auto position = leaf.FindRowId(*this, leaf_segment, row_identifiers[i]);
|
611
|
-
D_ASSERT(position == (uint32_t)DConstants::INVALID_INDEX);
|
567
|
+
auto leaf = Lookup(*tree, keys[i], 0);
|
568
|
+
if (leaf.IsSet()) {
|
569
|
+
D_ASSERT(!Leaf::ContainsRowId(*this, leaf, row_identifiers[i]));
|
612
570
|
}
|
613
571
|
}
|
614
572
|
#endif
|
@@ -622,21 +580,17 @@ void ART::Erase(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id)
|
|
622
580
|
|
623
581
|
// handle prefix
|
624
582
|
reference<Node> next_node(node);
|
625
|
-
if (next_node.get().
|
583
|
+
if (next_node.get().GetType() == NType::PREFIX) {
|
626
584
|
Prefix::Traverse(*this, next_node, key, depth);
|
627
|
-
if (next_node.get().
|
585
|
+
if (next_node.get().GetType() == NType::PREFIX) {
|
628
586
|
return;
|
629
587
|
}
|
630
588
|
}
|
631
589
|
|
632
590
|
// delete a row ID from a leaf (root is leaf with possible prefix nodes)
|
633
|
-
if (next_node.get().
|
634
|
-
|
635
|
-
leaf.Remove(*this, row_id);
|
636
|
-
|
637
|
-
if (leaf.count == 0) {
|
591
|
+
if (next_node.get().GetType() == NType::LEAF || next_node.get().GetType() == NType::LEAF_INLINED) {
|
592
|
+
if (Leaf::Remove(*this, next_node, row_id)) {
|
638
593
|
Node::Free(*this, node);
|
639
|
-
node.Reset();
|
640
594
|
}
|
641
595
|
return;
|
642
596
|
}
|
@@ -648,20 +602,16 @@ void ART::Erase(Node &node, const ARTKey &key, idx_t depth, const row_t &row_id)
|
|
648
602
|
|
649
603
|
auto temp_depth = depth + 1;
|
650
604
|
reference<Node> child_node(*child);
|
651
|
-
if (child_node.get().
|
605
|
+
if (child_node.get().GetType() == NType::PREFIX) {
|
652
606
|
Prefix::Traverse(*this, child_node, key, temp_depth);
|
653
|
-
if (child_node.get().
|
607
|
+
if (child_node.get().GetType() == NType::PREFIX) {
|
654
608
|
return;
|
655
609
|
}
|
656
610
|
}
|
657
611
|
|
658
|
-
if (child_node.get().
|
612
|
+
if (child_node.get().GetType() == NType::LEAF || child_node.get().GetType() == NType::LEAF_INLINED) {
|
659
613
|
// leaf found, remove entry
|
660
|
-
|
661
|
-
leaf.Remove(*this, row_id);
|
662
|
-
|
663
|
-
if (leaf.count == 0) {
|
664
|
-
// leaf is empty, delete leaf, decrement node counter and maybe shrink node
|
614
|
+
if (Leaf::Remove(*this, child_node, row_id)) {
|
665
615
|
Node::DeleteChild(*this, next_node, node, key[depth]);
|
666
616
|
}
|
667
617
|
return;
|
@@ -713,20 +663,11 @@ static ARTKey CreateKey(ArenaAllocator &allocator, PhysicalType type, Value &val
|
|
713
663
|
|
714
664
|
bool ART::SearchEqual(ARTKey &key, idx_t max_count, vector<row_t> &result_ids) {
|
715
665
|
|
716
|
-
auto
|
717
|
-
if (!
|
666
|
+
auto leaf = Lookup(*tree, key, 0);
|
667
|
+
if (!leaf.IsSet()) {
|
718
668
|
return true;
|
719
669
|
}
|
720
|
-
|
721
|
-
auto &leaf = Leaf::Get(*this, leaf_node);
|
722
|
-
if (leaf.count > max_count) {
|
723
|
-
return false;
|
724
|
-
}
|
725
|
-
for (idx_t i = 0; i < leaf.count; i++) {
|
726
|
-
row_t row_id = leaf.GetRowId(*this, i);
|
727
|
-
result_ids.push_back(row_id);
|
728
|
-
}
|
729
|
-
return true;
|
670
|
+
return Leaf::GetRowIds(*this, leaf, result_ids, max_count);
|
730
671
|
}
|
731
672
|
|
732
673
|
void ART::SearchEqualJoinNoFetch(ARTKey &key, idx_t &result_size) {
|
@@ -738,8 +679,10 @@ void ART::SearchEqualJoinNoFetch(ARTKey &key, idx_t &result_size) {
|
|
738
679
|
return;
|
739
680
|
}
|
740
681
|
|
741
|
-
|
742
|
-
|
682
|
+
// we only perform index joins on PK/FK columns
|
683
|
+
D_ASSERT(leaf_node.GetType() == NType::LEAF_INLINED);
|
684
|
+
result_size = 1;
|
685
|
+
return;
|
743
686
|
}
|
744
687
|
|
745
688
|
//===--------------------------------------------------------------------===//
|
@@ -752,14 +695,14 @@ Node ART::Lookup(Node node, const ARTKey &key, idx_t depth) {
|
|
752
695
|
|
753
696
|
// traverse prefix, if exists
|
754
697
|
reference<Node> next_node(node);
|
755
|
-
if (next_node.get().
|
698
|
+
if (next_node.get().GetType() == NType::PREFIX) {
|
756
699
|
Prefix::Traverse(*this, next_node, key, depth);
|
757
|
-
if (next_node.get().
|
700
|
+
if (next_node.get().GetType() == NType::PREFIX) {
|
758
701
|
return Node();
|
759
702
|
}
|
760
703
|
}
|
761
704
|
|
762
|
-
if (next_node.get().
|
705
|
+
if (next_node.get().GetType() == NType::LEAF || next_node.get().GetType() == NType::LEAF_INLINED) {
|
763
706
|
return next_node.get();
|
764
707
|
}
|
765
708
|
|
@@ -994,20 +937,18 @@ void ART::CheckConstraintsForChunk(DataChunk &input, ConflictManager &conflict_m
|
|
994
937
|
continue;
|
995
938
|
}
|
996
939
|
|
997
|
-
auto
|
998
|
-
if (!
|
940
|
+
auto leaf = Lookup(*tree, keys[i], 0);
|
941
|
+
if (!leaf.IsSet()) {
|
999
942
|
if (conflict_manager.AddMiss(i)) {
|
1000
943
|
found_conflict = i;
|
1001
944
|
}
|
1002
945
|
continue;
|
1003
946
|
}
|
1004
947
|
|
1005
|
-
//
|
1006
|
-
// NOTE:
|
1007
|
-
|
1008
|
-
|
1009
|
-
auto row_id = leaf.GetRowId(*this, 0);
|
1010
|
-
if (conflict_manager.AddHit(i, row_id)) {
|
948
|
+
// when we find a node, we need to update the 'matches' and 'row_ids'
|
949
|
+
// NOTE: leaves can have more than one row_id, but for UNIQUE/PRIMARY KEY they will only have one
|
950
|
+
D_ASSERT(leaf.GetType() == NType::LEAF_INLINED);
|
951
|
+
if (conflict_manager.AddHit(i, leaf.GetRowId())) {
|
1011
952
|
found_conflict = i;
|
1012
953
|
}
|
1013
954
|
}
|
@@ -1086,7 +1027,7 @@ void ART::Vacuum(IndexLock &state) {
|
|
1086
1027
|
}
|
1087
1028
|
|
1088
1029
|
// traverse the allocated memory of the tree to perform a vacuum
|
1089
|
-
|
1030
|
+
tree->Vacuum(*this, flags);
|
1090
1031
|
|
1091
1032
|
// finalize the vacuum operation
|
1092
1033
|
FinalizeVacuum(flags);
|
@@ -72,17 +72,6 @@ bool ARTKey::operator>(const ARTKey &k) const {
|
|
72
72
|
return len > k.len;
|
73
73
|
}
|
74
74
|
|
75
|
-
bool ARTKey::operator<(const ARTKey &k) const {
|
76
|
-
for (uint32_t i = 0; i < MinValue<uint32_t>(len, k.len); i++) {
|
77
|
-
if (data[i] < k.data[i]) {
|
78
|
-
return true;
|
79
|
-
} else if (data[i] > k.data[i]) {
|
80
|
-
return false;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
return len < k.len;
|
84
|
-
}
|
85
|
-
|
86
75
|
bool ARTKey::operator>=(const ARTKey &k) const {
|
87
76
|
for (uint32_t i = 0; i < MinValue<uint32_t>(len, k.len); i++) {
|
88
77
|
if (data[i] > k.data[i]) {
|
@@ -1,9 +1,5 @@
|
|
1
1
|
#include "duckdb/execution/index/art/fixed_size_allocator.hpp"
|
2
2
|
|
3
|
-
#include "duckdb/common/allocator.hpp"
|
4
|
-
#include "duckdb/common/exception.hpp"
|
5
|
-
#include "duckdb/common/helper.hpp"
|
6
|
-
|
7
3
|
namespace duckdb {
|
8
4
|
|
9
5
|
constexpr idx_t FixedSizeAllocator::BASE[];
|
@@ -46,7 +42,7 @@ FixedSizeAllocator::~FixedSizeAllocator() {
|
|
46
42
|
}
|
47
43
|
}
|
48
44
|
|
49
|
-
|
45
|
+
Node FixedSizeAllocator::New() {
|
50
46
|
|
51
47
|
// no more free pointers
|
52
48
|
if (buffers_with_free_space.empty()) {
|
@@ -77,19 +73,19 @@ SwizzleablePointer FixedSizeAllocator::New() {
|
|
77
73
|
buffers_with_free_space.erase(buffer_id);
|
78
74
|
}
|
79
75
|
|
80
|
-
return
|
76
|
+
return Node(buffer_id, offset);
|
81
77
|
}
|
82
78
|
|
83
|
-
void FixedSizeAllocator::Free(const
|
84
|
-
auto bitmask_ptr = reinterpret_cast<validity_t *>(buffers[ptr.
|
79
|
+
void FixedSizeAllocator::Free(const Node ptr) {
|
80
|
+
auto bitmask_ptr = reinterpret_cast<validity_t *>(buffers[ptr.GetBufferId()].ptr);
|
85
81
|
ValidityMask mask(bitmask_ptr);
|
86
|
-
D_ASSERT(!mask.RowIsValid(ptr.
|
87
|
-
mask.SetValid(ptr.
|
88
|
-
buffers_with_free_space.insert(ptr.
|
82
|
+
D_ASSERT(!mask.RowIsValid(ptr.GetOffset()));
|
83
|
+
mask.SetValid(ptr.GetOffset());
|
84
|
+
buffers_with_free_space.insert(ptr.GetBufferId());
|
89
85
|
|
90
86
|
D_ASSERT(total_allocations > 0);
|
91
|
-
D_ASSERT(buffers[ptr.
|
92
|
-
buffers[ptr.
|
87
|
+
D_ASSERT(buffers[ptr.GetBufferId()].allocation_count > 0);
|
88
|
+
buffers[ptr.GetBufferId()].allocation_count--;
|
93
89
|
total_allocations--;
|
94
90
|
}
|
95
91
|
|
@@ -172,7 +168,7 @@ void FixedSizeAllocator::FinalizeVacuum() {
|
|
172
168
|
}
|
173
169
|
}
|
174
170
|
|
175
|
-
|
171
|
+
Node FixedSizeAllocator::VacuumPointer(const Node ptr) {
|
176
172
|
|
177
173
|
// we do not need to adjust the bitmask of the old buffer, because we will free the entire
|
178
174
|
// buffer after the vacuum operation
|
@@ -58,17 +58,11 @@ bool Iterator::Scan(const ARTKey &upper_bound, const idx_t max_count, vector<row
|
|
58
58
|
}
|
59
59
|
}
|
60
60
|
|
61
|
-
//
|
62
|
-
if (
|
61
|
+
// copy all row IDs of this leaf into the result IDs (if they don't exceed max_count)
|
62
|
+
if (!Leaf::GetRowIds(*art, last_leaf, result_ids, max_count)) {
|
63
63
|
return false;
|
64
64
|
}
|
65
65
|
|
66
|
-
// FIXME: copy all at once to improve performance
|
67
|
-
for (idx_t i = 0; i < last_leaf->count; i++) {
|
68
|
-
row_t row_id = last_leaf->GetRowId(*art, i);
|
69
|
-
result_ids.push_back(row_id);
|
70
|
-
}
|
71
|
-
|
72
66
|
// get the next leaf
|
73
67
|
has_next = Next();
|
74
68
|
|
@@ -80,18 +74,18 @@ bool Iterator::Scan(const ARTKey &upper_bound, const idx_t max_count, vector<row
|
|
80
74
|
void Iterator::FindMinimum(Node &node) {
|
81
75
|
|
82
76
|
D_ASSERT(node.IsSet());
|
83
|
-
if (node.
|
77
|
+
if (node.IsSerialized()) {
|
84
78
|
node.Deserialize(*art);
|
85
79
|
}
|
86
80
|
|
87
81
|
// found the minimum
|
88
|
-
if (node.
|
89
|
-
last_leaf =
|
82
|
+
if (node.GetType() == NType::LEAF || node.GetType() == NType::LEAF_INLINED) {
|
83
|
+
last_leaf = node;
|
90
84
|
return;
|
91
85
|
}
|
92
86
|
|
93
87
|
// traverse the prefix
|
94
|
-
if (node.
|
88
|
+
if (node.GetType() == NType::PREFIX) {
|
95
89
|
auto &prefix = Prefix::Get(*art, node);
|
96
90
|
for (idx_t i = 0; i < prefix.data[Node::PREFIX_SIZE]; i++) {
|
97
91
|
current_key.Push(prefix.data[i]);
|
@@ -115,20 +109,20 @@ bool Iterator::LowerBound(Node &node, const ARTKey &key, const bool equal, idx_t
|
|
115
109
|
return false;
|
116
110
|
}
|
117
111
|
|
118
|
-
if (node.
|
112
|
+
if (node.IsSerialized()) {
|
119
113
|
node.Deserialize(*art);
|
120
114
|
}
|
121
115
|
|
122
116
|
// we found the lower bound
|
123
|
-
if (node.
|
117
|
+
if (node.GetType() == NType::LEAF || node.GetType() == NType::LEAF_INLINED) {
|
124
118
|
if (!equal && current_key == key) {
|
125
119
|
return Next();
|
126
120
|
}
|
127
|
-
last_leaf =
|
121
|
+
last_leaf = node;
|
128
122
|
return true;
|
129
123
|
}
|
130
124
|
|
131
|
-
if (node.
|
125
|
+
if (node.GetType() != NType::PREFIX) {
|
132
126
|
auto next_byte = key[depth];
|
133
127
|
auto child = node.GetNextChild(*art, next_byte);
|
134
128
|
if (!child) {
|
@@ -181,9 +175,9 @@ bool Iterator::Next() {
|
|
181
175
|
while (!nodes.empty()) {
|
182
176
|
|
183
177
|
auto &top = nodes.top();
|
184
|
-
D_ASSERT(top.node.
|
178
|
+
D_ASSERT(top.node.GetType() != NType::LEAF && top.node.GetType() != NType::LEAF_INLINED);
|
185
179
|
|
186
|
-
if (top.node.
|
180
|
+
if (top.node.GetType() == NType::PREFIX) {
|
187
181
|
PopNode();
|
188
182
|
continue;
|
189
183
|
}
|
@@ -211,7 +205,7 @@ bool Iterator::Next() {
|
|
211
205
|
}
|
212
206
|
|
213
207
|
void Iterator::PopNode() {
|
214
|
-
if (nodes.top().node.
|
208
|
+
if (nodes.top().node.GetType() == NType::PREFIX) {
|
215
209
|
auto prefix_byte_count = Prefix::Get(*art, nodes.top().node).data[Node::PREFIX_SIZE];
|
216
210
|
current_key.Pop(prefix_byte_count);
|
217
211
|
} else {
|