duckdb 0.6.1-dev201.0 → 0.6.1-dev218.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 +224 -74
- package/src/duckdb.hpp +38 -17
- package/src/parquet-amalgamation.cpp +29035 -29035
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -5163,6 +5163,98 @@ private:
|
|
|
5163
5163
|
|
|
5164
5164
|
|
|
5165
5165
|
|
|
5166
|
+
//===----------------------------------------------------------------------===//
|
|
5167
|
+
// DuckDB
|
|
5168
|
+
//
|
|
5169
|
+
// duckdb/catalog/mapping_value.hpp
|
|
5170
|
+
//
|
|
5171
|
+
//
|
|
5172
|
+
//===----------------------------------------------------------------------===//
|
|
5173
|
+
|
|
5174
|
+
|
|
5175
|
+
|
|
5176
|
+
|
|
5177
|
+
|
|
5178
|
+
|
|
5179
|
+
namespace duckdb {
|
|
5180
|
+
struct AlterInfo;
|
|
5181
|
+
|
|
5182
|
+
class ClientContext;
|
|
5183
|
+
|
|
5184
|
+
struct EntryIndex {
|
|
5185
|
+
EntryIndex() : catalog(nullptr), index(DConstants::INVALID_INDEX) {
|
|
5186
|
+
}
|
|
5187
|
+
EntryIndex(CatalogSet &catalog, idx_t index) : catalog(&catalog), index(index) {
|
|
5188
|
+
auto entry = catalog.entries.find(index);
|
|
5189
|
+
if (entry == catalog.entries.end()) {
|
|
5190
|
+
throw InternalException("EntryIndex - Catalog entry not found in constructor!?");
|
|
5191
|
+
}
|
|
5192
|
+
catalog.entries[index].reference_count++;
|
|
5193
|
+
}
|
|
5194
|
+
~EntryIndex() {
|
|
5195
|
+
if (!catalog) {
|
|
5196
|
+
return;
|
|
5197
|
+
}
|
|
5198
|
+
auto entry = catalog->entries.find(index);
|
|
5199
|
+
D_ASSERT(entry != catalog->entries.end());
|
|
5200
|
+
auto remaining_ref = --entry->second.reference_count;
|
|
5201
|
+
if (remaining_ref == 0) {
|
|
5202
|
+
catalog->entries.erase(index);
|
|
5203
|
+
}
|
|
5204
|
+
catalog = nullptr;
|
|
5205
|
+
}
|
|
5206
|
+
// disable copy constructors
|
|
5207
|
+
EntryIndex(const EntryIndex &other) = delete;
|
|
5208
|
+
EntryIndex &operator=(const EntryIndex &) = delete;
|
|
5209
|
+
//! enable move constructors
|
|
5210
|
+
EntryIndex(EntryIndex &&other) noexcept {
|
|
5211
|
+
catalog = nullptr;
|
|
5212
|
+
index = DConstants::INVALID_INDEX;
|
|
5213
|
+
std::swap(catalog, other.catalog);
|
|
5214
|
+
std::swap(index, other.index);
|
|
5215
|
+
}
|
|
5216
|
+
EntryIndex &operator=(EntryIndex &&other) noexcept {
|
|
5217
|
+
std::swap(catalog, other.catalog);
|
|
5218
|
+
std::swap(index, other.index);
|
|
5219
|
+
return *this;
|
|
5220
|
+
}
|
|
5221
|
+
|
|
5222
|
+
unique_ptr<CatalogEntry> &GetEntry() {
|
|
5223
|
+
auto entry = catalog->entries.find(index);
|
|
5224
|
+
if (entry == catalog->entries.end()) {
|
|
5225
|
+
throw InternalException("EntryIndex - Catalog entry not found!?");
|
|
5226
|
+
}
|
|
5227
|
+
return entry->second.entry;
|
|
5228
|
+
}
|
|
5229
|
+
idx_t GetIndex() {
|
|
5230
|
+
return index;
|
|
5231
|
+
}
|
|
5232
|
+
EntryIndex Copy() {
|
|
5233
|
+
if (catalog) {
|
|
5234
|
+
return EntryIndex(*catalog, index);
|
|
5235
|
+
} else {
|
|
5236
|
+
return EntryIndex();
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
|
|
5240
|
+
private:
|
|
5241
|
+
CatalogSet *catalog;
|
|
5242
|
+
idx_t index;
|
|
5243
|
+
};
|
|
5244
|
+
|
|
5245
|
+
struct MappingValue {
|
|
5246
|
+
explicit MappingValue(EntryIndex index_p) : index(move(index_p)), timestamp(0), deleted(false), parent(nullptr) {
|
|
5247
|
+
}
|
|
5248
|
+
|
|
5249
|
+
EntryIndex index;
|
|
5250
|
+
transaction_t timestamp;
|
|
5251
|
+
bool deleted;
|
|
5252
|
+
unique_ptr<MappingValue> child;
|
|
5253
|
+
MappingValue *parent;
|
|
5254
|
+
};
|
|
5255
|
+
|
|
5256
|
+
} // namespace duckdb
|
|
5257
|
+
|
|
5166
5258
|
|
|
5167
5259
|
namespace duckdb {
|
|
5168
5260
|
|
|
@@ -5176,27 +5268,44 @@ namespace duckdb {
|
|
|
5176
5268
|
class EntryDropper {
|
|
5177
5269
|
public:
|
|
5178
5270
|
//! Both constructor and destructor are privates because they should only be called by DropEntryDependencies
|
|
5179
|
-
explicit EntryDropper(
|
|
5180
|
-
|
|
5181
|
-
old_deleted = catalog_set.entries[entry_index].get()->deleted;
|
|
5271
|
+
explicit EntryDropper(EntryIndex &entry_index_p) : entry_index(entry_index_p) {
|
|
5272
|
+
old_deleted = entry_index.GetEntry()->deleted;
|
|
5182
5273
|
}
|
|
5183
5274
|
|
|
5184
5275
|
~EntryDropper() {
|
|
5185
|
-
|
|
5276
|
+
entry_index.GetEntry()->deleted = old_deleted;
|
|
5186
5277
|
}
|
|
5187
5278
|
|
|
5188
5279
|
private:
|
|
5189
|
-
//! The current catalog_set
|
|
5190
|
-
CatalogSet &catalog_set;
|
|
5191
5280
|
//! Keeps track of the state of the entry before starting the delete
|
|
5192
5281
|
bool old_deleted;
|
|
5193
5282
|
//! Index of entry to be deleted
|
|
5194
|
-
|
|
5283
|
+
EntryIndex &entry_index;
|
|
5195
5284
|
};
|
|
5196
5285
|
|
|
5197
5286
|
CatalogSet::CatalogSet(Catalog &catalog, unique_ptr<DefaultGenerator> defaults)
|
|
5198
5287
|
: catalog(catalog), defaults(move(defaults)) {
|
|
5199
5288
|
}
|
|
5289
|
+
CatalogSet::~CatalogSet() {
|
|
5290
|
+
}
|
|
5291
|
+
|
|
5292
|
+
EntryIndex CatalogSet::PutEntry(idx_t entry_index, unique_ptr<CatalogEntry> entry) {
|
|
5293
|
+
if (entries.find(entry_index) != entries.end()) {
|
|
5294
|
+
throw InternalException("Entry with entry index \"%llu\" already exists", entry_index);
|
|
5295
|
+
}
|
|
5296
|
+
entries.insert(make_pair(entry_index, EntryValue(move(entry))));
|
|
5297
|
+
return EntryIndex(*this, entry_index);
|
|
5298
|
+
}
|
|
5299
|
+
|
|
5300
|
+
void CatalogSet::PutEntry(EntryIndex index, unique_ptr<CatalogEntry> catalog_entry) {
|
|
5301
|
+
auto entry = entries.find(index.GetIndex());
|
|
5302
|
+
if (entry == entries.end()) {
|
|
5303
|
+
throw InternalException("Entry with entry index \"%llu\" does not exist", index.GetIndex());
|
|
5304
|
+
}
|
|
5305
|
+
catalog_entry->child = move(entry->second.entry);
|
|
5306
|
+
catalog_entry->child->parent = catalog_entry.get();
|
|
5307
|
+
entry->second.entry = move(catalog_entry);
|
|
5308
|
+
}
|
|
5200
5309
|
|
|
5201
5310
|
bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_ptr<CatalogEntry> value,
|
|
5202
5311
|
unordered_set<CatalogEntry *> &dependencies) {
|
|
@@ -5207,7 +5316,7 @@ bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_
|
|
|
5207
5316
|
unique_lock<mutex> read_lock(catalog_lock);
|
|
5208
5317
|
|
|
5209
5318
|
// first check if the entry exists in the unordered set
|
|
5210
|
-
idx_t
|
|
5319
|
+
idx_t index;
|
|
5211
5320
|
auto mapping_value = GetMapping(context, name);
|
|
5212
5321
|
if (mapping_value == nullptr || mapping_value->deleted) {
|
|
5213
5322
|
// if it does not: entry has never been created
|
|
@@ -5221,17 +5330,17 @@ bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_
|
|
|
5221
5330
|
// first create a dummy deleted entry for this entry
|
|
5222
5331
|
// so transactions started before the commit of this transaction don't
|
|
5223
5332
|
// see it yet
|
|
5224
|
-
entry_index = current_entry++;
|
|
5225
5333
|
auto dummy_node = make_unique<CatalogEntry>(CatalogType::INVALID, value->catalog, name);
|
|
5226
5334
|
dummy_node->timestamp = 0;
|
|
5227
5335
|
dummy_node->deleted = true;
|
|
5228
5336
|
dummy_node->set = this;
|
|
5229
5337
|
|
|
5230
|
-
|
|
5231
|
-
|
|
5338
|
+
auto entry_index = PutEntry(current_entry++, move(dummy_node));
|
|
5339
|
+
index = entry_index.GetIndex();
|
|
5340
|
+
PutMapping(context, name, move(entry_index));
|
|
5232
5341
|
} else {
|
|
5233
|
-
|
|
5234
|
-
auto ¤t = *
|
|
5342
|
+
index = mapping_value->index.GetIndex();
|
|
5343
|
+
auto ¤t = *mapping_value->index.GetEntry();
|
|
5235
5344
|
// if it does, we have to check version numbers
|
|
5236
5345
|
if (HasConflict(context, current.timestamp)) {
|
|
5237
5346
|
// current version has been written to by a currently active
|
|
@@ -5253,16 +5362,16 @@ bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_
|
|
|
5253
5362
|
// now add the dependency set of this object to the dependency manager
|
|
5254
5363
|
catalog.dependency_manager->AddObject(context, value.get(), dependencies);
|
|
5255
5364
|
|
|
5256
|
-
|
|
5257
|
-
|
|
5365
|
+
auto value_ptr = value.get();
|
|
5366
|
+
EntryIndex entry_index(*this, index);
|
|
5367
|
+
PutEntry(move(entry_index), move(value));
|
|
5258
5368
|
// push the old entry in the undo buffer for this transaction
|
|
5259
|
-
transaction.PushCatalogEntry(
|
|
5260
|
-
entries[entry_index] = move(value);
|
|
5369
|
+
transaction.PushCatalogEntry(value_ptr->child.get());
|
|
5261
5370
|
return true;
|
|
5262
5371
|
}
|
|
5263
5372
|
|
|
5264
|
-
bool CatalogSet::GetEntryInternal(ClientContext &context,
|
|
5265
|
-
catalog_entry =
|
|
5373
|
+
bool CatalogSet::GetEntryInternal(ClientContext &context, EntryIndex &entry_index, CatalogEntry *&catalog_entry) {
|
|
5374
|
+
catalog_entry = entry_index.GetEntry().get();
|
|
5266
5375
|
// if it does: we have to retrieve the entry and to check version numbers
|
|
5267
5376
|
if (HasConflict(context, catalog_entry->timestamp)) {
|
|
5268
5377
|
// current version has been written to by a currently active
|
|
@@ -5278,21 +5387,22 @@ bool CatalogSet::GetEntryInternal(ClientContext &context, idx_t entry_index, Cat
|
|
|
5278
5387
|
return true;
|
|
5279
5388
|
}
|
|
5280
5389
|
|
|
5281
|
-
bool CatalogSet::GetEntryInternal(ClientContext &context, const string &name,
|
|
5390
|
+
bool CatalogSet::GetEntryInternal(ClientContext &context, const string &name, EntryIndex *entry_index,
|
|
5282
5391
|
CatalogEntry *&catalog_entry) {
|
|
5283
5392
|
auto mapping_value = GetMapping(context, name);
|
|
5284
5393
|
if (mapping_value == nullptr || mapping_value->deleted) {
|
|
5285
5394
|
// the entry does not exist, check if we can create a default entry
|
|
5286
5395
|
return false;
|
|
5287
5396
|
}
|
|
5288
|
-
entry_index
|
|
5289
|
-
|
|
5397
|
+
if (entry_index) {
|
|
5398
|
+
*entry_index = mapping_value->index.Copy();
|
|
5399
|
+
}
|
|
5400
|
+
return GetEntryInternal(context, mapping_value->index, catalog_entry);
|
|
5290
5401
|
}
|
|
5291
5402
|
|
|
5292
5403
|
bool CatalogSet::AlterOwnership(ClientContext &context, ChangeOwnershipInfo *info) {
|
|
5293
|
-
idx_t entry_index;
|
|
5294
5404
|
CatalogEntry *entry;
|
|
5295
|
-
if (!GetEntryInternal(context, info->name,
|
|
5405
|
+
if (!GetEntryInternal(context, info->name, nullptr, entry)) {
|
|
5296
5406
|
return false;
|
|
5297
5407
|
}
|
|
5298
5408
|
|
|
@@ -5312,9 +5422,9 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf
|
|
|
5312
5422
|
lock_guard<mutex> write_lock(catalog.write_lock);
|
|
5313
5423
|
|
|
5314
5424
|
// first check if the entry exists in the unordered set
|
|
5315
|
-
|
|
5425
|
+
EntryIndex entry_index;
|
|
5316
5426
|
CatalogEntry *entry;
|
|
5317
|
-
if (!GetEntryInternal(context, name, entry_index, entry)) {
|
|
5427
|
+
if (!GetEntryInternal(context, name, &entry_index, entry)) {
|
|
5318
5428
|
return false;
|
|
5319
5429
|
}
|
|
5320
5430
|
if (entry->internal) {
|
|
@@ -5337,7 +5447,7 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf
|
|
|
5337
5447
|
if (value->name != original_name) {
|
|
5338
5448
|
auto mapping_value = GetMapping(context, value->name);
|
|
5339
5449
|
if (mapping_value && !mapping_value->deleted) {
|
|
5340
|
-
auto original_entry = GetEntryForTransaction(context,
|
|
5450
|
+
auto original_entry = GetEntryForTransaction(context, mapping_value->index.GetEntry().get());
|
|
5341
5451
|
if (!original_entry->deleted) {
|
|
5342
5452
|
entry->UndoAlter(context, alter_info);
|
|
5343
5453
|
string rename_err_msg =
|
|
@@ -5349,25 +5459,22 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf
|
|
|
5349
5459
|
|
|
5350
5460
|
if (value->name != original_name) {
|
|
5351
5461
|
// Do PutMapping and DeleteMapping after dependency check
|
|
5352
|
-
PutMapping(context, value->name, entry_index);
|
|
5462
|
+
PutMapping(context, value->name, entry_index.Copy());
|
|
5353
5463
|
DeleteMapping(context, original_name);
|
|
5354
5464
|
}
|
|
5355
5465
|
|
|
5356
5466
|
value->timestamp = transaction.transaction_id;
|
|
5357
|
-
value->child = move(entries[entry_index]);
|
|
5358
|
-
value->child->parent = value.get();
|
|
5359
5467
|
value->set = this;
|
|
5468
|
+
auto new_entry = value.get();
|
|
5469
|
+
PutEntry(move(entry_index), move(value));
|
|
5360
5470
|
|
|
5361
5471
|
// serialize the AlterInfo into a temporary buffer
|
|
5362
5472
|
BufferedSerializer serializer;
|
|
5363
5473
|
alter_info->Serialize(serializer);
|
|
5364
5474
|
BinaryData serialized_alter = serializer.GetData();
|
|
5365
5475
|
|
|
5366
|
-
auto new_entry = value.get();
|
|
5367
|
-
|
|
5368
5476
|
// push the old entry in the undo buffer for this transaction
|
|
5369
|
-
transaction.PushCatalogEntry(
|
|
5370
|
-
entries[entry_index] = move(value);
|
|
5477
|
+
transaction.PushCatalogEntry(new_entry->child.get(), serialized_alter.data.get(), serialized_alter.size);
|
|
5371
5478
|
|
|
5372
5479
|
// Check the dependency manager to verify that there are no conflicting dependencies with this alter
|
|
5373
5480
|
// Note that we do this AFTER the new entry has been entirely set up in the catalog set
|
|
@@ -5378,13 +5485,13 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf
|
|
|
5378
5485
|
return true;
|
|
5379
5486
|
}
|
|
5380
5487
|
|
|
5381
|
-
void CatalogSet::DropEntryDependencies(ClientContext &context,
|
|
5382
|
-
|
|
5488
|
+
void CatalogSet::DropEntryDependencies(ClientContext &context, EntryIndex &entry_index, CatalogEntry &entry,
|
|
5489
|
+
bool cascade) {
|
|
5383
5490
|
// Stores the deleted value of the entry before starting the process
|
|
5384
|
-
EntryDropper dropper(
|
|
5491
|
+
EntryDropper dropper(entry_index);
|
|
5385
5492
|
|
|
5386
5493
|
// To correctly delete the object and its dependencies, it temporarily is set to deleted.
|
|
5387
|
-
|
|
5494
|
+
entry_index.GetEntry()->deleted = true;
|
|
5388
5495
|
|
|
5389
5496
|
// check any dependencies of this object
|
|
5390
5497
|
entry.catalog->dependency_manager->DropObject(context, &entry, cascade);
|
|
@@ -5394,7 +5501,7 @@ void CatalogSet::DropEntryDependencies(ClientContext &context, idx_t entry_index
|
|
|
5394
5501
|
// dropper.~EntryDropper()
|
|
5395
5502
|
}
|
|
5396
5503
|
|
|
5397
|
-
void CatalogSet::DropEntryInternal(ClientContext &context,
|
|
5504
|
+
void CatalogSet::DropEntryInternal(ClientContext &context, EntryIndex entry_index, CatalogEntry &entry, bool cascade) {
|
|
5398
5505
|
auto &transaction = Transaction::GetTransaction(context);
|
|
5399
5506
|
|
|
5400
5507
|
DropEntryDependencies(context, entry_index, entry, cascade);
|
|
@@ -5404,24 +5511,22 @@ void CatalogSet::DropEntryInternal(ClientContext &context, idx_t entry_index, Ca
|
|
|
5404
5511
|
// and point it at the dummy node
|
|
5405
5512
|
auto value = make_unique<CatalogEntry>(CatalogType::DELETED_ENTRY, entry.catalog, entry.name);
|
|
5406
5513
|
value->timestamp = transaction.transaction_id;
|
|
5407
|
-
value->child = move(entries[entry_index]);
|
|
5408
|
-
value->child->parent = value.get();
|
|
5409
5514
|
value->set = this;
|
|
5410
5515
|
value->deleted = true;
|
|
5516
|
+
auto value_ptr = value.get();
|
|
5517
|
+
PutEntry(move(entry_index), move(value));
|
|
5411
5518
|
|
|
5412
5519
|
// push the old entry in the undo buffer for this transaction
|
|
5413
|
-
transaction.PushCatalogEntry(
|
|
5414
|
-
|
|
5415
|
-
entries[entry_index] = move(value);
|
|
5520
|
+
transaction.PushCatalogEntry(value_ptr->child.get());
|
|
5416
5521
|
}
|
|
5417
5522
|
|
|
5418
5523
|
bool CatalogSet::DropEntry(ClientContext &context, const string &name, bool cascade) {
|
|
5419
5524
|
// lock the catalog for writing
|
|
5420
5525
|
lock_guard<mutex> write_lock(catalog.write_lock);
|
|
5421
5526
|
// we can only delete an entry that exists
|
|
5422
|
-
|
|
5527
|
+
EntryIndex entry_index;
|
|
5423
5528
|
CatalogEntry *entry;
|
|
5424
|
-
if (!GetEntryInternal(context, name, entry_index, entry)) {
|
|
5529
|
+
if (!GetEntryInternal(context, name, &entry_index, entry)) {
|
|
5425
5530
|
return false;
|
|
5426
5531
|
}
|
|
5427
5532
|
if (entry->internal) {
|
|
@@ -5429,7 +5534,7 @@ bool CatalogSet::DropEntry(ClientContext &context, const string &name, bool casc
|
|
|
5429
5534
|
}
|
|
5430
5535
|
|
|
5431
5536
|
lock_guard<mutex> read_lock(catalog_lock);
|
|
5432
|
-
DropEntryInternal(context, entry_index, *entry, cascade);
|
|
5537
|
+
DropEntryInternal(context, move(entry_index), *entry, cascade);
|
|
5433
5538
|
return true;
|
|
5434
5539
|
}
|
|
5435
5540
|
|
|
@@ -5447,12 +5552,10 @@ void CatalogSet::CleanupEntry(CatalogEntry *catalog_entry) {
|
|
|
5447
5552
|
if (parent->deleted && !parent->child && !parent->parent) {
|
|
5448
5553
|
auto mapping_entry = mapping.find(parent->name);
|
|
5449
5554
|
D_ASSERT(mapping_entry != mapping.end());
|
|
5450
|
-
auto
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
if (entry->second.get() == parent) {
|
|
5555
|
+
auto entry = mapping_entry->second->index.GetEntry().get();
|
|
5556
|
+
D_ASSERT(entry);
|
|
5557
|
+
if (entry == parent) {
|
|
5454
5558
|
mapping.erase(mapping_entry);
|
|
5455
|
-
entries.erase(entry);
|
|
5456
5559
|
}
|
|
5457
5560
|
}
|
|
5458
5561
|
}
|
|
@@ -5486,9 +5589,9 @@ MappingValue *CatalogSet::GetMapping(ClientContext &context, const string &name,
|
|
|
5486
5589
|
return mapping_value;
|
|
5487
5590
|
}
|
|
5488
5591
|
|
|
5489
|
-
void CatalogSet::PutMapping(ClientContext &context, const string &name,
|
|
5592
|
+
void CatalogSet::PutMapping(ClientContext &context, const string &name, EntryIndex entry_index) {
|
|
5490
5593
|
auto entry = mapping.find(name);
|
|
5491
|
-
auto new_value = make_unique<MappingValue>(entry_index);
|
|
5594
|
+
auto new_value = make_unique<MappingValue>(move(entry_index));
|
|
5492
5595
|
new_value->timestamp = Transaction::GetTransaction(context).transaction_id;
|
|
5493
5596
|
if (entry != mapping.end()) {
|
|
5494
5597
|
if (HasConflict(context, entry->second->timestamp)) {
|
|
@@ -5503,7 +5606,7 @@ void CatalogSet::PutMapping(ClientContext &context, const string &name, idx_t en
|
|
|
5503
5606
|
void CatalogSet::DeleteMapping(ClientContext &context, const string &name) {
|
|
5504
5607
|
auto entry = mapping.find(name);
|
|
5505
5608
|
D_ASSERT(entry != mapping.end());
|
|
5506
|
-
auto delete_marker = make_unique<MappingValue>(entry->second->index);
|
|
5609
|
+
auto delete_marker = make_unique<MappingValue>(entry->second->index.Copy());
|
|
5507
5610
|
delete_marker->deleted = true;
|
|
5508
5611
|
delete_marker->timestamp = Transaction::GetTransaction(context).transaction_id;
|
|
5509
5612
|
delete_marker->child = move(entry->second);
|
|
@@ -5571,15 +5674,14 @@ CatalogEntry *CatalogSet::CreateEntryInternal(ClientContext &context, unique_ptr
|
|
|
5571
5674
|
return nullptr;
|
|
5572
5675
|
}
|
|
5573
5676
|
auto &name = entry->name;
|
|
5574
|
-
auto entry_index = current_entry++;
|
|
5575
5677
|
auto catalog_entry = entry.get();
|
|
5576
5678
|
|
|
5577
5679
|
entry->set = this;
|
|
5578
5680
|
entry->timestamp = 0;
|
|
5579
5681
|
|
|
5580
|
-
|
|
5682
|
+
auto entry_index = PutEntry(current_entry++, move(entry));
|
|
5683
|
+
PutMapping(context, name, move(entry_index));
|
|
5581
5684
|
mapping[name]->timestamp = 0;
|
|
5582
|
-
entries[entry_index] = move(entry);
|
|
5583
5685
|
return catalog_entry;
|
|
5584
5686
|
}
|
|
5585
5687
|
|
|
@@ -5618,7 +5720,7 @@ CatalogEntry *CatalogSet::GetEntry(ClientContext &context, const string &name) {
|
|
|
5618
5720
|
// we found an entry for this name
|
|
5619
5721
|
// check the version numbers
|
|
5620
5722
|
|
|
5621
|
-
auto catalog_entry =
|
|
5723
|
+
auto catalog_entry = mapping_value->index.GetEntry().get();
|
|
5622
5724
|
CatalogEntry *current = GetEntryForTransaction(context, catalog_entry);
|
|
5623
5725
|
if (current->deleted || (current->name != name && !UseTimestamp(context, mapping_value->timestamp))) {
|
|
5624
5726
|
return nullptr;
|
|
@@ -5727,7 +5829,7 @@ void CatalogSet::Undo(CatalogEntry *entry) {
|
|
|
5727
5829
|
// otherwise we need to update the base entry tables
|
|
5728
5830
|
auto &name = entry->name;
|
|
5729
5831
|
to_be_removed_node->child->SetAsRoot();
|
|
5730
|
-
|
|
5832
|
+
mapping[name]->index.GetEntry() = move(to_be_removed_node->child);
|
|
5731
5833
|
entry->parent = nullptr;
|
|
5732
5834
|
}
|
|
5733
5835
|
|
|
@@ -5742,7 +5844,7 @@ void CatalogSet::Undo(CatalogEntry *entry) {
|
|
|
5742
5844
|
}
|
|
5743
5845
|
}
|
|
5744
5846
|
// we mark the catalog as being modified, since this action can lead to e.g. tables being dropped
|
|
5745
|
-
|
|
5847
|
+
catalog.ModifyCatalog();
|
|
5746
5848
|
}
|
|
5747
5849
|
|
|
5748
5850
|
void CatalogSet::CreateDefaultEntries(ClientContext &context, unique_lock<mutex> &lock) {
|
|
@@ -5775,7 +5877,7 @@ void CatalogSet::Scan(ClientContext &context, const std::function<void(CatalogEn
|
|
|
5775
5877
|
CreateDefaultEntries(context, lock);
|
|
5776
5878
|
|
|
5777
5879
|
for (auto &kv : entries) {
|
|
5778
|
-
auto entry = kv.second.get();
|
|
5880
|
+
auto entry = kv.second.entry.get();
|
|
5779
5881
|
entry = GetEntryForTransaction(context, entry);
|
|
5780
5882
|
if (!entry->deleted) {
|
|
5781
5883
|
callback(entry);
|
|
@@ -5787,7 +5889,7 @@ void CatalogSet::Scan(const std::function<void(CatalogEntry *)> &callback) {
|
|
|
5787
5889
|
// lock the catalog set
|
|
5788
5890
|
lock_guard<mutex> lock(catalog_lock);
|
|
5789
5891
|
for (auto &kv : entries) {
|
|
5790
|
-
auto entry = kv.second.get();
|
|
5892
|
+
auto entry = kv.second.entry.get();
|
|
5791
5893
|
entry = GetCommittedEntry(entry);
|
|
5792
5894
|
if (!entry->deleted) {
|
|
5793
5895
|
callback(entry);
|
|
@@ -6280,6 +6382,7 @@ vector<string> DefaultViewGenerator::GetDefaultEntries() {
|
|
|
6280
6382
|
|
|
6281
6383
|
|
|
6282
6384
|
|
|
6385
|
+
|
|
6283
6386
|
namespace duckdb {
|
|
6284
6387
|
|
|
6285
6388
|
DependencyManager::DependencyManager(Catalog &catalog) : catalog(catalog) {
|
|
@@ -6289,12 +6392,11 @@ void DependencyManager::AddObject(ClientContext &context, CatalogEntry *object,
|
|
|
6289
6392
|
unordered_set<CatalogEntry *> &dependencies) {
|
|
6290
6393
|
// check for each object in the sources if they were not deleted yet
|
|
6291
6394
|
for (auto &dependency : dependencies) {
|
|
6292
|
-
idx_t entry_index;
|
|
6293
6395
|
CatalogEntry *catalog_entry;
|
|
6294
6396
|
if (!dependency->set) {
|
|
6295
6397
|
throw InternalException("Dependency has no set");
|
|
6296
6398
|
}
|
|
6297
|
-
if (!dependency->set->GetEntryInternal(context, dependency->name,
|
|
6399
|
+
if (!dependency->set->GetEntryInternal(context, dependency->name, nullptr, catalog_entry)) {
|
|
6298
6400
|
throw InternalException("Dependency has already been deleted?");
|
|
6299
6401
|
}
|
|
6300
6402
|
}
|
|
@@ -6322,10 +6424,9 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object,
|
|
|
6322
6424
|
if (mapping_value == nullptr) {
|
|
6323
6425
|
continue;
|
|
6324
6426
|
}
|
|
6325
|
-
idx_t entry_index = mapping_value->index;
|
|
6326
6427
|
CatalogEntry *dependency_entry;
|
|
6327
6428
|
|
|
6328
|
-
if (!catalog_set.GetEntryInternal(context,
|
|
6429
|
+
if (!catalog_set.GetEntryInternal(context, mapping_value->index, dependency_entry)) {
|
|
6329
6430
|
// the dependent object was already deleted, no conflict
|
|
6330
6431
|
continue;
|
|
6331
6432
|
}
|
|
@@ -6333,7 +6434,7 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object,
|
|
|
6333
6434
|
if (cascade || dep.dependency_type == DependencyType::DEPENDENCY_AUTOMATIC ||
|
|
6334
6435
|
dep.dependency_type == DependencyType::DEPENDENCY_OWNS) {
|
|
6335
6436
|
// cascade: drop the dependent object
|
|
6336
|
-
catalog_set.DropEntryInternal(context,
|
|
6437
|
+
catalog_set.DropEntryInternal(context, mapping_value->index.Copy(), *dependency_entry, cascade);
|
|
6337
6438
|
} else {
|
|
6338
6439
|
// no cascade and there are objects that depend on this object: throw error
|
|
6339
6440
|
throw DependencyException("Cannot drop entry \"%s\" because there are entries that "
|
|
@@ -6353,9 +6454,8 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob
|
|
|
6353
6454
|
for (auto &dep : dependent_objects) {
|
|
6354
6455
|
// look up the entry in the catalog set
|
|
6355
6456
|
auto &catalog_set = *dep.entry->set;
|
|
6356
|
-
idx_t entry_index;
|
|
6357
6457
|
CatalogEntry *dependency_entry;
|
|
6358
|
-
if (!catalog_set.GetEntryInternal(context, dep.entry->name,
|
|
6458
|
+
if (!catalog_set.GetEntryInternal(context, dep.entry->name, nullptr, dependency_entry)) {
|
|
6359
6459
|
// the dependent object was already deleted, no conflict
|
|
6360
6460
|
continue;
|
|
6361
6461
|
}
|
|
@@ -87775,6 +87875,7 @@ protected:
|
|
|
87775
87875
|
|
|
87776
87876
|
|
|
87777
87877
|
|
|
87878
|
+
|
|
87778
87879
|
namespace duckdb {
|
|
87779
87880
|
|
|
87780
87881
|
unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateTable &op) {
|
|
@@ -87788,13 +87889,14 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateTabl
|
|
|
87788
87889
|
|
|
87789
87890
|
bool parallel_streaming_insert = !PreserveInsertionOrder(*plan);
|
|
87790
87891
|
bool use_batch_index = UseBatchIndex(*plan);
|
|
87892
|
+
auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads();
|
|
87791
87893
|
unique_ptr<PhysicalOperator> create;
|
|
87792
87894
|
if (!parallel_streaming_insert && use_batch_index) {
|
|
87793
87895
|
create = make_unique<PhysicalBatchInsert>(op, op.schema, move(op.info), op.estimated_cardinality);
|
|
87794
87896
|
|
|
87795
87897
|
} else {
|
|
87796
87898
|
create = make_unique<PhysicalInsert>(op, op.schema, move(op.info), op.estimated_cardinality,
|
|
87797
|
-
parallel_streaming_insert);
|
|
87899
|
+
parallel_streaming_insert && num_threads > 1);
|
|
87798
87900
|
}
|
|
87799
87901
|
|
|
87800
87902
|
D_ASSERT(op.children.size() == 1);
|
|
@@ -89357,6 +89459,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalInsert &op
|
|
|
89357
89459
|
|
|
89358
89460
|
bool parallel_streaming_insert = !PreserveInsertionOrder(*plan);
|
|
89359
89461
|
bool use_batch_index = UseBatchIndex(*plan);
|
|
89462
|
+
auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads();
|
|
89360
89463
|
if (op.return_chunk) {
|
|
89361
89464
|
// not supported for RETURNING (yet?)
|
|
89362
89465
|
parallel_streaming_insert = false;
|
|
@@ -89368,7 +89471,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalInsert &op
|
|
|
89368
89471
|
op.estimated_cardinality);
|
|
89369
89472
|
} else {
|
|
89370
89473
|
insert = make_unique<PhysicalInsert>(op.types, op.table, op.column_index_map, move(op.bound_defaults),
|
|
89371
|
-
op.estimated_cardinality, op.return_chunk,
|
|
89474
|
+
op.estimated_cardinality, op.return_chunk,
|
|
89475
|
+
parallel_streaming_insert && num_threads > 1);
|
|
89372
89476
|
}
|
|
89373
89477
|
if (plan) {
|
|
89374
89478
|
insert->children.push_back(move(plan));
|
|
@@ -137286,6 +137390,14 @@ struct MaximumMemorySetting {
|
|
|
137286
137390
|
static Value GetSetting(ClientContext &context);
|
|
137287
137391
|
};
|
|
137288
137392
|
|
|
137393
|
+
struct PasswordSetting {
|
|
137394
|
+
static constexpr const char *Name = "password";
|
|
137395
|
+
static constexpr const char *Description = "The password to use. Ignored for legacy compatibility.";
|
|
137396
|
+
static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR;
|
|
137397
|
+
static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter);
|
|
137398
|
+
static Value GetSetting(ClientContext &context);
|
|
137399
|
+
};
|
|
137400
|
+
|
|
137289
137401
|
struct PerfectHashThresholdSetting {
|
|
137290
137402
|
static constexpr const char *Name = "perfect_ht_threshold";
|
|
137291
137403
|
static constexpr const char *Description = "Threshold in bytes for when to use a perfect hash table (default: 12)";
|
|
@@ -137381,6 +137493,14 @@ struct ThreadsSetting {
|
|
|
137381
137493
|
static Value GetSetting(ClientContext &context);
|
|
137382
137494
|
};
|
|
137383
137495
|
|
|
137496
|
+
struct UsernameSetting {
|
|
137497
|
+
static constexpr const char *Name = "username";
|
|
137498
|
+
static constexpr const char *Description = "The username to use. Ignored for legacy compatibility.";
|
|
137499
|
+
static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR;
|
|
137500
|
+
static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter);
|
|
137501
|
+
static Value GetSetting(ClientContext &context);
|
|
137502
|
+
};
|
|
137503
|
+
|
|
137384
137504
|
} // namespace duckdb
|
|
137385
137505
|
|
|
137386
137506
|
|
|
@@ -137430,6 +137550,7 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
|
|
|
137430
137550
|
DUCKDB_GLOBAL(MaximumMemorySetting),
|
|
137431
137551
|
DUCKDB_GLOBAL_ALIAS("memory_limit", MaximumMemorySetting),
|
|
137432
137552
|
DUCKDB_GLOBAL_ALIAS("null_order", DefaultNullOrderSetting),
|
|
137553
|
+
DUCKDB_GLOBAL(PasswordSetting),
|
|
137433
137554
|
DUCKDB_LOCAL(PerfectHashThresholdSetting),
|
|
137434
137555
|
DUCKDB_LOCAL(PreserveIdentifierCase),
|
|
137435
137556
|
DUCKDB_GLOBAL(PreserveInsertionOrder),
|
|
@@ -137442,6 +137563,8 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
|
|
|
137442
137563
|
DUCKDB_LOCAL(SearchPathSetting),
|
|
137443
137564
|
DUCKDB_GLOBAL(TempDirectorySetting),
|
|
137444
137565
|
DUCKDB_GLOBAL(ThreadsSetting),
|
|
137566
|
+
DUCKDB_GLOBAL(UsernameSetting),
|
|
137567
|
+
DUCKDB_GLOBAL_ALIAS("user", UsernameSetting),
|
|
137445
137568
|
DUCKDB_GLOBAL_ALIAS("wal_autocheckpoint", CheckpointThresholdSetting),
|
|
137446
137569
|
DUCKDB_GLOBAL_ALIAS("worker_threads", ThreadsSetting),
|
|
137447
137570
|
FINAL_SETTING};
|
|
@@ -151905,6 +152028,17 @@ Value MaximumMemorySetting::GetSetting(ClientContext &context) {
|
|
|
151905
152028
|
return Value(StringUtil::BytesToHumanReadableString(config.options.maximum_memory));
|
|
151906
152029
|
}
|
|
151907
152030
|
|
|
152031
|
+
//===--------------------------------------------------------------------===//
|
|
152032
|
+
// Password Setting
|
|
152033
|
+
//===--------------------------------------------------------------------===//
|
|
152034
|
+
void PasswordSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
|
|
152035
|
+
// nop
|
|
152036
|
+
}
|
|
152037
|
+
|
|
152038
|
+
Value PasswordSetting::GetSetting(ClientContext &context) {
|
|
152039
|
+
return Value();
|
|
152040
|
+
}
|
|
152041
|
+
|
|
151908
152042
|
//===--------------------------------------------------------------------===//
|
|
151909
152043
|
// Perfect Hash Threshold
|
|
151910
152044
|
//===--------------------------------------------------------------------===//
|
|
@@ -152071,6 +152205,17 @@ Value ThreadsSetting::GetSetting(ClientContext &context) {
|
|
|
152071
152205
|
return Value::BIGINT(config.options.maximum_threads);
|
|
152072
152206
|
}
|
|
152073
152207
|
|
|
152208
|
+
//===--------------------------------------------------------------------===//
|
|
152209
|
+
// Username Setting
|
|
152210
|
+
//===--------------------------------------------------------------------===//
|
|
152211
|
+
void UsernameSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
|
|
152212
|
+
// nop
|
|
152213
|
+
}
|
|
152214
|
+
|
|
152215
|
+
Value UsernameSetting::GetSetting(ClientContext &context) {
|
|
152216
|
+
return Value();
|
|
152217
|
+
}
|
|
152218
|
+
|
|
152074
152219
|
} // namespace duckdb
|
|
152075
152220
|
|
|
152076
152221
|
|
|
@@ -202320,6 +202465,7 @@ BlockHandle::~BlockHandle() {
|
|
|
202320
202465
|
} else {
|
|
202321
202466
|
D_ASSERT(memory_charge.size == 0);
|
|
202322
202467
|
}
|
|
202468
|
+
buffer_manager.PurgeQueue();
|
|
202323
202469
|
block_manager.UnregisterBlock(block_id, can_destroy);
|
|
202324
202470
|
}
|
|
202325
202471
|
|
|
@@ -215428,6 +215574,7 @@ block_id_t SingleFileBlockManager::GetFreeBlockId() {
|
|
|
215428
215574
|
void SingleFileBlockManager::MarkBlockAsFree(block_id_t block_id) {
|
|
215429
215575
|
lock_guard<mutex> lock(block_lock);
|
|
215430
215576
|
D_ASSERT(block_id >= 0);
|
|
215577
|
+
D_ASSERT(block_id < max_block);
|
|
215431
215578
|
D_ASSERT(free_list.find(block_id) == free_list.end());
|
|
215432
215579
|
multi_use_blocks.erase(block_id);
|
|
215433
215580
|
free_list.insert(block_id);
|
|
@@ -215436,6 +215583,7 @@ void SingleFileBlockManager::MarkBlockAsFree(block_id_t block_id) {
|
|
|
215436
215583
|
void SingleFileBlockManager::MarkBlockAsModified(block_id_t block_id) {
|
|
215437
215584
|
lock_guard<mutex> lock(block_lock);
|
|
215438
215585
|
D_ASSERT(block_id >= 0);
|
|
215586
|
+
D_ASSERT(block_id < max_block);
|
|
215439
215587
|
|
|
215440
215588
|
// check if the block is a multi-use block
|
|
215441
215589
|
auto entry = multi_use_blocks.find(block_id);
|
|
@@ -215458,6 +215606,8 @@ void SingleFileBlockManager::MarkBlockAsModified(block_id_t block_id) {
|
|
|
215458
215606
|
|
|
215459
215607
|
void SingleFileBlockManager::IncreaseBlockReferenceCount(block_id_t block_id) {
|
|
215460
215608
|
lock_guard<mutex> lock(block_lock);
|
|
215609
|
+
D_ASSERT(block_id >= 0);
|
|
215610
|
+
D_ASSERT(block_id < max_block);
|
|
215461
215611
|
D_ASSERT(free_list.find(block_id) == free_list.end());
|
|
215462
215612
|
auto entry = multi_use_blocks.find(block_id);
|
|
215463
215613
|
if (entry != multi_use_blocks.end()) {
|
|
@@ -218539,7 +218689,7 @@ unique_ptr<ColumnSegment> ColumnSegment::CreatePersistentSegment(DatabaseInstanc
|
|
|
218539
218689
|
block = block_manager.RegisterBlock(block_id);
|
|
218540
218690
|
}
|
|
218541
218691
|
auto segment_size = Storage::BLOCK_SIZE;
|
|
218542
|
-
return make_unique<ColumnSegment>(db, block, type, ColumnSegmentType::PERSISTENT, start, count, function,
|
|
218692
|
+
return make_unique<ColumnSegment>(db, move(block), type, ColumnSegmentType::PERSISTENT, start, count, function,
|
|
218543
218693
|
move(statistics), block_id, offset, segment_size);
|
|
218544
218694
|
}
|
|
218545
218695
|
|
|
@@ -218555,7 +218705,7 @@ unique_ptr<ColumnSegment> ColumnSegment::CreateTransientSegment(DatabaseInstance
|
|
|
218555
218705
|
} else {
|
|
218556
218706
|
buffer_manager.Allocate(segment_size, false, &block);
|
|
218557
218707
|
}
|
|
218558
|
-
return make_unique<ColumnSegment>(db, block, type, ColumnSegmentType::TRANSIENT, start, 0, function, nullptr,
|
|
218708
|
+
return make_unique<ColumnSegment>(db, move(block), type, ColumnSegmentType::TRANSIENT, start, 0, function, nullptr,
|
|
218559
218709
|
INVALID_BLOCK, 0, segment_size);
|
|
218560
218710
|
}
|
|
218561
218711
|
|