duckdb 0.5.2-dev1460.0 → 0.5.2-dev1468.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +83 -36
- package/src/duckdb.hpp +17 -3
- package/src/parquet-amalgamation.cpp +29218 -29218
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -80586,7 +80586,7 @@ public:
|
|
|
80586
80586
|
idx_t current_index;
|
|
80587
80587
|
TableAppendState current_append_state;
|
|
80588
80588
|
unique_ptr<RowGroupCollection> current_collection;
|
|
80589
|
-
|
|
80589
|
+
OptimisticDataWriter *writer;
|
|
80590
80590
|
bool written_to_disk;
|
|
80591
80591
|
|
|
80592
80592
|
void FlushToDisk() {
|
|
@@ -80636,16 +80636,17 @@ SinkResultType PhysicalBatchInsert::Sink(ExecutionContext &context, GlobalSinkSt
|
|
|
80636
80636
|
PhysicalInsert::ResolveDefaults(table, chunk, column_index_map, lstate.default_executor, lstate.insert_chunk);
|
|
80637
80637
|
|
|
80638
80638
|
if (!lstate.current_collection) {
|
|
80639
|
+
lock_guard<mutex> l(gstate.lock);
|
|
80639
80640
|
// no collection yet: create a new one
|
|
80640
80641
|
lstate.CreateNewCollection(table, insert_types);
|
|
80641
|
-
lstate.writer =
|
|
80642
|
+
lstate.writer = gstate.table->storage->CreateOptimisticWriter(context.client);
|
|
80642
80643
|
} else if (lstate.current_index != lstate.batch_index) {
|
|
80643
80644
|
// batch index has changed: move the old collection to the global state and create a new collection
|
|
80644
80645
|
TransactionData tdata(0, 0);
|
|
80645
80646
|
lstate.current_collection->FinalizeAppend(tdata, lstate.current_append_state);
|
|
80646
80647
|
lstate.FlushToDisk();
|
|
80647
80648
|
|
|
80648
|
-
gstate.AddCollection(context.client, lstate.current_index, move(lstate.current_collection), lstate.writer
|
|
80649
|
+
gstate.AddCollection(context.client, lstate.current_index, move(lstate.current_collection), lstate.writer,
|
|
80649
80650
|
&lstate.written_to_disk);
|
|
80650
80651
|
lstate.CreateNewCollection(table, insert_types);
|
|
80651
80652
|
}
|
|
@@ -80715,7 +80716,7 @@ SinkFinalizeType PhysicalBatchInsert::Finalize(Pipeline &pipeline, Event &event,
|
|
|
80715
80716
|
// now that we have created all of the mergers, perform the actual merging
|
|
80716
80717
|
vector<unique_ptr<RowGroupCollection>> final_collections;
|
|
80717
80718
|
final_collections.reserve(mergers.size());
|
|
80718
|
-
auto writer =
|
|
80719
|
+
auto writer = storage.CreateOptimisticWriter(context);
|
|
80719
80720
|
for (auto &merger : mergers) {
|
|
80720
80721
|
final_collections.push_back(merger->Flush(*writer));
|
|
80721
80722
|
}
|
|
@@ -81415,7 +81416,7 @@ public:
|
|
|
81415
81416
|
ExpressionExecutor default_executor;
|
|
81416
81417
|
TableAppendState local_append_state;
|
|
81417
81418
|
unique_ptr<RowGroupCollection> local_collection;
|
|
81418
|
-
|
|
81419
|
+
OptimisticDataWriter *writer;
|
|
81419
81420
|
};
|
|
81420
81421
|
|
|
81421
81422
|
unique_ptr<GlobalSinkState> PhysicalInsert::GetGlobalSinkState(ClientContext &context) const {
|
|
@@ -81494,13 +81495,14 @@ SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState &
|
|
|
81494
81495
|
D_ASSERT(!return_chunk);
|
|
81495
81496
|
// parallel append
|
|
81496
81497
|
if (!lstate.local_collection) {
|
|
81498
|
+
lock_guard<mutex> l(gstate.lock);
|
|
81497
81499
|
auto &table_info = table->storage->info;
|
|
81498
81500
|
auto &block_manager = TableIOManager::Get(*table->storage).GetBlockManagerForRowData();
|
|
81499
81501
|
lstate.local_collection =
|
|
81500
81502
|
make_unique<RowGroupCollection>(table_info, block_manager, insert_types, MAX_ROW_ID);
|
|
81501
81503
|
lstate.local_collection->InitializeEmpty();
|
|
81502
81504
|
lstate.local_collection->InitializeAppend(lstate.local_append_state);
|
|
81503
|
-
lstate.writer =
|
|
81505
|
+
lstate.writer = gstate.table->storage->CreateOptimisticWriter(context.client);
|
|
81504
81506
|
}
|
|
81505
81507
|
table->storage->VerifyAppendConstraints(*table, context.client, lstate.insert_chunk);
|
|
81506
81508
|
auto new_row_group = lstate.local_collection->Append(lstate.insert_chunk, lstate.local_append_state);
|
|
@@ -87227,11 +87229,6 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalInsert &op
|
|
|
87227
87229
|
|
|
87228
87230
|
bool parallel_streaming_insert = !PreserveInsertionOrder(*plan);
|
|
87229
87231
|
bool use_batch_index = UseBatchIndex(*plan);
|
|
87230
|
-
if (!op.table->storage->info->indexes.Empty()) {
|
|
87231
|
-
// not for tables with indexes currently
|
|
87232
|
-
parallel_streaming_insert = false;
|
|
87233
|
-
use_batch_index = false;
|
|
87234
|
-
}
|
|
87235
87232
|
if (op.return_chunk) {
|
|
87236
87233
|
// not supported for RETURNING (yet?)
|
|
87237
87234
|
parallel_streaming_insert = false;
|
|
@@ -198132,6 +198129,9 @@ public:
|
|
|
198132
198129
|
bool IsRootBlock(block_id_t root) override {
|
|
198133
198130
|
throw InternalException("Cannot perform IO in in-memory database!");
|
|
198134
198131
|
}
|
|
198132
|
+
void MarkBlockAsFree(block_id_t block_id) override {
|
|
198133
|
+
throw InternalException("Cannot perform IO in in-memory database!");
|
|
198134
|
+
}
|
|
198135
198135
|
void MarkBlockAsModified(block_id_t block_id) override {
|
|
198136
198136
|
throw InternalException("Cannot perform IO in in-memory database!");
|
|
198137
198137
|
}
|
|
@@ -208337,6 +208337,11 @@ void DataTable::FinalizeLocalAppend(LocalAppendState &state) {
|
|
|
208337
208337
|
LocalStorage::FinalizeAppend(state);
|
|
208338
208338
|
}
|
|
208339
208339
|
|
|
208340
|
+
OptimisticDataWriter *DataTable::CreateOptimisticWriter(ClientContext &context) {
|
|
208341
|
+
auto &local_storage = LocalStorage::Get(context);
|
|
208342
|
+
return local_storage.CreateOptimisticWriter(this);
|
|
208343
|
+
}
|
|
208344
|
+
|
|
208340
208345
|
void DataTable::LocalMerge(ClientContext &context, RowGroupCollection &collection) {
|
|
208341
208346
|
auto &local_storage = LocalStorage::Get(context);
|
|
208342
208347
|
local_storage.LocalMerge(this, collection);
|
|
@@ -209000,7 +209005,7 @@ void OptimisticDataWriter::Rollback() {
|
|
|
209000
209005
|
if (!written_blocks.empty()) {
|
|
209001
209006
|
auto &block_manager = table->info->table_io_manager->GetBlockManagerForRowData();
|
|
209002
209007
|
for (auto block_id : written_blocks) {
|
|
209003
|
-
block_manager.
|
|
209008
|
+
block_manager.MarkBlockAsFree(block_id);
|
|
209004
209009
|
}
|
|
209005
209010
|
}
|
|
209006
209011
|
}
|
|
@@ -209034,7 +209039,7 @@ LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &paren
|
|
|
209034
209039
|
const LogicalType &target_type, const vector<column_t> &bound_columns,
|
|
209035
209040
|
Expression &cast_expr)
|
|
209036
209041
|
: table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows),
|
|
209037
|
-
optimistic_writer(table, parent.optimistic_writer) {
|
|
209042
|
+
optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) {
|
|
209038
209043
|
row_groups = parent.row_groups->AlterType(changed_idx, target_type, bound_columns, cast_expr);
|
|
209039
209044
|
parent.row_groups.reset();
|
|
209040
209045
|
indexes.Move(parent.indexes);
|
|
@@ -209042,7 +209047,7 @@ LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &paren
|
|
|
209042
209047
|
|
|
209043
209048
|
LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &parent, idx_t drop_idx)
|
|
209044
209049
|
: table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows),
|
|
209045
|
-
optimistic_writer(table, parent.optimistic_writer) {
|
|
209050
|
+
optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) {
|
|
209046
209051
|
row_groups = parent.row_groups->RemoveColumn(drop_idx);
|
|
209047
209052
|
parent.row_groups.reset();
|
|
209048
209053
|
indexes.Move(parent.indexes);
|
|
@@ -209051,7 +209056,7 @@ LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &paren
|
|
|
209051
209056
|
LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &parent, ColumnDefinition &new_column,
|
|
209052
209057
|
Expression *default_value)
|
|
209053
209058
|
: table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows),
|
|
209054
|
-
optimistic_writer(table, parent.optimistic_writer) {
|
|
209059
|
+
optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) {
|
|
209055
209060
|
row_groups = parent.row_groups->AddColumn(new_column, default_value);
|
|
209056
209061
|
parent.row_groups.reset();
|
|
209057
209062
|
indexes.Move(parent.indexes);
|
|
@@ -209094,6 +209099,33 @@ void LocalTableStorage::FlushToDisk() {
|
|
|
209094
209099
|
optimistic_writer.FinalFlush();
|
|
209095
209100
|
}
|
|
209096
209101
|
|
|
209102
|
+
bool LocalTableStorage::AppendToIndexes(Transaction &transaction, RowGroupCollection &source,
|
|
209103
|
+
TableIndexList &index_list, const vector<LogicalType> &table_types,
|
|
209104
|
+
row_t &start_row) {
|
|
209105
|
+
// only need to scan for index append
|
|
209106
|
+
// figure out which columns we need to scan for the set of indexes
|
|
209107
|
+
auto columns = index_list.GetRequiredColumns();
|
|
209108
|
+
// create an empty mock chunk that contains all the correct types for the table
|
|
209109
|
+
DataChunk mock_chunk;
|
|
209110
|
+
mock_chunk.InitializeEmpty(table_types);
|
|
209111
|
+
bool success = true;
|
|
209112
|
+
source.Scan(transaction, columns, [&](DataChunk &chunk) -> bool {
|
|
209113
|
+
// construct the mock chunk by referencing the required columns
|
|
209114
|
+
for (idx_t i = 0; i < columns.size(); i++) {
|
|
209115
|
+
mock_chunk.data[columns[i]].Reference(chunk.data[i]);
|
|
209116
|
+
}
|
|
209117
|
+
mock_chunk.SetCardinality(chunk);
|
|
209118
|
+
// append this chunk to the indexes of the table
|
|
209119
|
+
if (!DataTable::AppendToIndexes(index_list, mock_chunk, start_row)) {
|
|
209120
|
+
success = false;
|
|
209121
|
+
return false;
|
|
209122
|
+
}
|
|
209123
|
+
start_row += chunk.size();
|
|
209124
|
+
return true;
|
|
209125
|
+
});
|
|
209126
|
+
return success;
|
|
209127
|
+
}
|
|
209128
|
+
|
|
209097
209129
|
void LocalTableStorage::AppendToIndexes(Transaction &transaction, TableAppendState &append_state, idx_t append_count,
|
|
209098
209130
|
bool append_to_table) {
|
|
209099
209131
|
bool constraint_violated = false;
|
|
@@ -209113,26 +209145,8 @@ void LocalTableStorage::AppendToIndexes(Transaction &transaction, TableAppendSta
|
|
|
209113
209145
|
return true;
|
|
209114
209146
|
});
|
|
209115
209147
|
} else {
|
|
209116
|
-
|
|
209117
|
-
|
|
209118
|
-
auto columns = table->info->indexes.GetRequiredColumns();
|
|
209119
|
-
// create an empty mock chunk that contains all the correct types for the table
|
|
209120
|
-
DataChunk mock_chunk;
|
|
209121
|
-
mock_chunk.InitializeEmpty(table->GetTypes());
|
|
209122
|
-
row_groups->Scan(transaction, columns, [&](DataChunk &chunk) -> bool {
|
|
209123
|
-
// construct the mock chunk by referencing the required columns
|
|
209124
|
-
for (idx_t i = 0; i < columns.size(); i++) {
|
|
209125
|
-
mock_chunk.data[columns[i]].Reference(chunk.data[i]);
|
|
209126
|
-
}
|
|
209127
|
-
mock_chunk.SetCardinality(chunk);
|
|
209128
|
-
// append this chunk to the indexes of the table
|
|
209129
|
-
if (!table->AppendToIndexes(mock_chunk, append_state.current_row)) {
|
|
209130
|
-
constraint_violated = true;
|
|
209131
|
-
return false;
|
|
209132
|
-
}
|
|
209133
|
-
append_state.current_row += chunk.size();
|
|
209134
|
-
return true;
|
|
209135
|
-
});
|
|
209148
|
+
constraint_violated = !AppendToIndexes(transaction, *row_groups, table->info->indexes, table->GetTypes(),
|
|
209149
|
+
append_state.current_row);
|
|
209136
209150
|
}
|
|
209137
209151
|
if (constraint_violated) {
|
|
209138
209152
|
// need to revert the append
|
|
@@ -209156,8 +209170,18 @@ void LocalTableStorage::AppendToIndexes(Transaction &transaction, TableAppendSta
|
|
|
209156
209170
|
}
|
|
209157
209171
|
}
|
|
209158
209172
|
|
|
209173
|
+
OptimisticDataWriter *LocalTableStorage::CreateOptimisticWriter() {
|
|
209174
|
+
auto writer = make_unique<OptimisticDataWriter>(table);
|
|
209175
|
+
optimistic_writers.push_back(move(writer));
|
|
209176
|
+
return optimistic_writers.back().get();
|
|
209177
|
+
}
|
|
209178
|
+
|
|
209159
209179
|
void LocalTableStorage::Rollback() {
|
|
209160
209180
|
optimistic_writer.Rollback();
|
|
209181
|
+
for (auto &writer : optimistic_writers) {
|
|
209182
|
+
writer->Rollback();
|
|
209183
|
+
}
|
|
209184
|
+
optimistic_writers.clear();
|
|
209161
209185
|
}
|
|
209162
209186
|
|
|
209163
209187
|
//===--------------------------------------------------------------------===//
|
|
@@ -209292,9 +209316,22 @@ void LocalStorage::FinalizeAppend(LocalAppendState &state) {
|
|
|
209292
209316
|
|
|
209293
209317
|
void LocalStorage::LocalMerge(DataTable *table, RowGroupCollection &collection) {
|
|
209294
209318
|
auto storage = table_manager.GetOrCreateStorage(table);
|
|
209319
|
+
if (!storage->indexes.Empty()) {
|
|
209320
|
+
// append data to indexes if required
|
|
209321
|
+
row_t base_id = MAX_ROW_ID + storage->row_groups->GetTotalRows();
|
|
209322
|
+
bool success = storage->AppendToIndexes(transaction, collection, storage->indexes, table->GetTypes(), base_id);
|
|
209323
|
+
if (!success) {
|
|
209324
|
+
throw ConstraintException("PRIMARY KEY or UNIQUE constraint violated: duplicated key");
|
|
209325
|
+
}
|
|
209326
|
+
}
|
|
209295
209327
|
storage->row_groups->MergeStorage(collection);
|
|
209296
209328
|
}
|
|
209297
209329
|
|
|
209330
|
+
OptimisticDataWriter *LocalStorage::CreateOptimisticWriter(DataTable *table) {
|
|
209331
|
+
auto storage = table_manager.GetOrCreateStorage(table);
|
|
209332
|
+
return storage->CreateOptimisticWriter();
|
|
209333
|
+
}
|
|
209334
|
+
|
|
209298
209335
|
bool LocalStorage::ChangesMade() noexcept {
|
|
209299
209336
|
return !table_manager.IsEmpty();
|
|
209300
209337
|
}
|
|
@@ -209737,7 +209774,9 @@ public:
|
|
|
209737
209774
|
block_id_t GetFreeBlockId() override;
|
|
209738
209775
|
//! Returns whether or not a specified block is the root block
|
|
209739
209776
|
bool IsRootBlock(block_id_t root) override;
|
|
209740
|
-
//! Mark a block as
|
|
209777
|
+
//! Mark a block as free (immediately re-writeable)
|
|
209778
|
+
void MarkBlockAsFree(block_id_t block_id) override;
|
|
209779
|
+
//! Mark a block as modified (re-writeable after a checkpoint)
|
|
209741
209780
|
void MarkBlockAsModified(block_id_t block_id) override;
|
|
209742
209781
|
//! Increase the reference count of a block. The block should hold at least one reference
|
|
209743
209782
|
void IncreaseBlockReferenceCount(block_id_t block_id) override;
|
|
@@ -210035,6 +210074,14 @@ block_id_t SingleFileBlockManager::GetFreeBlockId() {
|
|
|
210035
210074
|
return block;
|
|
210036
210075
|
}
|
|
210037
210076
|
|
|
210077
|
+
void SingleFileBlockManager::MarkBlockAsFree(block_id_t block_id) {
|
|
210078
|
+
lock_guard<mutex> lock(block_lock);
|
|
210079
|
+
D_ASSERT(block_id >= 0);
|
|
210080
|
+
D_ASSERT(free_list.find(block_id) == free_list.end());
|
|
210081
|
+
multi_use_blocks.erase(block_id);
|
|
210082
|
+
free_list.insert(block_id);
|
|
210083
|
+
}
|
|
210084
|
+
|
|
210038
210085
|
void SingleFileBlockManager::MarkBlockAsModified(block_id_t block_id) {
|
|
210039
210086
|
lock_guard<mutex> lock(block_lock);
|
|
210040
210087
|
D_ASSERT(block_id >= 0);
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.5.2-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "4f495e8eea"
|
|
15
|
+
#define DUCKDB_VERSION "v0.5.2-dev1468"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -25197,6 +25197,8 @@ public:
|
|
|
25197
25197
|
virtual block_id_t GetFreeBlockId() = 0;
|
|
25198
25198
|
//! Returns whether or not a specified block is the root block
|
|
25199
25199
|
virtual bool IsRootBlock(block_id_t root) = 0;
|
|
25200
|
+
//! Mark a block as "free"; free blocks are immediately added to the free list and can be immediately overwritten
|
|
25201
|
+
virtual void MarkBlockAsFree(block_id_t block_id) = 0;
|
|
25200
25202
|
//! Mark a block as "modified"; modified blocks are added to the free list after a checkpoint (i.e. their data is
|
|
25201
25203
|
//! assumed to be rewritten)
|
|
25202
25204
|
virtual void MarkBlockAsModified(block_id_t block_id) = 0;
|
|
@@ -26478,8 +26480,10 @@ public:
|
|
|
26478
26480
|
TableIndexList indexes;
|
|
26479
26481
|
//! The number of deleted rows
|
|
26480
26482
|
idx_t deleted_rows;
|
|
26481
|
-
//! The optimistic data writer
|
|
26483
|
+
//! The main optimistic data writer
|
|
26482
26484
|
OptimisticDataWriter optimistic_writer;
|
|
26485
|
+
//! The set of all optimistic data writers associated with this table
|
|
26486
|
+
vector<unique_ptr<OptimisticDataWriter>> optimistic_writers;
|
|
26483
26487
|
|
|
26484
26488
|
public:
|
|
26485
26489
|
void InitializeScan(CollectionScanState &state, TableFilterSet *table_filters = nullptr);
|
|
@@ -26492,6 +26496,11 @@ public:
|
|
|
26492
26496
|
|
|
26493
26497
|
void AppendToIndexes(Transaction &transaction, TableAppendState &append_state, idx_t append_count,
|
|
26494
26498
|
bool append_to_table);
|
|
26499
|
+
bool AppendToIndexes(Transaction &transaction, RowGroupCollection &source, TableIndexList &index_list,
|
|
26500
|
+
const vector<LogicalType> &table_types, row_t &start_row);
|
|
26501
|
+
|
|
26502
|
+
//! Creates an optimistic writer for this table
|
|
26503
|
+
OptimisticDataWriter *CreateOptimisticWriter();
|
|
26495
26504
|
};
|
|
26496
26505
|
|
|
26497
26506
|
class LocalTableManager {
|
|
@@ -26543,6 +26552,8 @@ public:
|
|
|
26543
26552
|
static void FinalizeAppend(LocalAppendState &state);
|
|
26544
26553
|
//! Merge a row group collection into the transaction-local storage
|
|
26545
26554
|
void LocalMerge(DataTable *table, RowGroupCollection &collection);
|
|
26555
|
+
//! Create an optimistic writer for the specified table
|
|
26556
|
+
OptimisticDataWriter *CreateOptimisticWriter(DataTable *table);
|
|
26546
26557
|
|
|
26547
26558
|
//! Delete a set of rows from the local storage
|
|
26548
26559
|
idx_t Delete(DataTable *table, Vector &row_ids, idx_t count);
|
|
@@ -26631,6 +26642,7 @@ class ClientContext;
|
|
|
26631
26642
|
class ColumnDataCollection;
|
|
26632
26643
|
class ColumnDefinition;
|
|
26633
26644
|
class DataTable;
|
|
26645
|
+
class OptimisticDataWriter;
|
|
26634
26646
|
class RowGroup;
|
|
26635
26647
|
class StorageManager;
|
|
26636
26648
|
class TableCatalogEntry;
|
|
@@ -26699,6 +26711,8 @@ public:
|
|
|
26699
26711
|
void LocalAppend(TableCatalogEntry &table, ClientContext &context, ColumnDataCollection &collection);
|
|
26700
26712
|
//! Merge a row group collection into the transaction-local storage
|
|
26701
26713
|
void LocalMerge(ClientContext &context, RowGroupCollection &collection);
|
|
26714
|
+
//! Creates an optimistic writer for this table - used for optimistically writing parallel appends
|
|
26715
|
+
OptimisticDataWriter *CreateOptimisticWriter(ClientContext &context);
|
|
26702
26716
|
|
|
26703
26717
|
//! Delete the entries with the specified row identifier from the table
|
|
26704
26718
|
idx_t Delete(TableCatalogEntry &table, ClientContext &context, Vector &row_ids, idx_t count);
|