duckdb 0.6.1-dev86.0 → 0.6.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/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 "0c8bafb821"
15
- #define DUCKDB_VERSION "v0.6.1-dev86"
14
+ #define DUCKDB_SOURCE_ID "919cad22e8"
15
+ #define DUCKDB_VERSION "v0.6.1"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -4351,6 +4351,7 @@ void DestroyObject(T *ptr) {
4351
4351
  //! As such this class should be used primarily for larger allocations.
4352
4352
  struct BufferAllocator {
4353
4353
  DUCKDB_API static Allocator &Get(ClientContext &context);
4354
+ DUCKDB_API static Allocator &Get(DatabaseInstance &db);
4354
4355
  };
4355
4356
 
4356
4357
  } // namespace duckdb
@@ -4404,7 +4405,7 @@ namespace duckdb {
4404
4405
  //! returned pointer will remain valid until the StringHeap is destroyed
4405
4406
  class StringHeap {
4406
4407
  public:
4407
- StringHeap();
4408
+ StringHeap(Allocator &allocator = Allocator::DefaultAllocator());
4408
4409
 
4409
4410
  void Destroy();
4410
4411
  void Move(StringHeap &other);
@@ -9171,6 +9172,7 @@ public:
9171
9172
 
9172
9173
  public:
9173
9174
  virtual unique_ptr<CatalogEntry> AlterEntry(ClientContext &context, AlterInfo *info);
9175
+ virtual void UndoAlter(ClientContext &context, AlterInfo *info);
9174
9176
 
9175
9177
  virtual unique_ptr<CatalogEntry> Copy(ClientContext &context);
9176
9178
 
@@ -11162,6 +11164,8 @@ public:
11162
11164
  public:
11163
11165
  bool HasGeneratedColumns() const;
11164
11166
  unique_ptr<CatalogEntry> AlterEntry(ClientContext &context, AlterInfo *info) override;
11167
+ void UndoAlter(ClientContext &context, AlterInfo *info) override;
11168
+
11165
11169
  //! Returns whether or not a column with the given name exists
11166
11170
  DUCKDB_API bool ColumnExists(const string &name);
11167
11171
  //! Returns a reference to the column of the specified name. Throws an
@@ -11340,6 +11344,9 @@ public:
11340
11344
  return true;
11341
11345
  }
11342
11346
 
11347
+ //! Returns the set of table indexes of this operator
11348
+ virtual vector<idx_t> GetTableIndex() const;
11349
+
11343
11350
  protected:
11344
11351
  //! Resolve types for this specific operator
11345
11352
  virtual void ResolveTypes() = 0;
@@ -14190,6 +14197,9 @@ public:
14190
14197
  void Reset();
14191
14198
  void ResetSink();
14192
14199
  void ResetSource(bool force);
14200
+ void ClearSource() {
14201
+ source_state.reset();
14202
+ }
14193
14203
  void Schedule(shared_ptr<Event> &event);
14194
14204
 
14195
14205
  //! Finalize this pipeline
@@ -15527,27 +15537,46 @@ namespace duckdb {
15527
15537
  struct AlterInfo;
15528
15538
 
15529
15539
  class ClientContext;
15540
+ struct MappingValue;
15541
+ struct EntryIndex;
15530
15542
 
15531
15543
  typedef unordered_map<CatalogSet *, unique_lock<mutex>> set_lock_map_t;
15532
15544
 
15533
- struct MappingValue {
15534
- explicit MappingValue(idx_t index_) : index(index_), timestamp(0), deleted(false), parent(nullptr) {
15545
+ struct EntryValue {
15546
+ EntryValue() {
15547
+ throw InternalException("EntryValue called without a catalog entry");
15535
15548
  }
15536
15549
 
15537
- idx_t index;
15538
- transaction_t timestamp;
15539
- bool deleted;
15540
- unique_ptr<MappingValue> child;
15541
- MappingValue *parent;
15550
+ explicit EntryValue(unique_ptr<CatalogEntry> entry_p) : entry(move(entry_p)), reference_count(0) {
15551
+ }
15552
+ //! enable move constructors
15553
+ EntryValue(EntryValue &&other) noexcept {
15554
+ Swap(other);
15555
+ }
15556
+ EntryValue &operator=(EntryValue &&other) noexcept {
15557
+ Swap(other);
15558
+ return *this;
15559
+ }
15560
+ void Swap(EntryValue &other) {
15561
+ std::swap(entry, other.entry);
15562
+ idx_t count = reference_count;
15563
+ reference_count = other.reference_count.load();
15564
+ other.reference_count = count;
15565
+ }
15566
+
15567
+ unique_ptr<CatalogEntry> entry;
15568
+ atomic<idx_t> reference_count;
15542
15569
  };
15543
15570
 
15544
15571
  //! The Catalog Set stores (key, value) map of a set of CatalogEntries
15545
15572
  class CatalogSet {
15546
15573
  friend class DependencyManager;
15547
15574
  friend class EntryDropper;
15575
+ friend struct EntryIndex;
15548
15576
 
15549
15577
  public:
15550
15578
  DUCKDB_API explicit CatalogSet(Catalog &catalog, unique_ptr<DefaultGenerator> defaults = nullptr);
15579
+ ~CatalogSet();
15551
15580
 
15552
15581
  //! Create an entry in the catalog set. Returns whether or not it was
15553
15582
  //! successful.
@@ -15588,7 +15617,6 @@ public:
15588
15617
  DUCKDB_API static bool HasConflict(ClientContext &context, transaction_t timestamp);
15589
15618
  DUCKDB_API static bool UseTimestamp(ClientContext &context, transaction_t timestamp);
15590
15619
 
15591
- CatalogEntry *GetEntryFromIndex(idx_t index);
15592
15620
  void UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp);
15593
15621
 
15594
15622
  private:
@@ -15601,29 +15629,32 @@ private:
15601
15629
  //! Given a root entry, gets the entry valid for this transaction
15602
15630
  CatalogEntry *GetEntryForTransaction(ClientContext &context, CatalogEntry *current);
15603
15631
  CatalogEntry *GetCommittedEntry(CatalogEntry *current);
15604
- bool GetEntryInternal(ClientContext &context, const string &name, idx_t &entry_index, CatalogEntry *&entry);
15605
- bool GetEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry *&entry);
15632
+ bool GetEntryInternal(ClientContext &context, const string &name, EntryIndex *entry_index, CatalogEntry *&entry);
15633
+ bool GetEntryInternal(ClientContext &context, EntryIndex &entry_index, CatalogEntry *&entry);
15606
15634
  //! Drops an entry from the catalog set; must hold the catalog_lock to safely call this
15607
- void DropEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade);
15635
+ void DropEntryInternal(ClientContext &context, EntryIndex entry_index, CatalogEntry &entry, bool cascade);
15608
15636
  CatalogEntry *CreateEntryInternal(ClientContext &context, unique_ptr<CatalogEntry> entry);
15609
15637
  MappingValue *GetMapping(ClientContext &context, const string &name, bool get_latest = false);
15610
- void PutMapping(ClientContext &context, const string &name, idx_t entry_index);
15638
+ void PutMapping(ClientContext &context, const string &name, EntryIndex entry_index);
15611
15639
  void DeleteMapping(ClientContext &context, const string &name);
15612
- void DropEntryDependencies(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade);
15640
+ void DropEntryDependencies(ClientContext &context, EntryIndex &entry_index, CatalogEntry &entry, bool cascade);
15613
15641
 
15614
15642
  //! Create all default entries
15615
15643
  void CreateDefaultEntries(ClientContext &context, unique_lock<mutex> &lock);
15616
15644
  //! Attempt to create a default entry with the specified name. Returns the entry if successful, nullptr otherwise.
15617
15645
  CatalogEntry *CreateDefaultEntry(ClientContext &context, const string &name, unique_lock<mutex> &lock);
15618
15646
 
15647
+ EntryIndex PutEntry(idx_t entry_index, unique_ptr<CatalogEntry> entry);
15648
+ void PutEntry(EntryIndex index, unique_ptr<CatalogEntry> entry);
15649
+
15619
15650
  private:
15620
15651
  Catalog &catalog;
15621
15652
  //! The catalog lock is used to make changes to the data
15622
15653
  mutex catalog_lock;
15654
+ //! The set of catalog entries
15655
+ unordered_map<idx_t, EntryValue> entries;
15623
15656
  //! Mapping of string to catalog entry
15624
15657
  case_insensitive_map_t<unique_ptr<MappingValue>> mapping;
15625
- //! The set of catalog entries
15626
- unordered_map<idx_t, unique_ptr<CatalogEntry>> entries;
15627
15658
  //! The current catalog entry index
15628
15659
  idx_t current_entry = 0;
15629
15660
  //! The generator used to generate default internal entries
@@ -18911,6 +18942,9 @@ struct OperatorExtensionInfo {
18911
18942
  typedef BoundStatement (*bind_function_t)(ClientContext &context, Binder &binder, OperatorExtensionInfo *info,
18912
18943
  SQLStatement &statement);
18913
18944
 
18945
+ // forward declaration to avoid circular reference
18946
+ struct LogicalExtensionOperator;
18947
+
18914
18948
  class OperatorExtension {
18915
18949
  public:
18916
18950
  bind_function_t Bind;
@@ -18918,6 +18952,10 @@ public:
18918
18952
  //! Additional info passed to the CreatePlan & Bind functions
18919
18953
  shared_ptr<OperatorExtensionInfo> operator_info;
18920
18954
 
18955
+ virtual std::string GetName() = 0;
18956
+ virtual std::unique_ptr<LogicalExtensionOperator> Deserialize(LogicalDeserializationState &state,
18957
+ FieldReader &reader) = 0;
18958
+
18921
18959
  DUCKDB_API virtual ~OperatorExtension() {
18922
18960
  }
18923
18961
  };
@@ -19063,7 +19101,7 @@ public:
19063
19101
  //! A reference to the (shared) default allocator (Allocator::DefaultAllocator)
19064
19102
  shared_ptr<Allocator> default_allocator;
19065
19103
  //! Extensions made to binder
19066
- vector<OperatorExtension> operator_extensions;
19104
+ vector<std::unique_ptr<OperatorExtension>> operator_extensions;
19067
19105
 
19068
19106
  public:
19069
19107
  DUCKDB_API static DBConfig &GetConfig(ClientContext &context);
@@ -25993,6 +26031,7 @@ struct SBIterator {
25993
26031
 
25994
26032
 
25995
26033
 
26034
+
25996
26035
  //===----------------------------------------------------------------------===//
25997
26036
  // DuckDB
25998
26037
  //
@@ -26164,6 +26203,10 @@ public:
26164
26203
  can_destroy = can_destroy_p;
26165
26204
  }
26166
26205
 
26206
+ inline const idx_t &GetMemoryUsage() const {
26207
+ return memory_usage;
26208
+ }
26209
+
26167
26210
  private:
26168
26211
  static BufferHandle Load(shared_ptr<BlockHandle> &handle, unique_ptr<FileBuffer> buffer = nullptr);
26169
26212
  unique_ptr<FileBuffer> UnloadAndTakeBlock();
@@ -26197,7 +26240,6 @@ private:
26197
26240
 
26198
26241
 
26199
26242
 
26200
-
26201
26243
  namespace duckdb {
26202
26244
  class BlockManager;
26203
26245
  class DatabaseInstance;
@@ -26218,10 +26260,6 @@ public:
26218
26260
  BufferManager(DatabaseInstance &db, string temp_directory, idx_t maximum_memory);
26219
26261
  virtual ~BufferManager();
26220
26262
 
26221
- //! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or
26222
- //! not the buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so
26223
- //! it can be reloaded. The resulting buffer will already be allocated, but needs to be pinned in order to be used.
26224
- shared_ptr<BlockHandle> RegisterMemory(idx_t block_size, bool can_destroy);
26225
26263
  //! Registers an in-memory buffer that cannot be unloaded until it is destroyed
26226
26264
  //! This buffer can be small (smaller than BLOCK_SIZE)
26227
26265
  //! Unpin and pin are nops on this block of memory
@@ -26229,7 +26267,8 @@ public:
26229
26267
 
26230
26268
  //! Allocate an in-memory buffer with a single pin.
26231
26269
  //! The allocated memory is released when the buffer handle is destroyed.
26232
- DUCKDB_API BufferHandle Allocate(idx_t block_size);
26270
+ DUCKDB_API BufferHandle Allocate(idx_t block_size, bool can_destroy = true,
26271
+ shared_ptr<BlockHandle> *block = nullptr);
26233
26272
 
26234
26273
  //! Reallocate an in-memory buffer that is pinned.
26235
26274
  void ReAllocate(shared_ptr<BlockHandle> &handle, idx_t block_size);
@@ -26263,6 +26302,10 @@ public:
26263
26302
  return db;
26264
26303
  }
26265
26304
 
26305
+ static idx_t GetAllocSize(idx_t block_size) {
26306
+ return AlignValue<idx_t, Storage::SECTOR_SIZE>(block_size + Storage::BLOCK_HEADER_SIZE);
26307
+ }
26308
+
26266
26309
  //! Construct a managed buffer.
26267
26310
  //! The block_id is just used for internal tracking. It doesn't map to any actual
26268
26311
  //! BlockManager.
@@ -26273,6 +26316,12 @@ public:
26273
26316
  DUCKDB_API void FreeReservedMemory(idx_t size);
26274
26317
 
26275
26318
  private:
26319
+ //! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or
26320
+ //! not the buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so
26321
+ //! it can be reloaded. The resulting buffer will already be allocated, but needs to be pinned in order to be used.
26322
+ //! This needs to be private to prevent creating blocks without ever pinning them:
26323
+ //! blocks that are never pinned are never added to the eviction queue
26324
+ shared_ptr<BlockHandle> RegisterMemory(idx_t block_size, bool can_destroy);
26276
26325
  //! Evict blocks until the currently used memory + extra_memory fit, returns false if this was not possible
26277
26326
  //! (i.e. not enough blocks could be evicted)
26278
26327
  //! If the "buffer" argument is specified AND the system can find a buffer to re-use for the given allocation size
@@ -26354,7 +26403,8 @@ public:
26354
26403
  RowDataBlock(BufferManager &buffer_manager, idx_t capacity, idx_t entry_size)
26355
26404
  : capacity(capacity), entry_size(entry_size), count(0), byte_offset(0) {
26356
26405
  idx_t size = MaxValue<idx_t>(Storage::BLOCK_SIZE, capacity * entry_size);
26357
- block = buffer_manager.RegisterMemory(size, false);
26406
+ buffer_manager.Allocate(size, false, &block);
26407
+ D_ASSERT(BufferManager::GetAllocSize(size) == block->GetMemoryUsage());
26358
26408
  }
26359
26409
  explicit RowDataBlock(idx_t entry_size) : entry_size(entry_size) {
26360
26410
  }
@@ -26428,17 +26478,23 @@ public:
26428
26478
  count = 0;
26429
26479
  }
26430
26480
 
26431
- //! The size (in bytes) of this RowDataCollection if it were stored in a single block
26481
+ //! The size (in bytes) of this RowDataCollection
26432
26482
  idx_t SizeInBytes() const {
26433
- idx_t bytes = 0;
26434
- if (entry_size == 1) {
26435
- for (auto &block : blocks) {
26436
- bytes += block->byte_offset;
26437
- }
26438
- } else {
26439
- bytes = count * entry_size;
26483
+ VerifyBlockSizes();
26484
+ idx_t size = 0;
26485
+ for (auto &block : blocks) {
26486
+ size += block->block->GetMemoryUsage();
26440
26487
  }
26441
- return bytes;
26488
+ return size;
26489
+ }
26490
+
26491
+ //! Verifies that the block sizes are correct (Debug only)
26492
+ void VerifyBlockSizes() const {
26493
+ #ifdef DEBUG
26494
+ for (auto &block : blocks) {
26495
+ D_ASSERT(block->block->GetMemoryUsage() == BufferManager::GetAllocSize(block->capacity * entry_size));
26496
+ }
26497
+ #endif
26442
26498
  }
26443
26499
 
26444
26500
  static inline idx_t EntriesPerBlock(idx_t width) {
@@ -30777,6 +30833,7 @@ public:
30777
30833
 
30778
30834
  void Serialize(FieldWriter &writer) const override;
30779
30835
  static unique_ptr<LogicalOperator> Deserialize(LogicalDeserializationState &state, FieldReader &reader);
30836
+ vector<idx_t> GetTableIndex() const override;
30780
30837
 
30781
30838
  protected:
30782
30839
  void ResolveTypes() override;
@@ -133,7 +133,6 @@ public:
133
133
  std::unique_ptr<duckdb::Connection> connection;
134
134
  Database *database_ref;
135
135
  std::unordered_map<std::string, duckdb_node_udf_function_t> udfs;
136
- std::unordered_map<std::string, std::vector<std::pair<uint64_t, uint64_t>>> buffers;
137
136
  std::unordered_map<std::string, Napi::Reference<Napi::Array>> array_references;
138
137
  };
139
138