duckdb 0.6.2-dev1770.0 → 0.6.2-dev1772.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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.6.2-dev1770.0",
5
+ "version": "0.6.2-dev1772.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -23,8 +23,6 @@ void FileBuffer::Init() {
23
23
  size = 0;
24
24
  internal_buffer = nullptr;
25
25
  internal_size = 0;
26
- malloced_buffer = nullptr;
27
- malloced_size = 0;
28
26
  }
29
27
 
30
28
  FileBuffer::FileBuffer(FileBuffer &source, FileBufferType type_p) : allocator(source.allocator), type(type_p) {
@@ -33,31 +31,29 @@ FileBuffer::FileBuffer(FileBuffer &source, FileBufferType type_p) : allocator(so
33
31
  size = source.size;
34
32
  internal_buffer = source.internal_buffer;
35
33
  internal_size = source.internal_size;
36
- malloced_buffer = source.malloced_buffer;
37
- malloced_size = source.malloced_size;
38
34
 
39
35
  source.Init();
40
36
  }
41
37
 
42
38
  FileBuffer::~FileBuffer() {
43
- if (!malloced_buffer) {
39
+ if (!internal_buffer) {
44
40
  return;
45
41
  }
46
- allocator.FreeData(malloced_buffer, malloced_size);
42
+ allocator.FreeData(internal_buffer, internal_size);
47
43
  }
48
44
 
49
45
  void FileBuffer::ReallocBuffer(size_t new_size) {
50
- if (malloced_buffer) {
51
- malloced_buffer = allocator.ReallocateData(malloced_buffer, malloced_size, new_size);
46
+ data_ptr_t new_buffer;
47
+ if (internal_buffer) {
48
+ new_buffer = allocator.ReallocateData(internal_buffer, internal_size, new_size);
52
49
  } else {
53
- malloced_buffer = allocator.AllocateData(new_size);
50
+ new_buffer = allocator.AllocateData(new_size);
54
51
  }
55
- if (!malloced_buffer) {
52
+ if (!new_buffer) {
56
53
  throw std::bad_alloc();
57
54
  }
58
- malloced_size = new_size;
59
- internal_buffer = malloced_buffer;
60
- internal_size = malloced_size;
55
+ internal_buffer = new_buffer;
56
+ internal_size = new_size;
61
57
  // Caller must update these.
62
58
  buffer = nullptr;
63
59
  size = 0;
@@ -92,32 +88,11 @@ void FileBuffer::Read(FileHandle &handle, uint64_t location) {
92
88
  handle.Read(internal_buffer, internal_size, location);
93
89
  }
94
90
 
95
- void FileBuffer::ReadAndChecksum(FileHandle &handle, uint64_t location) {
96
- // read the buffer from disk
97
- Read(handle, location);
98
- // compute the checksum
99
- auto stored_checksum = Load<uint64_t>(internal_buffer);
100
- uint64_t computed_checksum = Checksum(buffer, size);
101
- // verify the checksum
102
- if (stored_checksum != computed_checksum) {
103
- throw IOException("Corrupt database file: computed checksum %llu does not match stored checksum %llu in block",
104
- computed_checksum, stored_checksum);
105
- }
106
- }
107
-
108
91
  void FileBuffer::Write(FileHandle &handle, uint64_t location) {
109
92
  D_ASSERT(type != FileBufferType::TINY_BUFFER);
110
93
  handle.Write(internal_buffer, internal_size, location);
111
94
  }
112
95
 
113
- void FileBuffer::ChecksumAndWrite(FileHandle &handle, uint64_t location) {
114
- // compute the checksum and write it to the start of the buffer (if not temp buffer)
115
- uint64_t checksum = Checksum(buffer, size);
116
- Store<uint64_t>(checksum, internal_buffer);
117
- // now write the buffer
118
- Write(handle, location);
119
- }
120
-
121
96
  void FileBuffer::Clear() {
122
97
  memset(internal_buffer, 0, internal_size);
123
98
  }
@@ -11,8 +11,8 @@ SwizzleablePointer::~SwizzleablePointer() {
11
11
 
12
12
  SwizzleablePointer::SwizzleablePointer(duckdb::MetaBlockReader &reader) {
13
13
  idx_t block_id = reader.Read<block_id_t>();
14
- idx_t offset = reader.Read<uint32_t>();
15
- if (block_id == DConstants::INVALID_INDEX || offset == DConstants::INVALID_INDEX) {
14
+ uint32_t offset = reader.Read<uint32_t>();
15
+ if (block_id == DConstants::INVALID_INDEX || offset == (uint32_t)DConstants::INVALID_INDEX) {
16
16
  pointer = 0;
17
17
  return;
18
18
  }
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.6.2-dev1770"
2
+ #define DUCKDB_VERSION "0.6.2-dev1772"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "864ff1c719"
5
+ #define DUCKDB_SOURCE_ID "d25a77fff4"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -39,14 +39,8 @@ public:
39
39
  public:
40
40
  //! Read into the FileBuffer from the specified location.
41
41
  void Read(FileHandle &handle, uint64_t location);
42
- //! Read into the FileBuffer from the specified location. Automatically verifies the checksum, and throws an
43
- //! exception if the checksum does not match correctly.
44
- virtual void ReadAndChecksum(FileHandle &handle, uint64_t location);
45
42
  //! Write the contents of the FileBuffer to the specified location.
46
43
  void Write(FileHandle &handle, uint64_t location);
47
- //! Write the contents of the FileBuffer to the specified location. Automatically adds a checksum of the contents of
48
- //! the filebuffer in front of the written data.
49
- virtual void ChecksumAndWrite(FileHandle &handle, uint64_t location);
50
44
 
51
45
  void Clear();
52
46
 
@@ -57,6 +51,9 @@ public:
57
51
  uint64_t AllocSize() const {
58
52
  return internal_size;
59
53
  }
54
+ data_ptr_t InternalBuffer() {
55
+ return internal_buffer;
56
+ }
60
57
 
61
58
  struct MemoryRequirement {
62
59
  idx_t alloc_size;
@@ -72,16 +69,6 @@ protected:
72
69
  uint64_t internal_size;
73
70
 
74
71
  void ReallocBuffer(size_t malloc_size);
75
-
76
- private:
77
- //! The buffer that was actually malloc'd, i.e. the pointer that must be freed when the FileBuffer is destroyed
78
- data_ptr_t malloced_buffer;
79
- uint64_t malloced_size;
80
-
81
- protected:
82
- uint64_t GetMallocedSize() {
83
- return malloced_size;
84
- }
85
72
  void Init();
86
73
  };
87
74
 
@@ -85,10 +85,8 @@ public:
85
85
  }
86
86
 
87
87
  //! Construct a managed buffer.
88
- //! The block_id is just used for internal tracking. It doesn't map to any actual
89
- //! BlockManager.
90
- virtual unique_ptr<FileBuffer> ConstructManagedBuffer(idx_t size, unique_ptr<FileBuffer> &&source,
91
- FileBufferType type = FileBufferType::MANAGED_BUFFER);
88
+ unique_ptr<FileBuffer> ConstructManagedBuffer(idx_t size, unique_ptr<FileBuffer> &&source,
89
+ FileBufferType type = FileBufferType::MANAGED_BUFFER);
92
90
 
93
91
  DUCKDB_API void ReserveMemory(idx_t size);
94
92
  DUCKDB_API void FreeReservedMemory(idx_t size);
@@ -118,6 +118,7 @@ public:
118
118
  }
119
119
  //! Serializes the index and returns the pair of block_id offset positions
120
120
  virtual BlockPointer Serialize(duckdb::MetaBlockWriter &writer);
121
+ BlockPointer GetBlockPointer();
121
122
 
122
123
  //! Returns block/offset of where index was most recently serialized.
123
124
  BlockPointer GetSerializedDataPointer() const {
@@ -59,6 +59,9 @@ private:
59
59
 
60
60
  void Initialize(DatabaseHeader &header);
61
61
 
62
+ void ReadAndChecksum(FileBuffer &handle, uint64_t location) const;
63
+ void ChecksumAndWrite(FileBuffer &handle, uint64_t location) const;
64
+
62
65
  //! Return the blocks to which we will write the free list and modified blocks
63
66
  vector<block_id_t> GetFreeListBlocks();
64
67
 
@@ -12,11 +12,11 @@
12
12
  #include "duckdb/common/types/data_chunk.hpp"
13
13
  #include "duckdb/common/enums/wal_type.hpp"
14
14
  #include "duckdb/common/serializer/buffered_file_writer.hpp"
15
- #include "duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp"
16
- #include "duckdb/storage/storage_info.hpp"
17
-
18
15
  #include "duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp"
16
+ #include "duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp"
19
17
  #include "duckdb/catalog/catalog_entry/table_macro_catalog_entry.hpp"
18
+ #include "duckdb/main/attached_database.hpp"
19
+ #include "duckdb/storage/storage_info.hpp"
20
20
 
21
21
  namespace duckdb {
22
22
 
@@ -38,8 +38,8 @@ class TransactionManager;
38
38
  class ReplayState {
39
39
  public:
40
40
  ReplayState(AttachedDatabase &db, ClientContext &context, Deserializer &source)
41
- : db(db), context(context), catalog(Catalog::GetCatalog(context, INVALID_CATALOG)), source(source),
42
- current_table(nullptr), deserialize_only(false), checkpoint_id(INVALID_BLOCK) {
41
+ : db(db), context(context), catalog(db.GetCatalog()), source(source), current_table(nullptr),
42
+ deserialize_only(false), checkpoint_id(INVALID_BLOCK) {
43
43
  }
44
44
 
45
45
  AttachedDatabase &db;
@@ -9,11 +9,11 @@ Block::Block(Allocator &allocator, block_id_t id)
9
9
 
10
10
  Block::Block(Allocator &allocator, block_id_t id, uint32_t internal_size)
11
11
  : FileBuffer(allocator, FileBufferType::BLOCK, internal_size), id(id) {
12
- D_ASSERT((GetMallocedSize() & (Storage::SECTOR_SIZE - 1)) == 0);
12
+ D_ASSERT((AllocSize() & (Storage::SECTOR_SIZE - 1)) == 0);
13
13
  }
14
14
 
15
15
  Block::Block(FileBuffer &source, block_id_t id) : FileBuffer(source, FileBufferType::BLOCK), id(id) {
16
- D_ASSERT((GetMallocedSize() & (Storage::SECTOR_SIZE - 1)) == 0);
16
+ D_ASSERT((AllocSize() & (Storage::SECTOR_SIZE - 1)) == 0);
17
17
  }
18
18
 
19
19
  } // namespace duckdb
@@ -1,6 +1,7 @@
1
1
  #include "duckdb/storage/single_file_block_manager.hpp"
2
2
 
3
3
  #include "duckdb/common/allocator.hpp"
4
+ #include "duckdb/common/checksum.hpp"
4
5
  #include "duckdb/common/exception.hpp"
5
6
  #include "duckdb/common/serializer/buffered_deserializer.hpp"
6
7
  #include "duckdb/common/serializer/buffered_serializer.hpp"
@@ -142,7 +143,7 @@ SingleFileBlockManager::SingleFileBlockManager(AttachedDatabase &db, string path
142
143
 
143
144
  SerializeHeaderStructure<MainHeader>(main_header, header_buffer.buffer);
144
145
  // now write the header to the file
145
- header_buffer.ChecksumAndWrite(*handle, 0);
146
+ ChecksumAndWrite(header_buffer, 0);
146
147
  header_buffer.Clear();
147
148
 
148
149
  // write the database headers
@@ -155,14 +156,14 @@ SingleFileBlockManager::SingleFileBlockManager(AttachedDatabase &db, string path
155
156
  h1.free_list = INVALID_BLOCK;
156
157
  h1.block_count = 0;
157
158
  SerializeHeaderStructure<DatabaseHeader>(h1, header_buffer.buffer);
158
- header_buffer.ChecksumAndWrite(*handle, Storage::FILE_HEADER_SIZE);
159
+ ChecksumAndWrite(header_buffer, Storage::FILE_HEADER_SIZE);
159
160
  // header 2
160
161
  h2.iteration = 0;
161
162
  h2.meta_block = INVALID_BLOCK;
162
163
  h2.free_list = INVALID_BLOCK;
163
164
  h2.block_count = 0;
164
165
  SerializeHeaderStructure<DatabaseHeader>(h2, header_buffer.buffer);
165
- header_buffer.ChecksumAndWrite(*handle, Storage::FILE_HEADER_SIZE * 2);
166
+ ChecksumAndWrite(header_buffer, Storage::FILE_HEADER_SIZE * 2);
166
167
  // ensure that writing to disk is completed before returning
167
168
  handle->Sync();
168
169
  // we start with h2 as active_header, this way our initial write will be in h1
@@ -172,14 +173,14 @@ SingleFileBlockManager::SingleFileBlockManager(AttachedDatabase &db, string path
172
173
  } else {
173
174
  MainHeader::CheckMagicBytes(*handle);
174
175
  // otherwise, we check the metadata of the file
175
- header_buffer.ReadAndChecksum(*handle, 0);
176
+ ReadAndChecksum(header_buffer, 0);
176
177
  DeserializeHeaderStructure<MainHeader>(header_buffer.buffer);
177
178
 
178
179
  // read the database headers from disk
179
180
  DatabaseHeader h1, h2;
180
- header_buffer.ReadAndChecksum(*handle, Storage::FILE_HEADER_SIZE);
181
+ ReadAndChecksum(header_buffer, Storage::FILE_HEADER_SIZE);
181
182
  h1 = DeserializeHeaderStructure<DatabaseHeader>(header_buffer.buffer);
182
- header_buffer.ReadAndChecksum(*handle, Storage::FILE_HEADER_SIZE * 2);
183
+ ReadAndChecksum(header_buffer, Storage::FILE_HEADER_SIZE * 2);
183
184
  h2 = DeserializeHeaderStructure<DatabaseHeader>(header_buffer.buffer);
184
185
  // check the header with the highest iteration count
185
186
  if (h1.iteration > h2.iteration) {
@@ -195,6 +196,27 @@ SingleFileBlockManager::SingleFileBlockManager(AttachedDatabase &db, string path
195
196
  }
196
197
  }
197
198
 
199
+ void SingleFileBlockManager::ReadAndChecksum(FileBuffer &block, uint64_t location) const {
200
+ // read the buffer from disk
201
+ block.Read(*handle, location);
202
+ // compute the checksum
203
+ auto stored_checksum = Load<uint64_t>(block.InternalBuffer());
204
+ uint64_t computed_checksum = Checksum(block.buffer, block.size);
205
+ // verify the checksum
206
+ if (stored_checksum != computed_checksum) {
207
+ throw IOException("Corrupt database file: computed checksum %llu does not match stored checksum %llu in block",
208
+ computed_checksum, stored_checksum);
209
+ }
210
+ }
211
+
212
+ void SingleFileBlockManager::ChecksumAndWrite(FileBuffer &block, uint64_t location) const {
213
+ // compute the checksum and write it to the start of the buffer (if not temp buffer)
214
+ uint64_t checksum = Checksum(block.buffer, block.size);
215
+ Store<uint64_t>(checksum, block.InternalBuffer());
216
+ // now write the buffer
217
+ block.Write(*handle, location);
218
+ }
219
+
198
220
  void SingleFileBlockManager::Initialize(DatabaseHeader &header) {
199
221
  free_list_id = header.free_list;
200
222
  meta_block = header.meta_block;
@@ -317,12 +339,12 @@ unique_ptr<Block> SingleFileBlockManager::CreateBlock(block_id_t block_id, FileB
317
339
  void SingleFileBlockManager::Read(Block &block) {
318
340
  D_ASSERT(block.id >= 0);
319
341
  D_ASSERT(std::find(free_list.begin(), free_list.end(), block.id) == free_list.end());
320
- block.ReadAndChecksum(*handle, BLOCK_START + block.id * Storage::BLOCK_ALLOC_SIZE);
342
+ ReadAndChecksum(block, BLOCK_START + block.id * Storage::BLOCK_ALLOC_SIZE);
321
343
  }
322
344
 
323
345
  void SingleFileBlockManager::Write(FileBuffer &buffer, block_id_t block_id) {
324
346
  D_ASSERT(block_id >= 0);
325
- buffer.ChecksumAndWrite(*handle, BLOCK_START + block_id * Storage::BLOCK_ALLOC_SIZE);
347
+ ChecksumAndWrite(buffer, BLOCK_START + block_id * Storage::BLOCK_ALLOC_SIZE);
326
348
  }
327
349
 
328
350
  vector<block_id_t> SingleFileBlockManager::GetFreeListBlocks() {
@@ -431,8 +453,7 @@ void SingleFileBlockManager::WriteHeader(DatabaseHeader header) {
431
453
  Store<DatabaseHeader>(header, header_buffer.buffer);
432
454
  // now write the header to the file, active_header determines whether we write to h1 or h2
433
455
  // note that if active_header is h1 we write to h2, and vice versa
434
- header_buffer.ChecksumAndWrite(*handle,
435
- active_header == 1 ? Storage::FILE_HEADER_SIZE : Storage::FILE_HEADER_SIZE * 2);
456
+ ChecksumAndWrite(header_buffer, active_header == 1 ? Storage::FILE_HEADER_SIZE : Storage::FILE_HEADER_SIZE * 2);
436
457
  // switch active header to the other header
437
458
  active_header = 1 - active_header;
438
459
  //! Ensure the header write ends up on disk