duckdb 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb/extension/core_functions/scalar/generic/current_setting.cpp +1 -4
- package/src/duckdb/extension/icu/icu-strptime.cpp +2 -1
- package/src/duckdb/extension/json/include/json_common.hpp +2 -4
- package/src/duckdb/extension/json/json_functions.cpp +5 -1
- package/src/duckdb/extension/parquet/column_writer.cpp +31 -21
- package/src/duckdb/extension/parquet/geo_parquet.cpp +21 -6
- package/src/duckdb/extension/parquet/include/column_writer.hpp +2 -2
- package/src/duckdb/extension/parquet/include/geo_parquet.hpp +28 -1
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +7 -2
- package/src/duckdb/extension/parquet/include/reader/string_column_reader.hpp +13 -0
- package/src/duckdb/extension/parquet/include/writer/array_column_writer.hpp +4 -0
- package/src/duckdb/extension/parquet/parquet_extension.cpp +56 -1
- package/src/duckdb/extension/parquet/parquet_reader.cpp +4 -1
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +5 -7
- package/src/duckdb/extension/parquet/parquet_writer.cpp +15 -8
- package/src/duckdb/extension/parquet/reader/string_column_reader.cpp +17 -4
- package/src/duckdb/extension/parquet/writer/array_column_writer.cpp +22 -28
- package/src/duckdb/extension/parquet/writer/primitive_column_writer.cpp +17 -5
- package/src/duckdb/extension/parquet/writer/struct_column_writer.cpp +3 -2
- package/src/duckdb/src/catalog/catalog_search_path.cpp +2 -2
- package/src/duckdb/src/catalog/catalog_set.cpp +1 -2
- package/src/duckdb/src/common/enum_util.cpp +20 -0
- package/src/duckdb/src/common/file_system.cpp +0 -30
- package/src/duckdb/src/common/sorting/sort.cpp +25 -6
- package/src/duckdb/src/common/sorting/sorted_run_merger.cpp +1 -0
- package/src/duckdb/src/common/string_util.cpp +24 -0
- package/src/duckdb/src/common/virtual_file_system.cpp +59 -10
- package/src/duckdb/src/execution/index/art/art_merger.cpp +0 -3
- package/src/duckdb/src/execution/index/art/prefix.cpp +4 -0
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +1 -1
- package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +2 -2
- package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +1 -1
- package/src/duckdb/src/execution/physical_plan/plan_asof_join.cpp +3 -3
- package/src/duckdb/src/function/table/system/duckdb_connection_count.cpp +45 -0
- package/src/duckdb/src/function/table/system/duckdb_settings.cpp +11 -1
- package/src/duckdb/src/function/table/system_functions.cpp +1 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +3 -3
- package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/string_util.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp +4 -1
- package/src/duckdb/src/include/duckdb/function/scalar/variant_functions.hpp +1 -1
- package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/logging/log_storage.hpp +6 -6
- package/src/duckdb/src/include/duckdb/logging/log_type.hpp +26 -3
- package/src/duckdb/src/include/duckdb/main/attached_database.hpp +4 -0
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/connection.hpp +0 -1
- package/src/duckdb/src/include/duckdb/main/connection_manager.hpp +0 -1
- package/src/duckdb/src/include/duckdb/main/database_file_path_manager.hpp +12 -1
- package/src/duckdb/src/include/duckdb/main/database_manager.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/relation/create_table_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/create_view_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/delete_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/explain_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/insert_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/query_relation.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/relation/update_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/write_csv_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation/write_parquet_relation.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/relation.hpp +2 -1
- package/src/duckdb/src/include/duckdb/main/secret/secret.hpp +3 -1
- package/src/duckdb/src/include/duckdb/optimizer/filter_pushdown.hpp +3 -2
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +62 -3
- package/src/duckdb/src/include/duckdb/planner/expression_binder/lateral_binder.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_cte.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_dependent_join.hpp +3 -3
- package/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/subquery/has_correlated_expressions.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/subquery/rewrite_cte_scan.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/tableref/bound_joinref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/compression/alp/alp_analyze.hpp +6 -1
- package/src/duckdb/src/include/duckdb/storage/compression/alprd/alprd_analyze.hpp +5 -1
- package/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp +9 -7
- package/src/duckdb/src/include/duckdb/storage/statistics/string_stats.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/table/array_column_data.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +6 -6
- package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +5 -3
- package/src/duckdb/src/include/duckdb/storage/table/row_id_column_data.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/standard_column_data.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/struct_column_data.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -2
- package/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp +2 -1
- package/src/duckdb/src/include/duckdb/transaction/update_info.hpp +4 -1
- package/src/duckdb/src/include/duckdb/transaction/wal_write_state.hpp +1 -1
- package/src/duckdb/src/logging/log_types.cpp +63 -0
- package/src/duckdb/src/main/attached_database.cpp +16 -3
- package/src/duckdb/src/main/client_context.cpp +27 -19
- package/src/duckdb/src/main/connection.cpp +2 -5
- package/src/duckdb/src/main/database_file_path_manager.cpp +23 -6
- package/src/duckdb/src/main/database_manager.cpp +18 -3
- package/src/duckdb/src/main/http/http_util.cpp +3 -1
- package/src/duckdb/src/main/relation/create_table_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/create_view_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/delete_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/explain_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/insert_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/query_relation.cpp +4 -0
- package/src/duckdb/src/main/relation/update_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/write_csv_relation.cpp +8 -0
- package/src/duckdb/src/main/relation/write_parquet_relation.cpp +8 -0
- package/src/duckdb/src/main/relation.cpp +2 -2
- package/src/duckdb/src/optimizer/filter_combiner.cpp +7 -0
- package/src/duckdb/src/optimizer/filter_pushdown.cpp +9 -3
- package/src/duckdb/src/optimizer/pushdown/pushdown_get.cpp +4 -1
- package/src/duckdb/src/optimizer/rule/comparison_simplification.cpp +3 -7
- package/src/duckdb/src/parser/statement/relation_statement.cpp +1 -4
- package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +2 -0
- package/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp +8 -6
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -5
- package/src/duckdb/src/planner/binder/statement/bind_merge_into.cpp +10 -2
- package/src/duckdb/src/planner/binder/statement/bind_pragma.cpp +20 -3
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +8 -3
- package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +9 -2
- package/src/duckdb/src/planner/binder.cpp +2 -2
- package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +9 -13
- package/src/duckdb/src/planner/expression_binder/table_function_binder.cpp +4 -0
- package/src/duckdb/src/planner/expression_binder.cpp +3 -1
- package/src/duckdb/src/planner/operator/logical_dependent_join.cpp +2 -2
- package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +12 -14
- package/src/duckdb/src/planner/subquery/has_correlated_expressions.cpp +1 -1
- package/src/duckdb/src/planner/subquery/rewrite_cte_scan.cpp +2 -2
- package/src/duckdb/src/storage/compression/bitpacking.cpp +1 -2
- package/src/duckdb/src/storage/data_table.cpp +2 -2
- package/src/duckdb/src/storage/local_storage.cpp +1 -1
- package/src/duckdb/src/storage/metadata/metadata_manager.cpp +67 -25
- package/src/duckdb/src/storage/statistics/string_stats.cpp +8 -0
- package/src/duckdb/src/storage/table/array_column_data.cpp +6 -5
- package/src/duckdb/src/storage/table/column_data.cpp +23 -9
- package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +15 -1
- package/src/duckdb/src/storage/table/list_column_data.cpp +5 -4
- package/src/duckdb/src/storage/table/row_group.cpp +8 -8
- package/src/duckdb/src/storage/table/row_group_collection.cpp +12 -8
- package/src/duckdb/src/storage/table/row_id_column_data.cpp +5 -4
- package/src/duckdb/src/storage/table/standard_column_data.cpp +9 -8
- package/src/duckdb/src/storage/table/struct_column_data.cpp +10 -9
- package/src/duckdb/src/storage/table/update_segment.cpp +12 -10
- package/src/duckdb/src/transaction/commit_state.cpp +18 -0
- package/src/duckdb/src/transaction/duck_transaction.cpp +2 -10
- package/src/duckdb/src/transaction/wal_write_state.cpp +5 -5
- package/src/duckdb/third_party/httplib/httplib.hpp +6 -1
- package/src/duckdb/ub_src_function_table_system.cpp +2 -0
@@ -1542,7 +1542,7 @@ void DataTable::Update(TableUpdateState &state, ClientContext &context, Vector &
|
|
1542
1542
|
row_ids_slice.Slice(row_ids, sel_global_update, n_global_update);
|
1543
1543
|
row_ids_slice.Flatten(n_global_update);
|
1544
1544
|
|
1545
|
-
row_groups->Update(transaction, FlatVector::GetData<row_t>(row_ids_slice), column_ids, updates_slice);
|
1545
|
+
row_groups->Update(transaction, *this, FlatVector::GetData<row_t>(row_ids_slice), column_ids, updates_slice);
|
1546
1546
|
}
|
1547
1547
|
}
|
1548
1548
|
|
@@ -1566,7 +1566,7 @@ void DataTable::UpdateColumn(TableCatalogEntry &table, ClientContext &context, V
|
|
1566
1566
|
|
1567
1567
|
updates.Flatten();
|
1568
1568
|
row_ids.Flatten(updates.size());
|
1569
|
-
row_groups->UpdateColumn(transaction, row_ids, column_path, updates);
|
1569
|
+
row_groups->UpdateColumn(transaction, *this, row_ids, column_path, updates);
|
1570
1570
|
}
|
1571
1571
|
|
1572
1572
|
//===--------------------------------------------------------------------===//
|
@@ -563,7 +563,7 @@ void LocalStorage::Update(DataTable &table, Vector &row_ids, const vector<Physic
|
|
563
563
|
D_ASSERT(storage);
|
564
564
|
|
565
565
|
auto ids = FlatVector::GetData<row_t>(row_ids);
|
566
|
-
storage->row_groups->Update(TransactionData(0, 0), ids, column_ids, updates);
|
566
|
+
storage->row_groups->Update(TransactionData(0, 0), table, ids, column_ids, updates);
|
567
567
|
}
|
568
568
|
|
569
569
|
void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage, optional_ptr<StorageCommitState> commit_state) {
|
@@ -54,6 +54,8 @@ MetadataManager::~MetadataManager() {
|
|
54
54
|
MetadataHandle MetadataManager::AllocateHandle() {
|
55
55
|
// check if there is any free space left in an existing block
|
56
56
|
// if not allocate a new block
|
57
|
+
MetadataPointer pointer;
|
58
|
+
unique_lock<mutex> guard(block_lock);
|
57
59
|
block_id_t free_block = INVALID_BLOCK;
|
58
60
|
for (auto &kv : blocks) {
|
59
61
|
auto &block = kv.second;
|
@@ -63,13 +65,16 @@ MetadataHandle MetadataManager::AllocateHandle() {
|
|
63
65
|
break;
|
64
66
|
}
|
65
67
|
}
|
68
|
+
guard.unlock();
|
66
69
|
if (free_block == INVALID_BLOCK || free_block > PeekNextBlockId()) {
|
67
|
-
free_block = AllocateNewBlock();
|
70
|
+
free_block = AllocateNewBlock(guard);
|
71
|
+
} else {
|
72
|
+
guard.lock();
|
68
73
|
}
|
74
|
+
D_ASSERT(guard.owns_lock());
|
69
75
|
D_ASSERT(free_block != INVALID_BLOCK);
|
70
76
|
|
71
77
|
// select the first free metadata block we can find
|
72
|
-
MetadataPointer pointer;
|
73
78
|
pointer.block_index = UnsafeNumericCast<idx_t>(free_block);
|
74
79
|
auto &block = blocks[free_block];
|
75
80
|
// the block is now dirty
|
@@ -77,7 +82,7 @@ MetadataHandle MetadataManager::AllocateHandle() {
|
|
77
82
|
if (block.block->BlockId() < MAXIMUM_BLOCK) {
|
78
83
|
// this block is a disk-backed block, yet we are planning to write to it
|
79
84
|
// we need to convert it into a transient block before we can write to it
|
80
|
-
ConvertToTransient(block);
|
85
|
+
ConvertToTransient(guard, block);
|
81
86
|
D_ASSERT(block.block->BlockId() >= MAXIMUM_BLOCK);
|
82
87
|
}
|
83
88
|
D_ASSERT(!block.free_blocks.empty());
|
@@ -85,6 +90,7 @@ MetadataHandle MetadataManager::AllocateHandle() {
|
|
85
90
|
// mark the block as used
|
86
91
|
block.free_blocks.pop_back();
|
87
92
|
D_ASSERT(pointer.index < METADATA_BLOCK_COUNT);
|
93
|
+
guard.unlock();
|
88
94
|
// pin the block
|
89
95
|
return Pin(pointer);
|
90
96
|
}
|
@@ -95,25 +101,34 @@ MetadataHandle MetadataManager::Pin(const MetadataPointer &pointer) {
|
|
95
101
|
|
96
102
|
MetadataHandle MetadataManager::Pin(QueryContext context, const MetadataPointer &pointer) {
|
97
103
|
D_ASSERT(pointer.index < METADATA_BLOCK_COUNT);
|
98
|
-
|
104
|
+
shared_ptr<BlockHandle> block_handle;
|
105
|
+
{
|
106
|
+
lock_guard<mutex> guard(block_lock);
|
107
|
+
auto &block = blocks[UnsafeNumericCast<int64_t>(pointer.block_index)];
|
99
108
|
#ifdef DEBUG
|
100
|
-
|
101
|
-
|
102
|
-
|
109
|
+
for (auto &free_block : block.free_blocks) {
|
110
|
+
if (free_block == pointer.index) {
|
111
|
+
throw InternalException("Pinning block %d.%d but it is marked as a free block", block.block_id,
|
112
|
+
free_block);
|
113
|
+
}
|
103
114
|
}
|
104
|
-
}
|
105
115
|
#endif
|
116
|
+
block_handle = block.block;
|
117
|
+
}
|
106
118
|
|
107
119
|
MetadataHandle handle;
|
108
120
|
handle.pointer.block_index = pointer.block_index;
|
109
121
|
handle.pointer.index = pointer.index;
|
110
|
-
handle.handle = buffer_manager.Pin(
|
122
|
+
handle.handle = buffer_manager.Pin(block_handle);
|
111
123
|
return handle;
|
112
124
|
}
|
113
125
|
|
114
|
-
void MetadataManager::ConvertToTransient(MetadataBlock &metadata_block) {
|
126
|
+
void MetadataManager::ConvertToTransient(unique_lock<mutex> &block_lock, MetadataBlock &metadata_block) {
|
127
|
+
D_ASSERT(block_lock.owns_lock());
|
128
|
+
auto old_block = metadata_block.block;
|
129
|
+
block_lock.unlock();
|
115
130
|
// pin the old block
|
116
|
-
auto old_buffer = buffer_manager.Pin(
|
131
|
+
auto old_buffer = buffer_manager.Pin(old_block);
|
117
132
|
|
118
133
|
// allocate a new transient block to replace it
|
119
134
|
auto new_buffer = buffer_manager.Allocate(MemoryTag::METADATA, &block_manager, false);
|
@@ -121,14 +136,17 @@ void MetadataManager::ConvertToTransient(MetadataBlock &metadata_block) {
|
|
121
136
|
|
122
137
|
// copy the data to the transient block
|
123
138
|
memcpy(new_buffer.Ptr(), old_buffer.Ptr(), block_manager.GetBlockSize());
|
124
|
-
metadata_block.block = std::move(new_block);
|
125
|
-
metadata_block.dirty = true;
|
126
139
|
|
127
140
|
// unregister the old block
|
128
141
|
block_manager.UnregisterBlock(metadata_block.block_id);
|
142
|
+
|
143
|
+
block_lock.lock();
|
144
|
+
metadata_block.block = std::move(new_block);
|
145
|
+
metadata_block.dirty = true;
|
129
146
|
}
|
130
147
|
|
131
|
-
block_id_t MetadataManager::AllocateNewBlock() {
|
148
|
+
block_id_t MetadataManager::AllocateNewBlock(unique_lock<mutex> &block_lock) {
|
149
|
+
D_ASSERT(!block_lock.owns_lock());
|
132
150
|
auto new_block_id = GetNextBlockId();
|
133
151
|
|
134
152
|
MetadataBlock new_block;
|
@@ -141,11 +159,14 @@ block_id_t MetadataManager::AllocateNewBlock() {
|
|
141
159
|
new_block.dirty = true;
|
142
160
|
// zero-initialize the handle
|
143
161
|
memset(handle.Ptr(), 0, block_manager.GetBlockSize());
|
144
|
-
|
162
|
+
|
163
|
+
block_lock.lock();
|
164
|
+
AddBlock(block_lock, std::move(new_block));
|
145
165
|
return new_block_id;
|
146
166
|
}
|
147
167
|
|
148
|
-
void MetadataManager::AddBlock(MetadataBlock new_block, bool if_exists) {
|
168
|
+
void MetadataManager::AddBlock(unique_lock<mutex> &block_lock, MetadataBlock new_block, bool if_exists) {
|
169
|
+
D_ASSERT(block_lock.owns_lock());
|
149
170
|
if (blocks.find(new_block.block_id) != blocks.end()) {
|
150
171
|
if (if_exists) {
|
151
172
|
return;
|
@@ -155,15 +176,17 @@ void MetadataManager::AddBlock(MetadataBlock new_block, bool if_exists) {
|
|
155
176
|
blocks[new_block.block_id] = std::move(new_block);
|
156
177
|
}
|
157
178
|
|
158
|
-
void MetadataManager::AddAndRegisterBlock(MetadataBlock block) {
|
179
|
+
void MetadataManager::AddAndRegisterBlock(unique_lock<mutex> &block_lock, MetadataBlock block) {
|
159
180
|
if (block.block) {
|
160
181
|
throw InternalException("Calling AddAndRegisterBlock on block that already exists");
|
161
182
|
}
|
162
183
|
if (block.block_id >= MAXIMUM_BLOCK) {
|
163
184
|
throw InternalException("AddAndRegisterBlock called with a transient block id");
|
164
185
|
}
|
186
|
+
block_lock.unlock();
|
165
187
|
block.block = block_manager.RegisterBlock(block.block_id);
|
166
|
-
|
188
|
+
block_lock.lock();
|
189
|
+
AddBlock(block_lock, std::move(block), true);
|
167
190
|
}
|
168
191
|
|
169
192
|
MetaBlockPointer MetadataManager::GetDiskPointer(const MetadataPointer &pointer, uint32_t offset) {
|
@@ -181,8 +204,14 @@ uint32_t MetaBlockPointer::GetBlockIndex() const {
|
|
181
204
|
}
|
182
205
|
|
183
206
|
MetadataPointer MetadataManager::FromDiskPointer(MetaBlockPointer pointer) {
|
207
|
+
unique_lock<mutex> guard(block_lock);
|
208
|
+
return FromDiskPointerInternal(guard, pointer);
|
209
|
+
}
|
210
|
+
|
211
|
+
MetadataPointer MetadataManager::FromDiskPointerInternal(unique_lock<mutex> &block_lock, MetaBlockPointer pointer) {
|
184
212
|
auto block_id = pointer.GetBlockId();
|
185
213
|
auto index = pointer.GetBlockIndex();
|
214
|
+
|
186
215
|
auto entry = blocks.find(block_id);
|
187
216
|
if (entry == blocks.end()) { // LCOV_EXCL_START
|
188
217
|
throw InternalException("Failed to load metadata pointer (id %llu, idx %llu, ptr %llu)\n", block_id, index,
|
@@ -195,11 +224,13 @@ MetadataPointer MetadataManager::FromDiskPointer(MetaBlockPointer pointer) {
|
|
195
224
|
}
|
196
225
|
|
197
226
|
MetadataPointer MetadataManager::RegisterDiskPointer(MetaBlockPointer pointer) {
|
227
|
+
unique_lock<mutex> guard(block_lock);
|
228
|
+
|
198
229
|
auto block_id = pointer.GetBlockId();
|
199
230
|
MetadataBlock block;
|
200
231
|
block.block_id = block_id;
|
201
|
-
AddAndRegisterBlock(std::move(block));
|
202
|
-
return
|
232
|
+
AddAndRegisterBlock(guard, std::move(block));
|
233
|
+
return FromDiskPointerInternal(guard, pointer);
|
203
234
|
}
|
204
235
|
|
205
236
|
BlockPointer MetadataManager::ToBlockPointer(MetaBlockPointer meta_pointer, const idx_t metadata_block_size) {
|
@@ -232,6 +263,7 @@ void MetadataManager::Flush() {
|
|
232
263
|
// Write the blocks of the metadata manager to disk.
|
233
264
|
const idx_t total_metadata_size = GetMetadataBlockSize() * METADATA_BLOCK_COUNT;
|
234
265
|
|
266
|
+
unique_lock<mutex> guard(block_lock, std::defer_lock);
|
235
267
|
for (auto &kv : blocks) {
|
236
268
|
auto &block = kv.second;
|
237
269
|
if (!block.dirty) {
|
@@ -245,9 +277,13 @@ void MetadataManager::Flush() {
|
|
245
277
|
memset(handle.Ptr() + total_metadata_size, 0, block_manager.GetBlockSize() - total_metadata_size);
|
246
278
|
D_ASSERT(kv.first == block.block_id);
|
247
279
|
if (block.block->BlockId() >= MAXIMUM_BLOCK) {
|
280
|
+
auto new_block =
|
281
|
+
block_manager.ConvertToPersistent(QueryContext(), kv.first, block.block, std::move(handle));
|
282
|
+
|
248
283
|
// Convert the temporary block to a persistent block.
|
249
|
-
|
250
|
-
|
284
|
+
guard.lock();
|
285
|
+
block.block = std::move(new_block);
|
286
|
+
guard.unlock();
|
251
287
|
} else {
|
252
288
|
// Already a persistent block, so we only need to write it.
|
253
289
|
D_ASSERT(block.block->BlockId() == block.block_id);
|
@@ -269,10 +305,12 @@ void MetadataManager::Read(ReadStream &source) {
|
|
269
305
|
auto block_count = source.Read<uint64_t>();
|
270
306
|
for (idx_t i = 0; i < block_count; i++) {
|
271
307
|
auto block = MetadataBlock::Read(source);
|
308
|
+
|
309
|
+
unique_lock<mutex> guard(block_lock);
|
272
310
|
auto entry = blocks.find(block.block_id);
|
273
311
|
if (entry == blocks.end()) {
|
274
312
|
// block does not exist yet
|
275
|
-
AddAndRegisterBlock(std::move(block));
|
313
|
+
AddAndRegisterBlock(guard, std::move(block));
|
276
314
|
} else {
|
277
315
|
// block was already created - only copy over the free list
|
278
316
|
entry->second.free_blocks = std::move(block.free_blocks);
|
@@ -349,6 +387,7 @@ void MetadataManager::MarkBlocksAsModified() {
|
|
349
387
|
}
|
350
388
|
|
351
389
|
modified_blocks.clear();
|
390
|
+
|
352
391
|
for (auto &kv : blocks) {
|
353
392
|
auto &block = kv.second;
|
354
393
|
idx_t free_list = block.FreeBlocksToInteger();
|
@@ -361,6 +400,7 @@ void MetadataManager::ClearModifiedBlocks(const vector<MetaBlockPointer> &pointe
|
|
361
400
|
if (pointers.empty()) {
|
362
401
|
return;
|
363
402
|
}
|
403
|
+
unique_lock<mutex> guard(block_lock);
|
364
404
|
for (auto &pointer : pointers) {
|
365
405
|
auto block_id = pointer.GetBlockId();
|
366
406
|
auto block_index = pointer.GetBlockIndex();
|
@@ -376,6 +416,7 @@ void MetadataManager::ClearModifiedBlocks(const vector<MetaBlockPointer> &pointe
|
|
376
416
|
|
377
417
|
vector<MetadataBlockInfo> MetadataManager::GetMetadataInfo() const {
|
378
418
|
vector<MetadataBlockInfo> result;
|
419
|
+
unique_lock<mutex> guard(block_lock);
|
379
420
|
for (auto &block : blocks) {
|
380
421
|
MetadataBlockInfo block_info;
|
381
422
|
block_info.block_id = block.second.block_id;
|
@@ -393,17 +434,18 @@ vector<MetadataBlockInfo> MetadataManager::GetMetadataInfo() const {
|
|
393
434
|
|
394
435
|
vector<shared_ptr<BlockHandle>> MetadataManager::GetBlocks() const {
|
395
436
|
vector<shared_ptr<BlockHandle>> result;
|
437
|
+
unique_lock<mutex> guard(block_lock);
|
396
438
|
for (auto &entry : blocks) {
|
397
439
|
result.push_back(entry.second.block);
|
398
440
|
}
|
399
441
|
return result;
|
400
442
|
}
|
401
443
|
|
402
|
-
block_id_t MetadataManager::PeekNextBlockId() {
|
444
|
+
block_id_t MetadataManager::PeekNextBlockId() const {
|
403
445
|
return block_manager.PeekFreeBlockId();
|
404
446
|
}
|
405
447
|
|
406
|
-
block_id_t MetadataManager::GetNextBlockId() {
|
448
|
+
block_id_t MetadataManager::GetNextBlockId() const {
|
407
449
|
return block_manager.GetFreeBlockId();
|
408
450
|
}
|
409
451
|
|
@@ -170,6 +170,14 @@ void StringStats::Update(BaseStatistics &stats, const string_t &value) {
|
|
170
170
|
}
|
171
171
|
}
|
172
172
|
|
173
|
+
void StringStats::SetMin(BaseStatistics &stats, const string_t &value) {
|
174
|
+
ConstructValue(const_data_ptr_cast(value.GetData()), value.GetSize(), GetDataUnsafe(stats).min);
|
175
|
+
}
|
176
|
+
|
177
|
+
void StringStats::SetMax(BaseStatistics &stats, const string_t &value) {
|
178
|
+
ConstructValue(const_data_ptr_cast(value.GetData()), value.GetSize(), GetDataUnsafe(stats).max);
|
179
|
+
}
|
180
|
+
|
173
181
|
void StringStats::Merge(BaseStatistics &stats, const BaseStatistics &other) {
|
174
182
|
if (other.GetType().id() == LogicalTypeId::VALIDITY) {
|
175
183
|
return;
|
@@ -97,7 +97,7 @@ idx_t ArrayColumnData::ScanCount(ColumnScanState &state, Vector &result, idx_t c
|
|
97
97
|
|
98
98
|
void ArrayColumnData::Select(TransactionData transaction, idx_t vector_index, ColumnScanState &state, Vector &result,
|
99
99
|
SelectionVector &sel, idx_t sel_count) {
|
100
|
-
bool is_supported = !child_column->type.IsNested();
|
100
|
+
bool is_supported = !child_column->type.IsNested() && child_column->type.InternalType() != PhysicalType::VARCHAR;
|
101
101
|
if (!is_supported) {
|
102
102
|
ColumnData::Select(transaction, vector_index, state, result, sel, sel_count);
|
103
103
|
return;
|
@@ -224,13 +224,14 @@ idx_t ArrayColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &resul
|
|
224
224
|
throw NotImplementedException("Array Fetch");
|
225
225
|
}
|
226
226
|
|
227
|
-
void ArrayColumnData::Update(TransactionData transaction,
|
228
|
-
idx_t update_count) {
|
227
|
+
void ArrayColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
228
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count) {
|
229
229
|
throw NotImplementedException("Array Update is not supported.");
|
230
230
|
}
|
231
231
|
|
232
|
-
void ArrayColumnData::UpdateColumn(TransactionData transaction,
|
233
|
-
Vector &update_vector, row_t *row_ids,
|
232
|
+
void ArrayColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table,
|
233
|
+
const vector<column_t> &column_path, Vector &update_vector, row_t *row_ids,
|
234
|
+
idx_t update_count, idx_t depth) {
|
234
235
|
throw NotImplementedException("Array Update Column is not supported");
|
235
236
|
}
|
236
237
|
|
@@ -293,13 +293,13 @@ void ColumnData::FetchUpdateRow(TransactionData transaction, row_t row_id, Vecto
|
|
293
293
|
updates->FetchRow(transaction, NumericCast<idx_t>(row_id), result, result_idx);
|
294
294
|
}
|
295
295
|
|
296
|
-
void ColumnData::UpdateInternal(TransactionData transaction,
|
297
|
-
idx_t update_count, Vector &base_vector) {
|
296
|
+
void ColumnData::UpdateInternal(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
297
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count, Vector &base_vector) {
|
298
298
|
lock_guard<mutex> update_guard(update_lock);
|
299
299
|
if (!updates) {
|
300
300
|
updates = make_uniq<UpdateSegment>(*this);
|
301
301
|
}
|
302
|
-
updates->Update(transaction, column_index, update_vector, row_ids, update_count, base_vector);
|
302
|
+
updates->Update(transaction, data_table, column_index, update_vector, row_ids, update_count, base_vector);
|
303
303
|
}
|
304
304
|
|
305
305
|
idx_t ColumnData::ScanVector(TransactionData transaction, idx_t vector_index, ColumnScanState &state, Vector &result,
|
@@ -578,20 +578,20 @@ idx_t ColumnData::FetchUpdateData(ColumnScanState &state, row_t *row_ids, Vector
|
|
578
578
|
return fetch_count;
|
579
579
|
}
|
580
580
|
|
581
|
-
void ColumnData::Update(TransactionData transaction, idx_t column_index, Vector &update_vector,
|
582
|
-
idx_t update_count) {
|
581
|
+
void ColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index, Vector &update_vector,
|
582
|
+
row_t *row_ids, idx_t update_count) {
|
583
583
|
Vector base_vector(type);
|
584
584
|
ColumnScanState state;
|
585
585
|
FetchUpdateData(state, row_ids, base_vector);
|
586
586
|
|
587
|
-
UpdateInternal(transaction, column_index, update_vector, row_ids, update_count, base_vector);
|
587
|
+
UpdateInternal(transaction, data_table, column_index, update_vector, row_ids, update_count, base_vector);
|
588
588
|
}
|
589
589
|
|
590
|
-
void ColumnData::UpdateColumn(TransactionData transaction, const vector<column_t> &column_path,
|
591
|
-
row_t *row_ids, idx_t update_count, idx_t depth) {
|
590
|
+
void ColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table, const vector<column_t> &column_path,
|
591
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) {
|
592
592
|
// this method should only be called at the end of the path in the base column case
|
593
593
|
D_ASSERT(depth >= column_path.size());
|
594
|
-
ColumnData::Update(transaction, column_path[0], update_vector, row_ids, update_count);
|
594
|
+
ColumnData::Update(transaction, data_table, column_path[0], update_vector, row_ids, update_count);
|
595
595
|
}
|
596
596
|
|
597
597
|
void ColumnData::AppendTransientSegment(SegmentLock &l, idx_t start_row) {
|
@@ -873,6 +873,17 @@ PersistentColumnData ColumnData::Serialize() {
|
|
873
873
|
return result;
|
874
874
|
}
|
875
875
|
|
876
|
+
void RealignColumnData(PersistentColumnData &column_data, idx_t new_start) {
|
877
|
+
idx_t current_start = new_start;
|
878
|
+
for (auto &pointer : column_data.pointers) {
|
879
|
+
pointer.row_start = current_start;
|
880
|
+
current_start += pointer.tuple_count;
|
881
|
+
}
|
882
|
+
for (auto &child : column_data.child_columns) {
|
883
|
+
RealignColumnData(child, new_start);
|
884
|
+
}
|
885
|
+
}
|
886
|
+
|
876
887
|
shared_ptr<ColumnData> ColumnData::Deserialize(BlockManager &block_manager, DataTableInfo &info, idx_t column_index,
|
877
888
|
idx_t start_row, ReadStream &source, const LogicalType &type) {
|
878
889
|
auto entry = ColumnData::CreateColumn(block_manager, info, column_index, start_row, type, nullptr);
|
@@ -890,6 +901,9 @@ shared_ptr<ColumnData> ColumnData::Deserialize(BlockManager &block_manager, Data
|
|
890
901
|
deserializer.Unset<DatabaseInstance>();
|
891
902
|
deserializer.End();
|
892
903
|
|
904
|
+
// re-align data segments, in case our start_row has changed
|
905
|
+
RealignColumnData(persistent_column_data, start_row);
|
906
|
+
|
893
907
|
// initialize the column
|
894
908
|
entry->InitializeColumn(persistent_column_data, entry->stats->statistics);
|
895
909
|
return entry;
|
@@ -376,8 +376,22 @@ void ColumnDataCheckpointer::WritePersistentSegments(ColumnCheckpointState &stat
|
|
376
376
|
for (idx_t segment_idx = 0; segment_idx < nodes.size(); segment_idx++) {
|
377
377
|
auto segment = nodes[segment_idx].node.get();
|
378
378
|
if (segment->start != current_row) {
|
379
|
+
string extra_info;
|
380
|
+
for (auto &s : nodes) {
|
381
|
+
extra_info += "\n";
|
382
|
+
extra_info += StringUtil::Format("Start %d, count %d", s.node->start, s.node->count.load());
|
383
|
+
}
|
384
|
+
const_reference<ColumnData> root = col_data;
|
385
|
+
while (root.get().HasParent()) {
|
386
|
+
root = root.get().Parent();
|
387
|
+
}
|
379
388
|
throw InternalException(
|
380
|
-
"Failure in RowGroup::Checkpoint - column data pointer is unaligned with row group
|
389
|
+
"Failure in RowGroup::Checkpoint - column data pointer is unaligned with row group "
|
390
|
+
"start\nRow group start: %d\nRow group count %d\nCurrent row: %d\nSegment start: %d\nColumn index: "
|
391
|
+
"%d\nColumn type: %s\nRoot type: %s\nTable: %s.%s\nAll segments:%s",
|
392
|
+
row_group.start, row_group.count.load(), current_row, segment->start, root.get().column_index,
|
393
|
+
col_data.type, root.get().type, root.get().info.GetSchemaName(), root.get().info.GetTableName(),
|
394
|
+
extra_info);
|
381
395
|
}
|
382
396
|
current_row += segment->count;
|
383
397
|
auto pointer = segment->GetDataPointer();
|
@@ -263,13 +263,14 @@ idx_t ListColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &result
|
|
263
263
|
throw NotImplementedException("List Fetch");
|
264
264
|
}
|
265
265
|
|
266
|
-
void ListColumnData::Update(TransactionData transaction,
|
267
|
-
idx_t update_count) {
|
266
|
+
void ListColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
267
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count) {
|
268
268
|
throw NotImplementedException("List Update is not supported.");
|
269
269
|
}
|
270
270
|
|
271
|
-
void ListColumnData::UpdateColumn(TransactionData transaction,
|
272
|
-
Vector &update_vector, row_t *row_ids,
|
271
|
+
void ListColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table,
|
272
|
+
const vector<column_t> &column_path, Vector &update_vector, row_t *row_ids,
|
273
|
+
idx_t update_count, idx_t depth) {
|
273
274
|
throw NotImplementedException("List Update Column is not supported");
|
274
275
|
}
|
275
276
|
|
@@ -859,8 +859,8 @@ void RowGroup::CleanupAppend(transaction_t lowest_transaction, idx_t start, idx_
|
|
859
859
|
vinfo.CleanupAppend(lowest_transaction, start, count);
|
860
860
|
}
|
861
861
|
|
862
|
-
void RowGroup::Update(TransactionData transaction, DataChunk &update_chunk, row_t *ids,
|
863
|
-
const vector<PhysicalIndex> &column_ids) {
|
862
|
+
void RowGroup::Update(TransactionData transaction, DataTable &data_table, DataChunk &update_chunk, row_t *ids,
|
863
|
+
idx_t offset, idx_t count, const vector<PhysicalIndex> &column_ids) {
|
864
864
|
#ifdef DEBUG
|
865
865
|
for (size_t i = offset; i < offset + count; i++) {
|
866
866
|
D_ASSERT(ids[i] >= row_t(this->start) && ids[i] < row_t(this->start + this->count));
|
@@ -873,16 +873,16 @@ void RowGroup::Update(TransactionData transaction, DataChunk &update_chunk, row_
|
|
873
873
|
if (offset > 0) {
|
874
874
|
Vector sliced_vector(update_chunk.data[i], offset, offset + count);
|
875
875
|
sliced_vector.Flatten(count);
|
876
|
-
col_data.Update(transaction, column.index, sliced_vector, ids + offset, count);
|
876
|
+
col_data.Update(transaction, data_table, column.index, sliced_vector, ids + offset, count);
|
877
877
|
} else {
|
878
|
-
col_data.Update(transaction, column.index, update_chunk.data[i], ids, count);
|
878
|
+
col_data.Update(transaction, data_table, column.index, update_chunk.data[i], ids, count);
|
879
879
|
}
|
880
880
|
MergeStatistics(column.index, *col_data.GetUpdateStatistics());
|
881
881
|
}
|
882
882
|
}
|
883
883
|
|
884
|
-
void RowGroup::UpdateColumn(TransactionData transaction, DataChunk &updates, Vector &row_ids,
|
885
|
-
const vector<column_t> &column_path) {
|
884
|
+
void RowGroup::UpdateColumn(TransactionData transaction, DataTable &data_table, DataChunk &updates, Vector &row_ids,
|
885
|
+
idx_t offset, idx_t count, const vector<column_t> &column_path) {
|
886
886
|
D_ASSERT(updates.ColumnCount() == 1);
|
887
887
|
auto ids = FlatVector::GetData<row_t>(row_ids);
|
888
888
|
|
@@ -892,9 +892,9 @@ void RowGroup::UpdateColumn(TransactionData transaction, DataChunk &updates, Vec
|
|
892
892
|
if (offset > 0) {
|
893
893
|
Vector sliced_vector(updates.data[0], offset, offset + count);
|
894
894
|
sliced_vector.Flatten(count);
|
895
|
-
col_data.UpdateColumn(transaction, column_path, sliced_vector, ids + offset, count, 1);
|
895
|
+
col_data.UpdateColumn(transaction, data_table, column_path, sliced_vector, ids + offset, count, 1);
|
896
896
|
} else {
|
897
|
-
col_data.UpdateColumn(transaction, column_path, updates.data[0], ids, count, 1);
|
897
|
+
col_data.UpdateColumn(transaction, data_table, column_path, updates.data[0], ids, count, 1);
|
898
898
|
}
|
899
899
|
MergeStatistics(primary_column_idx, *col_data.GetUpdateStatistics());
|
900
900
|
}
|
@@ -645,14 +645,14 @@ optional_ptr<RowGroup> RowGroupCollection::NextUpdateRowGroup(row_t *ids, idx_t
|
|
645
645
|
return row_group;
|
646
646
|
}
|
647
647
|
|
648
|
-
void RowGroupCollection::Update(TransactionData transaction, row_t *ids,
|
649
|
-
DataChunk &updates) {
|
648
|
+
void RowGroupCollection::Update(TransactionData transaction, DataTable &data_table, row_t *ids,
|
649
|
+
const vector<PhysicalIndex> &column_ids, DataChunk &updates) {
|
650
650
|
D_ASSERT(updates.size() >= 1);
|
651
651
|
idx_t pos = 0;
|
652
652
|
do {
|
653
653
|
idx_t start = pos;
|
654
654
|
auto row_group = NextUpdateRowGroup(ids, pos, updates.size());
|
655
|
-
row_group->Update(transaction, updates, ids, start, pos - start, column_ids);
|
655
|
+
row_group->Update(transaction, data_table, updates, ids, start, pos - start, column_ids);
|
656
656
|
|
657
657
|
auto l = stats.GetLock();
|
658
658
|
for (idx_t i = 0; i < column_ids.size(); i++) {
|
@@ -764,15 +764,15 @@ void RowGroupCollection::RemoveFromIndexes(TableIndexList &indexes, Vector &row_
|
|
764
764
|
}
|
765
765
|
}
|
766
766
|
|
767
|
-
void RowGroupCollection::UpdateColumn(TransactionData transaction,
|
768
|
-
DataChunk &updates) {
|
767
|
+
void RowGroupCollection::UpdateColumn(TransactionData transaction, DataTable &data_table, Vector &row_ids,
|
768
|
+
const vector<column_t> &column_path, DataChunk &updates) {
|
769
769
|
D_ASSERT(updates.size() >= 1);
|
770
770
|
auto ids = FlatVector::GetData<row_t>(row_ids);
|
771
771
|
idx_t pos = 0;
|
772
772
|
do {
|
773
773
|
idx_t start = pos;
|
774
774
|
auto row_group = NextUpdateRowGroup(ids, pos, updates.size());
|
775
|
-
row_group->UpdateColumn(transaction, updates, row_ids, start, pos - start, column_path);
|
775
|
+
row_group->UpdateColumn(transaction, data_table, updates, row_ids, start, pos - start, column_path);
|
776
776
|
|
777
777
|
auto lock = stats.GetLock();
|
778
778
|
auto primary_column_idx = column_path[0];
|
@@ -1008,8 +1008,8 @@ bool RowGroupCollection::ScheduleVacuumTasks(CollectionCheckpointState &checkpoi
|
|
1008
1008
|
}
|
1009
1009
|
idx_t merge_rows;
|
1010
1010
|
idx_t next_idx = 0;
|
1011
|
-
idx_t merge_count;
|
1012
|
-
idx_t target_count;
|
1011
|
+
idx_t merge_count = 0;
|
1012
|
+
idx_t target_count = 0;
|
1013
1013
|
bool perform_merge = false;
|
1014
1014
|
// check if we can merge row groups adjacent to the current segment_idx
|
1015
1015
|
// we try merging row groups into batches of 1-3 row groups
|
@@ -1061,6 +1061,8 @@ bool RowGroupCollection::ScheduleVacuumTasks(CollectionCheckpointState &checkpoi
|
|
1061
1061
|
return false;
|
1062
1062
|
}
|
1063
1063
|
// schedule the vacuum task
|
1064
|
+
DUCKDB_LOG(checkpoint_state.writer.GetDatabase(), CheckpointLogType, GetAttached(), *info, segment_idx, merge_count,
|
1065
|
+
target_count, merge_rows, state.row_start);
|
1064
1066
|
auto vacuum_task = make_uniq<VacuumTask>(checkpoint_state, state, segment_idx, merge_count, target_count,
|
1065
1067
|
merge_rows, state.row_start);
|
1066
1068
|
checkpoint_state.executor->ScheduleTask(std::move(vacuum_task));
|
@@ -1107,6 +1109,8 @@ void RowGroupCollection::Checkpoint(TableDataWriter &writer, TableStatistics &gl
|
|
1107
1109
|
// schedule a checkpoint task for this row group
|
1108
1110
|
entry.node->MoveToCollection(*this, vacuum_state.row_start);
|
1109
1111
|
if (writer.GetCheckpointType() != CheckpointType::VACUUM_ONLY) {
|
1112
|
+
DUCKDB_LOG(checkpoint_state.writer.GetDatabase(), CheckpointLogType, GetAttached(), *info, segment_idx,
|
1113
|
+
*entry.node);
|
1110
1114
|
auto checkpoint_task = GetCheckpointTask(checkpoint_state, segment_idx);
|
1111
1115
|
checkpoint_state.executor->ScheduleTask(std::move(checkpoint_task));
|
1112
1116
|
}
|
@@ -138,13 +138,14 @@ void RowIdColumnData::RevertAppend(row_t start_row) {
|
|
138
138
|
throw InternalException("RowIdColumnData cannot be appended to");
|
139
139
|
}
|
140
140
|
|
141
|
-
void RowIdColumnData::Update(TransactionData transaction,
|
142
|
-
idx_t update_count) {
|
141
|
+
void RowIdColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
142
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count) {
|
143
143
|
throw InternalException("RowIdColumnData cannot be updated");
|
144
144
|
}
|
145
145
|
|
146
|
-
void RowIdColumnData::UpdateColumn(TransactionData transaction,
|
147
|
-
Vector &update_vector, row_t *row_ids,
|
146
|
+
void RowIdColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table,
|
147
|
+
const vector<column_t> &column_path, Vector &update_vector, row_t *row_ids,
|
148
|
+
idx_t update_count, idx_t depth) {
|
148
149
|
throw InternalException("RowIdColumnData cannot be updated");
|
149
150
|
}
|
150
151
|
|
@@ -152,8 +152,8 @@ idx_t StandardColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &re
|
|
152
152
|
return scan_count;
|
153
153
|
}
|
154
154
|
|
155
|
-
void StandardColumnData::Update(TransactionData transaction,
|
156
|
-
idx_t update_count) {
|
155
|
+
void StandardColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
156
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count) {
|
157
157
|
ColumnScanState standard_state, validity_state;
|
158
158
|
Vector base_vector(type);
|
159
159
|
auto standard_fetch = FetchUpdateData(standard_state, row_ids, base_vector);
|
@@ -162,18 +162,19 @@ void StandardColumnData::Update(TransactionData transaction, idx_t column_index,
|
|
162
162
|
throw InternalException("Unaligned fetch in validity and main column data for update");
|
163
163
|
}
|
164
164
|
|
165
|
-
UpdateInternal(transaction, column_index, update_vector, row_ids, update_count, base_vector);
|
166
|
-
validity.UpdateInternal(transaction, column_index, update_vector, row_ids, update_count, base_vector);
|
165
|
+
UpdateInternal(transaction, data_table, column_index, update_vector, row_ids, update_count, base_vector);
|
166
|
+
validity.UpdateInternal(transaction, data_table, column_index, update_vector, row_ids, update_count, base_vector);
|
167
167
|
}
|
168
168
|
|
169
|
-
void StandardColumnData::UpdateColumn(TransactionData transaction,
|
170
|
-
Vector &update_vector, row_t *row_ids,
|
169
|
+
void StandardColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table,
|
170
|
+
const vector<column_t> &column_path, Vector &update_vector, row_t *row_ids,
|
171
|
+
idx_t update_count, idx_t depth) {
|
171
172
|
if (depth >= column_path.size()) {
|
172
173
|
// update this column
|
173
|
-
ColumnData::Update(transaction, column_path[0], update_vector, row_ids, update_count);
|
174
|
+
ColumnData::Update(transaction, data_table, column_path[0], update_vector, row_ids, update_count);
|
174
175
|
} else {
|
175
176
|
// update the child column (i.e. the validity column)
|
176
|
-
validity.UpdateColumn(transaction, column_path, update_vector, row_ids, update_count, depth + 1);
|
177
|
+
validity.UpdateColumn(transaction, data_table, column_path, update_vector, row_ids, update_count, depth + 1);
|
177
178
|
}
|
178
179
|
}
|
179
180
|
|
@@ -207,17 +207,18 @@ idx_t StructColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &resu
|
|
207
207
|
return scan_count;
|
208
208
|
}
|
209
209
|
|
210
|
-
void StructColumnData::Update(TransactionData transaction,
|
211
|
-
idx_t update_count) {
|
212
|
-
validity.Update(transaction, column_index, update_vector, row_ids, update_count);
|
210
|
+
void StructColumnData::Update(TransactionData transaction, DataTable &data_table, idx_t column_index,
|
211
|
+
Vector &update_vector, row_t *row_ids, idx_t update_count) {
|
212
|
+
validity.Update(transaction, data_table, column_index, update_vector, row_ids, update_count);
|
213
213
|
auto &child_entries = StructVector::GetEntries(update_vector);
|
214
214
|
for (idx_t i = 0; i < child_entries.size(); i++) {
|
215
|
-
sub_columns[i]->Update(transaction, column_index, *child_entries[i], row_ids, update_count);
|
215
|
+
sub_columns[i]->Update(transaction, data_table, column_index, *child_entries[i], row_ids, update_count);
|
216
216
|
}
|
217
217
|
}
|
218
218
|
|
219
|
-
void StructColumnData::UpdateColumn(TransactionData transaction,
|
220
|
-
Vector &update_vector, row_t *row_ids,
|
219
|
+
void StructColumnData::UpdateColumn(TransactionData transaction, DataTable &data_table,
|
220
|
+
const vector<column_t> &column_path, Vector &update_vector, row_t *row_ids,
|
221
|
+
idx_t update_count, idx_t depth) {
|
221
222
|
// we can never DIRECTLY update a struct column
|
222
223
|
if (depth >= column_path.size()) {
|
223
224
|
throw InternalException("Attempting to directly update a struct column - this should not be possible");
|
@@ -225,13 +226,13 @@ void StructColumnData::UpdateColumn(TransactionData transaction, const vector<co
|
|
225
226
|
auto update_column = column_path[depth];
|
226
227
|
if (update_column == 0) {
|
227
228
|
// update the validity column
|
228
|
-
validity.UpdateColumn(transaction, column_path, update_vector, row_ids, update_count, depth + 1);
|
229
|
+
validity.UpdateColumn(transaction, data_table, column_path, update_vector, row_ids, update_count, depth + 1);
|
229
230
|
} else {
|
230
231
|
if (update_column > sub_columns.size()) {
|
231
232
|
throw InternalException("Update column_path out of range");
|
232
233
|
}
|
233
|
-
sub_columns[update_column - 1]->UpdateColumn(transaction, column_path, update_vector, row_ids,
|
234
|
-
depth + 1);
|
234
|
+
sub_columns[update_column - 1]->UpdateColumn(transaction, data_table, column_path, update_vector, row_ids,
|
235
|
+
update_count, depth + 1);
|
235
236
|
}
|
236
237
|
}
|
237
238
|
|