duckdb 0.8.2-dev2509.0 → 0.8.2-dev2669.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/extension/icu/icu-datepart.cpp +3 -3
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +1 -1
- package/src/duckdb/src/catalog/default/default_functions.cpp +5 -0
- package/src/duckdb/src/common/enum_util.cpp +35 -1
- package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +6 -0
- package/src/duckdb/src/execution/expression_executor/execute_parameter.cpp +2 -2
- package/src/duckdb/src/execution/index/art/art.cpp +43 -31
- package/src/duckdb/src/execution/index/art/leaf.cpp +47 -33
- package/src/duckdb/src/execution/index/art/node.cpp +31 -24
- package/src/duckdb/src/execution/index/art/prefix.cpp +100 -16
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +54 -31
- package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +32 -15
- package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +57 -0
- package/src/duckdb/src/function/table/arrow.cpp +95 -92
- package/src/duckdb/src/function/table/arrow_conversion.cpp +45 -68
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/case_insensitive_map.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/helper.hpp +8 -3
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +4 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +7 -5
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +6 -6
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +6 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +9 -11
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_create_index.hpp +8 -1
- package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +99 -0
- package/src/duckdb/src/include/duckdb/function/table/arrow.hpp +6 -36
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +3 -1
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +15 -14
- package/src/duckdb/src/include/duckdb/main/prepared_statement.hpp +73 -5
- package/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp +6 -6
- package/src/duckdb/src/include/duckdb/parser/expression/parameter_expression.hpp +17 -1
- package/src/duckdb/src/include/duckdb/parser/statement/execute_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +5 -3
- package/src/duckdb/src/include/duckdb/planner/bound_parameter_map.hpp +2 -1
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +20 -5
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_expression.hpp +3 -3
- package/src/duckdb/src/include/duckdb/planner/planner.hpp +4 -3
- package/src/duckdb/src/include/duckdb/storage/object_cache.hpp +1 -1
- package/src/duckdb/src/include/duckdb/verification/prepared_statement_verifier.hpp +1 -1
- package/src/duckdb/src/include/duckdb.h +16 -0
- package/src/duckdb/src/main/capi/pending-c.cpp +6 -0
- package/src/duckdb/src/main/capi/prepared-c.cpp +52 -4
- package/src/duckdb/src/main/client_context.cpp +27 -17
- package/src/duckdb/src/main/client_verify.cpp +17 -0
- package/src/duckdb/src/main/prepared_statement.cpp +38 -11
- package/src/duckdb/src/main/prepared_statement_data.cpp +23 -18
- package/src/duckdb/src/parser/expression/parameter_expression.cpp +7 -7
- package/src/duckdb/src/parser/statement/execute_statement.cpp +2 -2
- package/src/duckdb/src/parser/transform/expression/transform_param_ref.cpp +45 -26
- package/src/duckdb/src/parser/transform/statement/transform_prepare.cpp +28 -6
- package/src/duckdb/src/parser/transformer.cpp +27 -9
- package/src/duckdb/src/planner/binder/expression/bind_parameter_expression.cpp +10 -10
- package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +13 -7
- package/src/duckdb/src/planner/expression/bound_parameter_expression.cpp +13 -13
- package/src/duckdb/src/planner/planner.cpp +7 -6
- package/src/duckdb/src/storage/checkpoint_manager.cpp +1 -1
- package/src/duckdb/src/storage/serialization/serialize_expression.cpp +3 -3
- package/src/duckdb/src/storage/serialization/serialize_parsed_expression.cpp +2 -2
- package/src/duckdb/src/verification/prepared_statement_verifier.cpp +16 -11
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +9652 -9482
- package/src/duckdb/ub_src_function_table_arrow.cpp +2 -0
package/binding.gyp
CHANGED
@@ -87,6 +87,7 @@
|
|
87
87
|
"src/duckdb/ub_src_function_scalar_string_regexp.cpp",
|
88
88
|
"src/duckdb/ub_src_function_scalar_struct.cpp",
|
89
89
|
"src/duckdb/ub_src_function_scalar_system.cpp",
|
90
|
+
"src/duckdb/ub_src_function_table_arrow.cpp",
|
90
91
|
"src/duckdb/ub_src_function_table.cpp",
|
91
92
|
"src/duckdb/ub_src_function_table_system.cpp",
|
92
93
|
"src/duckdb/ub_src_function_table_version.cpp",
|
package/package.json
CHANGED
@@ -54,13 +54,13 @@ struct ICUDatePart : public ICUDateFunc {
|
|
54
54
|
}
|
55
55
|
|
56
56
|
static int64_t ExtractDayOfWeek(icu::Calendar *calendar, const uint64_t micros) {
|
57
|
-
|
57
|
+
// [Sun(0), Sat(6)]
|
58
58
|
return ExtractField(calendar, UCAL_DAY_OF_WEEK) - UCAL_SUNDAY;
|
59
59
|
}
|
60
60
|
|
61
61
|
static int64_t ExtractISODayOfWeek(icu::Calendar *calendar, const uint64_t micros) {
|
62
|
-
|
63
|
-
return ExtractField(calendar, UCAL_DAY_OF_WEEK);
|
62
|
+
// [Mon(1), Sun(7)]
|
63
|
+
return 1 + (ExtractField(calendar, UCAL_DAY_OF_WEEK) + 7 - UCAL_MONDAY) % 7;
|
64
64
|
}
|
65
65
|
|
66
66
|
static int64_t ExtractWeek(icu::Calendar *calendar, const uint64_t micros) {
|
@@ -43,7 +43,7 @@ void AddDataTableIndex(DataTable &storage, const ColumnList &columns, const vect
|
|
43
43
|
// create an adaptive radix tree around the expressions
|
44
44
|
if (index_block) {
|
45
45
|
art = make_uniq<ART>(column_ids, TableIOManager::Get(storage), std::move(unbound_expressions), constraint_type,
|
46
|
-
storage.db, index_block->block_id, index_block->offset);
|
46
|
+
storage.db, nullptr, index_block->block_id, index_block->offset);
|
47
47
|
} else {
|
48
48
|
art = make_uniq<ART>(column_ids, TableIOManager::Get(storage), std::move(unbound_expressions), constraint_type,
|
49
49
|
storage.db);
|
@@ -98,6 +98,11 @@ static DefaultMacro internal_macros[] = {
|
|
98
98
|
{DEFAULT_SCHEMA, "fmod", {"x", "y", nullptr}, "(x-y*floor(x/y))"},
|
99
99
|
{DEFAULT_SCHEMA, "count_if", {"l", nullptr}, "sum(if(l, 1, 0))"},
|
100
100
|
{DEFAULT_SCHEMA, "split_part", {"string", "delimiter", "position", nullptr}, "coalesce(string_split(string, delimiter)[position],'')"},
|
101
|
+
{DEFAULT_SCHEMA, "geomean", {"x", nullptr}, "exp(avg(ln(x)))"},
|
102
|
+
{DEFAULT_SCHEMA, "geometric_mean", {"x", nullptr}, "geomean(x)"},
|
103
|
+
|
104
|
+
{DEFAULT_SCHEMA, "list_reverse", {"l", nullptr}, "l[:-:-1]"},
|
105
|
+
{DEFAULT_SCHEMA, "array_reverse", {"l", nullptr}, "list_reverse(l)"},
|
101
106
|
|
102
107
|
// FIXME implement as actual function if we encounter a lot of performance issues. Complexity now: n * m, with hashing possibly n + m
|
103
108
|
{DEFAULT_SCHEMA, "list_intersect", {"l1", "l2", nullptr}, "list_filter(l1, (x) -> list_contains(l2, x))"},
|
@@ -71,7 +71,7 @@
|
|
71
71
|
#include "duckdb/function/macro_function.hpp"
|
72
72
|
#include "duckdb/function/scalar/compressed_materialization_functions.hpp"
|
73
73
|
#include "duckdb/function/scalar/strftime_format.hpp"
|
74
|
-
#include "duckdb/function/table/arrow.hpp"
|
74
|
+
#include "duckdb/function/table/arrow/arrow_duck_schema.hpp"
|
75
75
|
#include "duckdb/main/appender.hpp"
|
76
76
|
#include "duckdb/main/capi/capi_internal.hpp"
|
77
77
|
#include "duckdb/main/config.hpp"
|
@@ -81,6 +81,7 @@
|
|
81
81
|
#include "duckdb/parallel/interrupt.hpp"
|
82
82
|
#include "duckdb/parallel/task.hpp"
|
83
83
|
#include "duckdb/parser/constraint.hpp"
|
84
|
+
#include "duckdb/parser/expression/parameter_expression.hpp"
|
84
85
|
#include "duckdb/parser/expression/window_expression.hpp"
|
85
86
|
#include "duckdb/parser/parsed_data/alter_info.hpp"
|
86
87
|
#include "duckdb/parser/parsed_data/alter_scalar_function_info.hpp"
|
@@ -4404,6 +4405,39 @@ PragmaType EnumUtil::FromString<PragmaType>(const char *value) {
|
|
4404
4405
|
throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented", value));
|
4405
4406
|
}
|
4406
4407
|
|
4408
|
+
template<>
|
4409
|
+
const char* EnumUtil::ToChars<PreparedParamType>(PreparedParamType value) {
|
4410
|
+
switch(value) {
|
4411
|
+
case PreparedParamType::AUTO_INCREMENT:
|
4412
|
+
return "AUTO_INCREMENT";
|
4413
|
+
case PreparedParamType::POSITIONAL:
|
4414
|
+
return "POSITIONAL";
|
4415
|
+
case PreparedParamType::NAMED:
|
4416
|
+
return "NAMED";
|
4417
|
+
case PreparedParamType::INVALID:
|
4418
|
+
return "INVALID";
|
4419
|
+
default:
|
4420
|
+
throw NotImplementedException(StringUtil::Format("Enum value: '%d' not implemented", value));
|
4421
|
+
}
|
4422
|
+
}
|
4423
|
+
|
4424
|
+
template<>
|
4425
|
+
PreparedParamType EnumUtil::FromString<PreparedParamType>(const char *value) {
|
4426
|
+
if (StringUtil::Equals(value, "AUTO_INCREMENT")) {
|
4427
|
+
return PreparedParamType::AUTO_INCREMENT;
|
4428
|
+
}
|
4429
|
+
if (StringUtil::Equals(value, "POSITIONAL")) {
|
4430
|
+
return PreparedParamType::POSITIONAL;
|
4431
|
+
}
|
4432
|
+
if (StringUtil::Equals(value, "NAMED")) {
|
4433
|
+
return PreparedParamType::NAMED;
|
4434
|
+
}
|
4435
|
+
if (StringUtil::Equals(value, "INVALID")) {
|
4436
|
+
return PreparedParamType::INVALID;
|
4437
|
+
}
|
4438
|
+
throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented", value));
|
4439
|
+
}
|
4440
|
+
|
4407
4441
|
template<>
|
4408
4442
|
const char* EnumUtil::ToChars<ProfilerPrintFormat>(ProfilerPrintFormat value) {
|
4409
4443
|
switch(value) {
|
@@ -308,6 +308,12 @@ static void ArraySliceFunction(DataChunk &args, ExpressionState &state, Vector &
|
|
308
308
|
auto count = args.size();
|
309
309
|
|
310
310
|
Vector &list_or_str_vector = args.data[0];
|
311
|
+
if (list_or_str_vector.GetType().id() == LogicalTypeId::SQLNULL) {
|
312
|
+
auto &result_validity = FlatVector::Validity(result);
|
313
|
+
result_validity.SetInvalid(0);
|
314
|
+
return;
|
315
|
+
}
|
316
|
+
|
311
317
|
Vector &begin_vector = args.data[1];
|
312
318
|
Vector &end_vector = args.data[2];
|
313
319
|
|
@@ -15,8 +15,8 @@ void ExpressionExecutor::Execute(const BoundParameterExpression &expr, Expressio
|
|
15
15
|
const SelectionVector *sel, idx_t count, Vector &result) {
|
16
16
|
D_ASSERT(expr.parameter_data);
|
17
17
|
D_ASSERT(expr.parameter_data->return_type == expr.return_type);
|
18
|
-
D_ASSERT(expr.parameter_data->
|
19
|
-
result.Reference(expr.parameter_data->
|
18
|
+
D_ASSERT(expr.parameter_data->GetValue().type() == expr.return_type);
|
19
|
+
result.Reference(expr.parameter_data->GetValue());
|
20
20
|
}
|
21
21
|
|
22
22
|
} // namespace duckdb
|
@@ -33,21 +33,27 @@ struct ARTIndexScanState : public IndexScanState {
|
|
33
33
|
|
34
34
|
ART::ART(const vector<column_t> &column_ids, TableIOManager &table_io_manager,
|
35
35
|
const vector<unique_ptr<Expression>> &unbound_expressions, const IndexConstraintType constraint_type,
|
36
|
-
AttachedDatabase &db, const
|
36
|
+
AttachedDatabase &db, const shared_ptr<vector<FixedSizeAllocator>> &allocators_ptr, const idx_t block_id,
|
37
|
+
const idx_t block_offset)
|
37
38
|
|
38
|
-
: Index(db, IndexType::ART, table_io_manager, column_ids, unbound_expressions, constraint_type)
|
39
|
+
: Index(db, IndexType::ART, table_io_manager, column_ids, unbound_expressions, constraint_type),
|
40
|
+
allocators(allocators_ptr), owns_data(false) {
|
39
41
|
|
40
42
|
if (!Radix::IsLittleEndian()) {
|
41
43
|
throw NotImplementedException("ART indexes are not supported on big endian architectures");
|
42
44
|
}
|
43
45
|
|
44
46
|
// initialize all allocators
|
45
|
-
allocators
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
if (!allocators) {
|
48
|
+
owns_data = true;
|
49
|
+
allocators = make_shared<vector<FixedSizeAllocator>>();
|
50
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Prefix), buffer_manager.GetBufferAllocator()));
|
51
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Leaf), buffer_manager.GetBufferAllocator()));
|
52
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Node4), buffer_manager.GetBufferAllocator()));
|
53
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Node16), buffer_manager.GetBufferAllocator()));
|
54
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Node48), buffer_manager.GetBufferAllocator()));
|
55
|
+
allocators->emplace_back(FixedSizeAllocator(sizeof(Node256), buffer_manager.GetBufferAllocator()));
|
56
|
+
}
|
51
57
|
|
52
58
|
// set the root node of the tree
|
53
59
|
tree = make_uniq<Node>();
|
@@ -986,26 +992,28 @@ BlockPointer ART::Serialize(MetaBlockWriter &writer) {
|
|
986
992
|
|
987
993
|
void ART::InitializeVacuum(ARTFlags &flags) {
|
988
994
|
|
989
|
-
flags.vacuum_flags.reserve(allocators
|
990
|
-
for (auto &allocator : allocators) {
|
991
|
-
flags.vacuum_flags.push_back(allocator
|
995
|
+
flags.vacuum_flags.reserve(allocators->size());
|
996
|
+
for (auto &allocator : *allocators) {
|
997
|
+
flags.vacuum_flags.push_back(allocator.InitializeVacuum());
|
992
998
|
}
|
993
999
|
}
|
994
1000
|
|
995
1001
|
void ART::FinalizeVacuum(const ARTFlags &flags) {
|
996
1002
|
|
997
|
-
for (idx_t i = 0; i < allocators
|
1003
|
+
for (idx_t i = 0; i < allocators->size(); i++) {
|
998
1004
|
if (flags.vacuum_flags[i]) {
|
999
|
-
allocators[i]
|
1005
|
+
(*allocators)[i].FinalizeVacuum();
|
1000
1006
|
}
|
1001
1007
|
}
|
1002
1008
|
}
|
1003
1009
|
|
1004
1010
|
void ART::Vacuum(IndexLock &state) {
|
1005
1011
|
|
1012
|
+
D_ASSERT(owns_data);
|
1013
|
+
|
1006
1014
|
if (!tree->IsSet()) {
|
1007
|
-
for (auto &allocator : allocators) {
|
1008
|
-
allocator
|
1015
|
+
for (auto &allocator : *allocators) {
|
1016
|
+
allocator.Reset();
|
1009
1017
|
}
|
1010
1018
|
return;
|
1011
1019
|
}
|
@@ -1032,8 +1040,8 @@ void ART::Vacuum(IndexLock &state) {
|
|
1032
1040
|
// finalize the vacuum operation
|
1033
1041
|
FinalizeVacuum(flags);
|
1034
1042
|
|
1035
|
-
for (auto &allocator : allocators) {
|
1036
|
-
allocator
|
1043
|
+
for (auto &allocator : *allocators) {
|
1044
|
+
allocator.Verify();
|
1037
1045
|
}
|
1038
1046
|
}
|
1039
1047
|
|
@@ -1043,9 +1051,11 @@ void ART::Vacuum(IndexLock &state) {
|
|
1043
1051
|
|
1044
1052
|
void ART::InitializeMerge(ARTFlags &flags) {
|
1045
1053
|
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1054
|
+
D_ASSERT(owns_data);
|
1055
|
+
|
1056
|
+
flags.merge_buffer_counts.reserve(allocators->size());
|
1057
|
+
for (auto &allocator : *allocators) {
|
1058
|
+
flags.merge_buffer_counts.emplace_back(allocator.buffers.size());
|
1049
1059
|
}
|
1050
1060
|
}
|
1051
1061
|
|
@@ -1056,16 +1066,18 @@ bool ART::MergeIndexes(IndexLock &state, Index &other_index) {
|
|
1056
1066
|
return true;
|
1057
1067
|
}
|
1058
1068
|
|
1059
|
-
if (
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1069
|
+
if (other_art.owns_data) {
|
1070
|
+
if (tree->IsSet()) {
|
1071
|
+
// fully deserialize other_index, and traverse it to increment its buffer IDs
|
1072
|
+
ARTFlags flags;
|
1073
|
+
InitializeMerge(flags);
|
1074
|
+
other_art.tree->InitializeMerge(other_art, flags);
|
1075
|
+
}
|
1065
1076
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1077
|
+
// merge the node storage
|
1078
|
+
for (idx_t i = 0; i < allocators->size(); i++) {
|
1079
|
+
(*allocators)[i].Merge((*other_art.allocators)[i]);
|
1080
|
+
}
|
1069
1081
|
}
|
1070
1082
|
|
1071
1083
|
// merge the ARTs
|
@@ -1073,8 +1085,8 @@ bool ART::MergeIndexes(IndexLock &state, Index &other_index) {
|
|
1073
1085
|
return false;
|
1074
1086
|
}
|
1075
1087
|
|
1076
|
-
for (auto &allocator : allocators) {
|
1077
|
-
allocator
|
1088
|
+
for (auto &allocator : *allocators) {
|
1089
|
+
allocator.Verify();
|
1078
1090
|
}
|
1079
1091
|
return true;
|
1080
1092
|
}
|
@@ -42,19 +42,30 @@ void Leaf::New(ART &art, reference<Node> &node, const row_t *row_ids, idx_t coun
|
|
42
42
|
|
43
43
|
void Leaf::Free(ART &art, Node &node) {
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
Node current_node = node;
|
46
|
+
Node next_node;
|
47
|
+
while (current_node.IsSet() && !current_node.IsSerialized()) {
|
48
|
+
next_node = Leaf::Get(art, current_node).ptr;
|
49
|
+
Node::GetAllocator(art, NType::LEAF).Free(current_node);
|
50
|
+
current_node = next_node;
|
51
|
+
}
|
52
|
+
|
53
|
+
node.Reset();
|
48
54
|
}
|
49
55
|
|
50
56
|
void Leaf::InitializeMerge(ART &art, Node &node, const ARTFlags &flags) {
|
51
57
|
|
52
|
-
|
53
|
-
D_ASSERT(node.GetType() == NType::LEAF);
|
58
|
+
auto merge_buffer_count = flags.merge_buffer_counts[(uint8_t)NType::LEAF - 1];
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
Node next_node = node;
|
61
|
+
node.AddToBufferID(merge_buffer_count);
|
62
|
+
|
63
|
+
while (next_node.IsSet()) {
|
64
|
+
auto &leaf = Leaf::Get(art, next_node);
|
65
|
+
next_node = leaf.ptr;
|
66
|
+
if (leaf.ptr.IsSet()) {
|
67
|
+
leaf.ptr.AddToBufferID(merge_buffer_count);
|
68
|
+
}
|
58
69
|
}
|
59
70
|
}
|
60
71
|
|
@@ -290,7 +301,6 @@ string Leaf::VerifyAndToString(ART &art, Node &node) {
|
|
290
301
|
return "Leaf [count: 1, row ID: " + to_string(node.GetRowId()) + "]";
|
291
302
|
}
|
292
303
|
|
293
|
-
// NOTE: we could do this recursively, but the function-call overhead can become kinda crazy
|
294
304
|
string str = "";
|
295
305
|
|
296
306
|
reference<Node> node_ref(node);
|
@@ -322,46 +332,51 @@ BlockPointer Leaf::Serialize(ART &art, Node &node, MetaBlockWriter &writer) {
|
|
322
332
|
return block_pointer;
|
323
333
|
}
|
324
334
|
|
325
|
-
// recurse into the child and retrieve its block pointer
|
326
|
-
auto &leaf = Leaf::Get(art, node);
|
327
|
-
auto child_block_pointer = leaf.ptr.Serialize(art, writer);
|
328
|
-
|
329
|
-
// get pointer and write fields
|
330
335
|
auto block_pointer = writer.GetBlockPointer();
|
331
336
|
writer.Write(NType::LEAF);
|
332
|
-
|
337
|
+
idx_t total_count = Leaf::TotalCount(art, node);
|
338
|
+
writer.Write<idx_t>(total_count);
|
333
339
|
|
334
|
-
// write row IDs
|
335
|
-
|
336
|
-
|
337
|
-
|
340
|
+
// iterate all leaves and write their row IDs
|
341
|
+
reference<Node> ref_node(node);
|
342
|
+
while (ref_node.get().IsSet()) {
|
343
|
+
D_ASSERT(!ref_node.get().IsSerialized());
|
344
|
+
auto &leaf = Leaf::Get(art, ref_node);
|
338
345
|
|
339
|
-
|
340
|
-
|
341
|
-
|
346
|
+
// write row IDs
|
347
|
+
for (idx_t i = 0; i < leaf.count; i++) {
|
348
|
+
writer.Write(leaf.row_ids[i]);
|
349
|
+
}
|
350
|
+
ref_node = leaf.ptr;
|
351
|
+
}
|
342
352
|
|
343
353
|
return block_pointer;
|
344
354
|
}
|
345
355
|
|
346
356
|
void Leaf::Deserialize(ART &art, Node &node, MetaBlockReader &reader) {
|
347
357
|
|
348
|
-
|
358
|
+
auto total_count = reader.Read<idx_t>();
|
359
|
+
reference<Node> ref_node(node);
|
349
360
|
|
350
|
-
|
351
|
-
|
361
|
+
while (total_count) {
|
362
|
+
ref_node.get() = Node::GetAllocator(art, NType::LEAF).New();
|
363
|
+
ref_node.get().SetType((uint8_t)NType::LEAF);
|
352
364
|
|
353
|
-
|
354
|
-
|
355
|
-
leaf.
|
356
|
-
|
365
|
+
auto &leaf = Leaf::Get(art, ref_node);
|
366
|
+
|
367
|
+
leaf.count = MinValue((idx_t)Node::LEAF_SIZE, total_count);
|
368
|
+
for (idx_t i = 0; i < leaf.count; i++) {
|
369
|
+
leaf.row_ids[i] = reader.Read<row_t>();
|
370
|
+
}
|
357
371
|
|
358
|
-
|
359
|
-
|
372
|
+
total_count -= leaf.count;
|
373
|
+
ref_node = leaf.ptr;
|
374
|
+
leaf.ptr.Reset();
|
375
|
+
}
|
360
376
|
}
|
361
377
|
|
362
378
|
void Leaf::Vacuum(ART &art, Node &node) {
|
363
379
|
|
364
|
-
// NOTE: we could do this recursively, but the function-call overhead can become kinda crazy
|
365
380
|
auto &allocator = Node::GetAllocator(art, NType::LEAF);
|
366
381
|
|
367
382
|
reference<Node> node_ref(node);
|
@@ -373,7 +388,6 @@ void Leaf::Vacuum(ART &art, Node &node) {
|
|
373
388
|
auto &leaf = Leaf::Get(art, node_ref);
|
374
389
|
node_ref = leaf.ptr;
|
375
390
|
}
|
376
|
-
return;
|
377
391
|
}
|
378
392
|
|
379
393
|
void Leaf::MoveInlinedToLeaf(ART &art, Node &node) {
|
@@ -61,7 +61,6 @@ void Node::New(ART &art, Node &node, const NType type) {
|
|
61
61
|
|
62
62
|
void Node::Free(ART &art, Node &node) {
|
63
63
|
|
64
|
-
// recursively free all nodes that are in-memory, and skip serialized and empty nodes
|
65
64
|
if (!node.IsSet()) {
|
66
65
|
return;
|
67
66
|
}
|
@@ -72,11 +71,11 @@ void Node::Free(ART &art, Node &node) {
|
|
72
71
|
auto type = node.GetType();
|
73
72
|
switch (type) {
|
74
73
|
case NType::PREFIX:
|
75
|
-
|
76
|
-
|
74
|
+
// iterative
|
75
|
+
return Prefix::Free(art, node);
|
77
76
|
case NType::LEAF:
|
78
|
-
|
79
|
-
|
77
|
+
// iterative
|
78
|
+
return Leaf::Free(art, node);
|
80
79
|
case NType::NODE_4:
|
81
80
|
Node4::Free(art, node);
|
82
81
|
break;
|
@@ -90,8 +89,7 @@ void Node::Free(ART &art, Node &node) {
|
|
90
89
|
Node256::Free(art, node);
|
91
90
|
break;
|
92
91
|
case NType::LEAF_INLINED:
|
93
|
-
node.Reset();
|
94
|
-
return;
|
92
|
+
return node.Reset();
|
95
93
|
}
|
96
94
|
|
97
95
|
Node::GetAllocator(art, type).Free(node);
|
@@ -236,8 +234,10 @@ BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
|
|
236
234
|
|
237
235
|
switch (GetType()) {
|
238
236
|
case NType::PREFIX:
|
239
|
-
|
237
|
+
// iterative
|
238
|
+
return Prefix::Serialize(art, *this, writer);
|
240
239
|
case NType::LEAF:
|
240
|
+
// iterative
|
241
241
|
return Leaf::Serialize(art, *this, writer);
|
242
242
|
case NType::NODE_4:
|
243
243
|
return Node4::Get(art, *this).Serialize(art, writer);
|
@@ -263,19 +263,23 @@ void Node::Deserialize(ART &art) {
|
|
263
263
|
SetType(reader.Read<uint8_t>());
|
264
264
|
|
265
265
|
auto decoded_type = GetType();
|
266
|
+
|
267
|
+
// iterative functions
|
268
|
+
if (decoded_type == NType::PREFIX) {
|
269
|
+
return Prefix::Deserialize(art, *this, reader);
|
270
|
+
}
|
266
271
|
if (decoded_type == NType::LEAF_INLINED) {
|
267
|
-
SetRowId(reader.Read<row_t>());
|
268
|
-
|
272
|
+
return SetRowId(reader.Read<row_t>());
|
273
|
+
}
|
274
|
+
if (decoded_type == NType::LEAF) {
|
275
|
+
return Leaf::Deserialize(art, *this, reader);
|
269
276
|
}
|
270
277
|
|
271
278
|
*this = Node::GetAllocator(art, decoded_type).New();
|
272
279
|
SetType((uint8_t)decoded_type);
|
273
280
|
|
281
|
+
// recursive functions
|
274
282
|
switch (decoded_type) {
|
275
|
-
case NType::PREFIX:
|
276
|
-
return Prefix::Get(art, *this).Deserialize(reader);
|
277
|
-
case NType::LEAF:
|
278
|
-
return Leaf::Deserialize(art, *this, reader);
|
279
283
|
case NType::NODE_4:
|
280
284
|
return Node4::Get(art, *this).Deserialize(reader);
|
281
285
|
case NType::NODE_16:
|
@@ -363,7 +367,7 @@ NType Node::GetARTNodeTypeByCount(const idx_t count) {
|
|
363
367
|
}
|
364
368
|
|
365
369
|
FixedSizeAllocator &Node::GetAllocator(const ART &art, NType type) {
|
366
|
-
return *art.allocators[(uint8_t)type - 1];
|
370
|
+
return (*art.allocators)[(uint8_t)type - 1];
|
367
371
|
}
|
368
372
|
|
369
373
|
//===--------------------------------------------------------------------===//
|
@@ -377,11 +381,11 @@ void Node::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
377
381
|
|
378
382
|
switch (GetType()) {
|
379
383
|
case NType::PREFIX:
|
380
|
-
|
381
|
-
|
384
|
+
// iterative
|
385
|
+
return Prefix::InitializeMerge(art, *this, flags);
|
382
386
|
case NType::LEAF:
|
383
|
-
|
384
|
-
|
387
|
+
// iterative
|
388
|
+
return Leaf::InitializeMerge(art, *this, flags);
|
385
389
|
case NType::NODE_4:
|
386
390
|
Node4::Get(art, *this).InitializeMerge(art, flags);
|
387
391
|
break;
|
@@ -398,8 +402,7 @@ void Node::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
398
402
|
return;
|
399
403
|
}
|
400
404
|
|
401
|
-
|
402
|
-
data += flags.merge_buffer_counts[(uint8_t)GetType() - 1];
|
405
|
+
AddToBufferID(flags.merge_buffer_counts[(uint8_t)GetType() - 1]);
|
403
406
|
}
|
404
407
|
|
405
408
|
bool Node::Merge(ART &art, Node &other) {
|
@@ -572,11 +575,16 @@ void Node::Vacuum(ART &art, const ARTFlags &flags) {
|
|
572
575
|
}
|
573
576
|
|
574
577
|
auto node_type = GetType();
|
578
|
+
|
579
|
+
// iterative functions
|
580
|
+
if (node_type == NType::PREFIX) {
|
581
|
+
return Prefix::Vacuum(art, *this, flags);
|
582
|
+
}
|
575
583
|
if (node_type == NType::LEAF_INLINED) {
|
576
584
|
return;
|
577
585
|
}
|
578
586
|
if (node_type == NType::LEAF) {
|
579
|
-
if (flags.vacuum_flags[(uint8_t)
|
587
|
+
if (flags.vacuum_flags[(uint8_t)node_type - 1]) {
|
580
588
|
Leaf::Vacuum(art, *this);
|
581
589
|
}
|
582
590
|
return;
|
@@ -589,9 +597,8 @@ void Node::Vacuum(ART &art, const ARTFlags &flags) {
|
|
589
597
|
SetType((uint8_t)node_type);
|
590
598
|
}
|
591
599
|
|
600
|
+
// recursive functions
|
592
601
|
switch (node_type) {
|
593
|
-
case NType::PREFIX:
|
594
|
-
return Prefix::Get(art, *this).Vacuum(art, flags);
|
595
602
|
case NType::NODE_4:
|
596
603
|
return Node4::Get(art, *this).Vacuum(art, flags);
|
597
604
|
case NType::NODE_16:
|