duckdb 0.7.2-dev16.0 → 0.7.2-dev225.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/binding.gyp +2 -0
- package/package.json +1 -1
- package/src/duckdb/extension/icu/icu-extension.cpp +2 -0
- package/src/duckdb/extension/icu/icu-table-range.cpp +194 -0
- package/src/duckdb/extension/icu/include/icu-table-range.hpp +17 -0
- package/src/duckdb/extension/parquet/column_writer.cpp +0 -1
- package/src/duckdb/extension/parquet/parquet-extension.cpp +11 -2
- package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +4 -0
- package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +7 -6
- package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +20 -1
- package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
- package/src/duckdb/src/common/types/bit.cpp +95 -58
- package/src/duckdb/src/common/types/value.cpp +149 -53
- package/src/duckdb/src/common/types/vector.cpp +13 -10
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
- package/src/duckdb/src/function/aggregate/algebraic/avg.cpp +0 -6
- package/src/duckdb/src/function/aggregate/distributive/bitagg.cpp +99 -95
- package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +261 -0
- package/src/duckdb/src/function/aggregate/distributive/sum.cpp +0 -3
- package/src/duckdb/src/function/aggregate/distributive_functions.cpp +1 -0
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +16 -5
- package/src/duckdb/src/function/cast/bit_cast.cpp +0 -2
- package/src/duckdb/src/function/cast/blob_cast.cpp +0 -1
- package/src/duckdb/src/function/scalar/bit/bitstring.cpp +99 -0
- package/src/duckdb/src/function/scalar/map/map_entries.cpp +61 -0
- package/src/duckdb/src/function/scalar/map/map_keys_values.cpp +97 -0
- package/src/duckdb/src/function/scalar/nested_functions.cpp +3 -0
- package/src/duckdb/src/function/scalar/operators/add.cpp +0 -9
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +2 -14
- package/src/duckdb/src/function/scalar/operators/bitwise.cpp +0 -63
- package/src/duckdb/src/function/scalar/operators/multiply.cpp +0 -6
- package/src/duckdb/src/function/scalar/operators/subtract.cpp +0 -6
- package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
- package/src/duckdb/src/function/table/read_csv.cpp +9 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/function/table_function.cpp +19 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +6 -8
- package/src/duckdb/src/include/duckdb/common/constants.hpp +0 -19
- package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/enums/tableref_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/types/bit.hpp +5 -1
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -8
- package/src/duckdb/src/include/duckdb/common/types.hpp +1 -2
- package/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +5 -0
- package/src/duckdb/src/include/duckdb/function/scalar/bit_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +12 -0
- package/src/duckdb/src/include/duckdb/function/table_function.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/database.hpp +1 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/{alter_function_info.hpp → alter_scalar_function_info.hpp} +13 -13
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_function_info.hpp +47 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_function_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/statement/multi_statement.hpp +28 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +76 -0
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +28 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +8 -0
- package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +76 -44
- package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/statistics/node_statistics.hpp +26 -0
- package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +2 -0
- package/src/duckdb/src/include/duckdb.h +49 -1
- package/src/duckdb/src/include/duckdb.hpp +0 -1
- package/src/duckdb/src/main/capi/pending-c.cpp +16 -3
- package/src/duckdb/src/main/capi/result-c.cpp +27 -1
- package/src/duckdb/src/main/capi/stream-c.cpp +25 -0
- package/src/duckdb/src/main/client_context.cpp +8 -1
- package/src/duckdb/src/main/database.cpp +10 -2
- package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +98 -66
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +16 -3
- package/src/duckdb/src/parser/parsed_data/alter_info.cpp +7 -3
- package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +56 -0
- package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +51 -0
- package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +3 -2
- package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +6 -0
- package/src/duckdb/src/parser/parsed_expression_iterator.cpp +8 -0
- package/src/duckdb/src/parser/query_node.cpp +1 -1
- package/src/duckdb/src/parser/statement/multi_statement.cpp +18 -0
- package/src/duckdb/src/parser/tableref/pivotref.cpp +296 -0
- package/src/duckdb/src/parser/tableref.cpp +3 -0
- package/src/duckdb/src/parser/transform/helpers/transform_alias.cpp +12 -6
- package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +24 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +4 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_view.cpp +4 -0
- package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +150 -0
- package/src/duckdb/src/parser/transform/statement/transform_select.cpp +8 -0
- package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -1
- package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +105 -0
- package/src/duckdb/src/parser/transform/tableref/transform_tableref.cpp +2 -0
- package/src/duckdb/src/parser/transformer.cpp +15 -3
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +11 -3
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -1
- package/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +17 -0
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +365 -0
- package/src/duckdb/src/planner/binder.cpp +5 -0
- package/src/duckdb/src/planner/pragma_handler.cpp +10 -2
- package/src/duckdb/src/storage/buffer_manager.cpp +44 -46
- package/src/duckdb/src/storage/compression/bitpacking.cpp +25 -21
- package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +41 -43
- package/src/duckdb/src/storage/compression/rle.cpp +17 -13
- package/src/duckdb/src/storage/statistics/base_statistics.cpp +3 -3
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/src/storage/table/column_data.cpp +5 -2
- package/src/duckdb/src/storage/table/list_column_data.cpp +32 -47
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +3 -0
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +34 -1
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +1016 -530
- package/src/duckdb/third_party/libpg_query/include/parser/kwlist.hpp +5 -0
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +22697 -21987
- package/src/duckdb/ub_src_function_aggregate_distributive.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_bit.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_map.cpp +4 -0
- package/src/duckdb/ub_src_main_capi.cpp +2 -0
- package/src/duckdb/ub_src_parser_parsed_data.cpp +4 -2
- package/src/duckdb/ub_src_parser_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_tableref.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_tableref.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_tableref.cpp +2 -0
- package/src/duckdb/src/include/duckdb/main/loadable_extension.hpp +0 -59
- package/src/duckdb/src/parser/parsed_data/alter_function_info.cpp +0 -55
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
#include "duckdb/storage/in_memory_block_manager.hpp"
|
|
8
8
|
#include "duckdb/storage/storage_manager.hpp"
|
|
9
9
|
#include "duckdb/main/attached_database.hpp"
|
|
10
|
+
#include "duckdb/main/database.hpp"
|
|
10
11
|
|
|
11
12
|
namespace duckdb {
|
|
12
13
|
|
|
@@ -71,11 +72,11 @@ BlockHandle::~BlockHandle() { // NOLINT: allow internal exceptions
|
|
|
71
72
|
D_ASSERT(memory_charge.size > 0);
|
|
72
73
|
// the block is still loaded in memory: erase it
|
|
73
74
|
buffer.reset();
|
|
74
|
-
memory_charge.Resize(buffer_manager.current_memory, 0);
|
|
75
|
+
memory_charge.Resize(buffer_manager.buffer_pool.current_memory, 0);
|
|
75
76
|
} else {
|
|
76
77
|
D_ASSERT(memory_charge.size == 0);
|
|
77
78
|
}
|
|
78
|
-
buffer_manager.PurgeQueue();
|
|
79
|
+
buffer_manager.buffer_pool.PurgeQueue();
|
|
79
80
|
block_manager.UnregisterBlock(block_id, can_destroy);
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -150,7 +151,7 @@ unique_ptr<FileBuffer> BlockHandle::UnloadAndTakeBlock() {
|
|
|
150
151
|
// temporary block that cannot be destroyed: write to temporary file
|
|
151
152
|
block_manager.buffer_manager.WriteTemporaryBuffer(block_id, *buffer);
|
|
152
153
|
}
|
|
153
|
-
memory_charge.Resize(block_manager.buffer_manager.current_memory, 0);
|
|
154
|
+
memory_charge.Resize(block_manager.buffer_manager.buffer_pool.current_memory, 0);
|
|
154
155
|
state = BlockState::BLOCK_UNLOADED;
|
|
155
156
|
return std::move(buffer);
|
|
156
157
|
}
|
|
@@ -241,9 +242,14 @@ void BufferManager::SetTemporaryDirectory(string new_dir) {
|
|
|
241
242
|
this->temp_directory = std::move(new_dir);
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
|
|
245
|
-
:
|
|
246
|
-
|
|
245
|
+
BufferPool::BufferPool(idx_t maximum_memory)
|
|
246
|
+
: current_memory(0), maximum_memory(maximum_memory), queue(make_unique<EvictionQueue>()), queue_insertions(0) {
|
|
247
|
+
}
|
|
248
|
+
BufferPool::~BufferPool() {
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
BufferManager::BufferManager(DatabaseInstance &db, string tmp)
|
|
252
|
+
: db(db), buffer_pool(db.GetBufferPool()), temp_directory(std::move(tmp)), temporary_id(MAXIMUM_BLOCK),
|
|
247
253
|
buffer_allocator(BufferAllocatorAllocate, BufferAllocatorFree, BufferAllocatorRealloc,
|
|
248
254
|
make_unique<BufferAllocatorData>(*this)) {
|
|
249
255
|
temp_block_manager = make_unique<InMemoryBlockManager>(*this);
|
|
@@ -311,15 +317,15 @@ shared_ptr<BlockHandle> BlockManager::ConvertToPersistent(block_id_t block_id, s
|
|
|
311
317
|
// persist the new block to disk
|
|
312
318
|
Write(*new_block->buffer, block_id);
|
|
313
319
|
|
|
314
|
-
buffer_manager.AddToEvictionQueue(new_block);
|
|
320
|
+
buffer_manager.buffer_pool.AddToEvictionQueue(new_block);
|
|
315
321
|
|
|
316
322
|
return new_block;
|
|
317
323
|
}
|
|
318
324
|
|
|
319
325
|
template <typename... ARGS>
|
|
320
|
-
TempBufferPoolReservation BufferManager::EvictBlocksOrThrow(idx_t memory_delta,
|
|
321
|
-
|
|
322
|
-
auto r = EvictBlocks(memory_delta,
|
|
326
|
+
TempBufferPoolReservation BufferManager::EvictBlocksOrThrow(idx_t memory_delta, unique_ptr<FileBuffer> *buffer,
|
|
327
|
+
ARGS... args) {
|
|
328
|
+
auto r = buffer_pool.EvictBlocks(memory_delta, buffer_pool.maximum_memory, buffer);
|
|
323
329
|
if (!r.success) {
|
|
324
330
|
throw OutOfMemoryException(args..., InMemoryWarning());
|
|
325
331
|
}
|
|
@@ -328,9 +334,8 @@ TempBufferPoolReservation BufferManager::EvictBlocksOrThrow(idx_t memory_delta,
|
|
|
328
334
|
|
|
329
335
|
shared_ptr<BlockHandle> BufferManager::RegisterSmallMemory(idx_t block_size) {
|
|
330
336
|
D_ASSERT(block_size < Storage::BLOCK_SIZE);
|
|
331
|
-
auto res = EvictBlocksOrThrow(block_size,
|
|
332
|
-
|
|
333
|
-
GetUsedMemory(), GetMaxMemory());
|
|
337
|
+
auto res = EvictBlocksOrThrow(block_size, nullptr, "could not allocate block of %lld bytes (%lld/%lld used) %s",
|
|
338
|
+
block_size, GetUsedMemory(), GetMaxMemory());
|
|
334
339
|
|
|
335
340
|
auto buffer = ConstructManagedBuffer(block_size, nullptr, FileBufferType::TINY_BUFFER);
|
|
336
341
|
|
|
@@ -344,9 +349,9 @@ shared_ptr<BlockHandle> BufferManager::RegisterMemory(idx_t block_size, bool can
|
|
|
344
349
|
auto alloc_size = GetAllocSize(block_size);
|
|
345
350
|
// first evict blocks until we have enough memory to store this buffer
|
|
346
351
|
unique_ptr<FileBuffer> reusable_buffer;
|
|
347
|
-
auto res =
|
|
348
|
-
|
|
349
|
-
|
|
352
|
+
auto res =
|
|
353
|
+
EvictBlocksOrThrow(alloc_size, &reusable_buffer, "could not allocate block of %lld bytes (%lld/%lld used) %s",
|
|
354
|
+
alloc_size, GetUsedMemory(), GetMaxMemory());
|
|
350
355
|
|
|
351
356
|
auto buffer = ConstructManagedBuffer(block_size, std::move(reusable_buffer));
|
|
352
357
|
|
|
@@ -376,14 +381,13 @@ void BufferManager::ReAllocate(shared_ptr<BlockHandle> &handle, idx_t block_size
|
|
|
376
381
|
return;
|
|
377
382
|
} else if (memory_delta > 0) {
|
|
378
383
|
// evict blocks until we have space to resize this block
|
|
379
|
-
auto reservation =
|
|
380
|
-
|
|
381
|
-
handle->memory_usage, req.alloc_size);
|
|
384
|
+
auto reservation = EvictBlocksOrThrow(memory_delta, nullptr, "failed to resize block from %lld to %lld%s",
|
|
385
|
+
handle->memory_usage, req.alloc_size);
|
|
382
386
|
// EvictBlocks decrements 'current_memory' for us.
|
|
383
387
|
handle->memory_charge.Merge(std::move(reservation));
|
|
384
388
|
} else {
|
|
385
389
|
// no need to evict blocks, but we do need to decrement 'current_memory'.
|
|
386
|
-
handle->memory_charge.Resize(current_memory, req.alloc_size);
|
|
390
|
+
handle->memory_charge.Resize(buffer_pool.current_memory, req.alloc_size);
|
|
387
391
|
}
|
|
388
392
|
|
|
389
393
|
// resize and adjust current memory
|
|
@@ -407,15 +411,15 @@ BufferHandle BufferManager::Pin(shared_ptr<BlockHandle> &handle) {
|
|
|
407
411
|
}
|
|
408
412
|
// evict blocks until we have space for the current block
|
|
409
413
|
unique_ptr<FileBuffer> reusable_buffer;
|
|
410
|
-
auto reservation =
|
|
411
|
-
|
|
414
|
+
auto reservation =
|
|
415
|
+
EvictBlocksOrThrow(required_memory, &reusable_buffer, "failed to pin block of size %lld%s", required_memory);
|
|
412
416
|
// lock the handle again and repeat the check (in case anybody loaded in the mean time)
|
|
413
417
|
lock_guard<mutex> lock(handle->lock);
|
|
414
418
|
// check if the block is already loaded
|
|
415
419
|
if (handle->state == BlockState::BLOCK_LOADED) {
|
|
416
420
|
// the block is loaded, increment the reader count and return a pointer to the handle
|
|
417
421
|
handle->readers++;
|
|
418
|
-
reservation.Resize(current_memory, 0);
|
|
422
|
+
reservation.Resize(buffer_pool.current_memory, 0);
|
|
419
423
|
return handle->Load(handle);
|
|
420
424
|
}
|
|
421
425
|
// now we can actually load the current block
|
|
@@ -428,13 +432,13 @@ BufferHandle BufferManager::Pin(shared_ptr<BlockHandle> &handle) {
|
|
|
428
432
|
if (delta) {
|
|
429
433
|
D_ASSERT(delta < 0);
|
|
430
434
|
handle->memory_usage += delta;
|
|
431
|
-
handle->memory_charge.Resize(current_memory, handle->memory_usage);
|
|
435
|
+
handle->memory_charge.Resize(buffer_pool.current_memory, handle->memory_usage);
|
|
432
436
|
}
|
|
433
437
|
D_ASSERT(handle->memory_usage == handle->buffer->AllocSize());
|
|
434
438
|
return buf;
|
|
435
439
|
}
|
|
436
440
|
|
|
437
|
-
void
|
|
441
|
+
void BufferPool::AddToEvictionQueue(shared_ptr<BlockHandle> &handle) {
|
|
438
442
|
constexpr int INSERT_INTERVAL = 1024;
|
|
439
443
|
|
|
440
444
|
D_ASSERT(handle->readers == 0);
|
|
@@ -465,12 +469,12 @@ void BufferManager::Unpin(shared_ptr<BlockHandle> &handle) {
|
|
|
465
469
|
handle->readers--;
|
|
466
470
|
if (handle->readers == 0) {
|
|
467
471
|
VerifyZeroReaders(handle);
|
|
468
|
-
AddToEvictionQueue(handle);
|
|
472
|
+
buffer_pool.AddToEvictionQueue(handle);
|
|
469
473
|
}
|
|
470
474
|
}
|
|
471
475
|
|
|
472
|
-
|
|
473
|
-
|
|
476
|
+
BufferPool::EvictionResult BufferPool::EvictBlocks(idx_t extra_memory, idx_t memory_limit,
|
|
477
|
+
unique_ptr<FileBuffer> *buffer) {
|
|
474
478
|
BufferEvictionNode node;
|
|
475
479
|
TempBufferPoolReservation r(current_memory, extra_memory);
|
|
476
480
|
while (current_memory > memory_limit) {
|
|
@@ -504,7 +508,7 @@ BufferManager::EvictionResult BufferManager::EvictBlocks(idx_t extra_memory, idx
|
|
|
504
508
|
return {true, std::move(r)};
|
|
505
509
|
}
|
|
506
510
|
|
|
507
|
-
void
|
|
511
|
+
void BufferPool::PurgeQueue() {
|
|
508
512
|
BufferEvictionNode node;
|
|
509
513
|
while (true) {
|
|
510
514
|
if (!queue->q.try_dequeue(node)) {
|
|
@@ -531,13 +535,13 @@ void BlockManager::UnregisterBlock(block_id_t block_id, bool can_destroy) {
|
|
|
531
535
|
}
|
|
532
536
|
}
|
|
533
537
|
|
|
534
|
-
void
|
|
538
|
+
void BufferPool::SetLimit(idx_t limit, const char *exception_postscript) {
|
|
535
539
|
lock_guard<mutex> l_lock(limit_lock);
|
|
536
540
|
// try to evict until the limit is reached
|
|
537
541
|
if (!EvictBlocks(0, limit).success) {
|
|
538
542
|
throw OutOfMemoryException(
|
|
539
543
|
"Failed to change memory limit to %lld: could not free up enough memory for the new limit%s", limit,
|
|
540
|
-
|
|
544
|
+
exception_postscript);
|
|
541
545
|
}
|
|
542
546
|
idx_t old_limit = maximum_memory;
|
|
543
547
|
// set the global maximum memory to the new limit if successful
|
|
@@ -548,20 +552,16 @@ void BufferManager::SetLimit(idx_t limit) {
|
|
|
548
552
|
maximum_memory = old_limit;
|
|
549
553
|
throw OutOfMemoryException(
|
|
550
554
|
"Failed to change memory limit to %lld: could not free up enough memory for the new limit%s", limit,
|
|
551
|
-
|
|
555
|
+
exception_postscript);
|
|
552
556
|
}
|
|
553
557
|
}
|
|
554
558
|
|
|
555
559
|
void BufferManager::IncreaseUsedMemory(idx_t size) {
|
|
556
|
-
|
|
557
|
-
throw OutOfMemoryException("Failed to allocate data of size %lld%s", size, InMemoryWarning());
|
|
558
|
-
}
|
|
559
|
-
current_memory += size;
|
|
560
|
+
ReserveMemory(size);
|
|
560
561
|
}
|
|
561
562
|
|
|
562
563
|
void BufferManager::DecreaseUsedMemory(idx_t size) {
|
|
563
|
-
|
|
564
|
-
current_memory -= size;
|
|
564
|
+
FreeReservedMemory(size);
|
|
565
565
|
}
|
|
566
566
|
|
|
567
567
|
//===--------------------------------------------------------------------===//
|
|
@@ -1044,7 +1044,7 @@ vector<TemporaryFileInformation> BufferManager::GetTemporaryFiles() {
|
|
|
1044
1044
|
return result;
|
|
1045
1045
|
}
|
|
1046
1046
|
|
|
1047
|
-
|
|
1047
|
+
const char *BufferManager::InMemoryWarning() {
|
|
1048
1048
|
if (!temp_directory.empty()) {
|
|
1049
1049
|
return "";
|
|
1050
1050
|
}
|
|
@@ -1058,8 +1058,7 @@ void BufferManager::ReserveMemory(idx_t size) {
|
|
|
1058
1058
|
if (size == 0) {
|
|
1059
1059
|
return;
|
|
1060
1060
|
}
|
|
1061
|
-
auto reservation =
|
|
1062
|
-
EvictBlocksOrThrow(size, maximum_memory, nullptr, "failed to reserve memory data of size %lld%s", size);
|
|
1061
|
+
auto reservation = EvictBlocksOrThrow(size, nullptr, "failed to reserve memory data of size %lld%s", size);
|
|
1063
1062
|
reservation.size = 0;
|
|
1064
1063
|
}
|
|
1065
1064
|
|
|
@@ -1067,7 +1066,7 @@ void BufferManager::FreeReservedMemory(idx_t size) {
|
|
|
1067
1066
|
if (size == 0) {
|
|
1068
1067
|
return;
|
|
1069
1068
|
}
|
|
1070
|
-
current_memory -= size;
|
|
1069
|
+
buffer_pool.current_memory -= size;
|
|
1071
1070
|
}
|
|
1072
1071
|
|
|
1073
1072
|
//===--------------------------------------------------------------------===//
|
|
@@ -1075,8 +1074,7 @@ void BufferManager::FreeReservedMemory(idx_t size) {
|
|
|
1075
1074
|
//===--------------------------------------------------------------------===//
|
|
1076
1075
|
data_ptr_t BufferManager::BufferAllocatorAllocate(PrivateAllocatorData *private_data, idx_t size) {
|
|
1077
1076
|
auto &data = (BufferAllocatorData &)*private_data;
|
|
1078
|
-
auto reservation = data.manager.EvictBlocksOrThrow(size, data
|
|
1079
|
-
"failed to allocate data of size %lld%s", size);
|
|
1077
|
+
auto reservation = data.manager.EvictBlocksOrThrow(size, nullptr, "failed to allocate data of size %lld%s", size);
|
|
1080
1078
|
// We rely on manual tracking of this one. :(
|
|
1081
1079
|
reservation.size = 0;
|
|
1082
1080
|
return Allocator::Get(data.manager.db).AllocateData(size);
|
|
@@ -1086,7 +1084,7 @@ void BufferManager::BufferAllocatorFree(PrivateAllocatorData *private_data, data
|
|
|
1086
1084
|
auto &data = (BufferAllocatorData &)*private_data;
|
|
1087
1085
|
BufferPoolReservation r;
|
|
1088
1086
|
r.size = size;
|
|
1089
|
-
r.Resize(data.manager.current_memory, 0);
|
|
1087
|
+
r.Resize(data.manager.buffer_pool.current_memory, 0);
|
|
1090
1088
|
return Allocator::Get(data.manager.db).FreeData(pointer, size);
|
|
1091
1089
|
}
|
|
1092
1090
|
|
|
@@ -1098,7 +1096,7 @@ data_ptr_t BufferManager::BufferAllocatorRealloc(PrivateAllocatorData *private_d
|
|
|
1098
1096
|
auto &data = (BufferAllocatorData &)*private_data;
|
|
1099
1097
|
BufferPoolReservation r;
|
|
1100
1098
|
r.size = old_size;
|
|
1101
|
-
r.Resize(data.manager.current_memory, size);
|
|
1099
|
+
r.Resize(data.manager.buffer_pool.current_memory, size);
|
|
1102
1100
|
r.size = 0;
|
|
1103
1101
|
return Allocator::Get(data.manager.db).ReallocateData(pointer, old_size, size);
|
|
1104
1102
|
}
|
|
@@ -347,7 +347,7 @@ idx_t BitpackingFinalAnalyze(AnalyzeState &state) {
|
|
|
347
347
|
//===--------------------------------------------------------------------===//
|
|
348
348
|
// Compress
|
|
349
349
|
//===--------------------------------------------------------------------===//
|
|
350
|
-
template <class T, class T_S = typename std::make_signed<T>::type>
|
|
350
|
+
template <class T, bool WRITE_STATISTICS, class T_S = typename std::make_signed<T>::type>
|
|
351
351
|
struct BitpackingCompressState : public CompressionState {
|
|
352
352
|
public:
|
|
353
353
|
explicit BitpackingCompressState(ColumnDataCheckpointer &checkpointer) : checkpointer(checkpointer) {
|
|
@@ -377,7 +377,7 @@ public:
|
|
|
377
377
|
public:
|
|
378
378
|
struct BitpackingWriter {
|
|
379
379
|
static void WriteConstant(T constant, idx_t count, void *data_ptr, bool all_invalid) {
|
|
380
|
-
auto state = (BitpackingCompressState<T> *)data_ptr;
|
|
380
|
+
auto state = (BitpackingCompressState<T, WRITE_STATISTICS> *)data_ptr;
|
|
381
381
|
|
|
382
382
|
ReserveSpace(state, sizeof(T));
|
|
383
383
|
WriteMetaData(state, BitpackingMode::CONSTANT);
|
|
@@ -388,7 +388,7 @@ public:
|
|
|
388
388
|
|
|
389
389
|
static void WriteConstantDelta(T_S constant, T frame_of_reference, idx_t count, T *values, bool *validity,
|
|
390
390
|
void *data_ptr) {
|
|
391
|
-
auto state = (BitpackingCompressState<T> *)data_ptr;
|
|
391
|
+
auto state = (BitpackingCompressState<T, WRITE_STATISTICS> *)data_ptr;
|
|
392
392
|
|
|
393
393
|
ReserveSpace(state, 2 * sizeof(T));
|
|
394
394
|
WriteMetaData(state, BitpackingMode::CONSTANT_DELTA);
|
|
@@ -400,7 +400,7 @@ public:
|
|
|
400
400
|
|
|
401
401
|
static void WriteDeltaFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference,
|
|
402
402
|
T_S delta_offset, T *original_values, idx_t count, void *data_ptr) {
|
|
403
|
-
auto state = (BitpackingCompressState<T> *)data_ptr;
|
|
403
|
+
auto state = (BitpackingCompressState<T, WRITE_STATISTICS> *)data_ptr;
|
|
404
404
|
|
|
405
405
|
auto bp_size = BitpackingPrimitives::GetRequiredSize(count, width);
|
|
406
406
|
ReserveSpace(state, bp_size + 3 * sizeof(T));
|
|
@@ -418,7 +418,7 @@ public:
|
|
|
418
418
|
|
|
419
419
|
static void WriteFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, idx_t count,
|
|
420
420
|
void *data_ptr) {
|
|
421
|
-
auto state = (BitpackingCompressState<T> *)data_ptr;
|
|
421
|
+
auto state = (BitpackingCompressState<T, WRITE_STATISTICS> *)data_ptr;
|
|
422
422
|
|
|
423
423
|
auto bp_size = BitpackingPrimitives::GetRequiredSize(count, width);
|
|
424
424
|
ReserveSpace(state, bp_size + 2 * sizeof(T));
|
|
@@ -439,22 +439,22 @@ public:
|
|
|
439
439
|
ptr += sizeof(T_OUT);
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
static void WriteMetaData(BitpackingCompressState<T> *state, BitpackingMode mode) {
|
|
442
|
+
static void WriteMetaData(BitpackingCompressState<T, WRITE_STATISTICS> *state, BitpackingMode mode) {
|
|
443
443
|
bitpacking_metadata_t metadata {mode, (uint32_t)(state->data_ptr - state->handle.Ptr())};
|
|
444
444
|
state->metadata_ptr -= sizeof(bitpacking_metadata_encoded_t);
|
|
445
445
|
Store<bitpacking_metadata_encoded_t>(EncodeMeta(metadata), state->metadata_ptr);
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
-
static void ReserveSpace(BitpackingCompressState<T> *state, idx_t data_bytes) {
|
|
448
|
+
static void ReserveSpace(BitpackingCompressState<T, WRITE_STATISTICS> *state, idx_t data_bytes) {
|
|
449
449
|
idx_t meta_bytes = sizeof(bitpacking_metadata_encoded_t);
|
|
450
450
|
state->FlushAndCreateSegmentIfFull(data_bytes, meta_bytes);
|
|
451
451
|
D_ASSERT(state->CanStore(data_bytes, meta_bytes));
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
-
static void UpdateStats(BitpackingCompressState<T> *state, idx_t count) {
|
|
454
|
+
static void UpdateStats(BitpackingCompressState<T, WRITE_STATISTICS> *state, idx_t count) {
|
|
455
455
|
state->current_segment->count += count;
|
|
456
456
|
|
|
457
|
-
if (!state->state.all_invalid) {
|
|
457
|
+
if (WRITE_STATISTICS && !state->state.all_invalid) {
|
|
458
458
|
NumericStatistics::Update<T>(state->current_segment->stats, state->state.minimum);
|
|
459
459
|
NumericStatistics::Update<T>(state->current_segment->stats, state->state.maximum);
|
|
460
460
|
}
|
|
@@ -487,8 +487,8 @@ public:
|
|
|
487
487
|
|
|
488
488
|
for (idx_t i = 0; i < count; i++) {
|
|
489
489
|
auto idx = vdata.sel->get_index(i);
|
|
490
|
-
state.template Update<BitpackingCompressState<T, T_S>::BitpackingWriter>(
|
|
491
|
-
|
|
490
|
+
state.template Update<BitpackingCompressState<T, WRITE_STATISTICS, T_S>::BitpackingWriter>(
|
|
491
|
+
data[idx], vdata.validity.RowIsValid(idx));
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
494
|
|
|
@@ -524,29 +524,29 @@ public:
|
|
|
524
524
|
}
|
|
525
525
|
|
|
526
526
|
void Finalize() {
|
|
527
|
-
state.template Flush<BitpackingCompressState<T, T_S>::BitpackingWriter>();
|
|
527
|
+
state.template Flush<BitpackingCompressState<T, WRITE_STATISTICS, T_S>::BitpackingWriter>();
|
|
528
528
|
FlushSegment();
|
|
529
529
|
current_segment.reset();
|
|
530
530
|
}
|
|
531
531
|
};
|
|
532
532
|
|
|
533
|
-
template <class T>
|
|
533
|
+
template <class T, bool WRITE_STATISTICS>
|
|
534
534
|
unique_ptr<CompressionState> BitpackingInitCompression(ColumnDataCheckpointer &checkpointer,
|
|
535
535
|
unique_ptr<AnalyzeState> state) {
|
|
536
|
-
return make_unique<BitpackingCompressState<T>>(checkpointer);
|
|
536
|
+
return make_unique<BitpackingCompressState<T, WRITE_STATISTICS>>(checkpointer);
|
|
537
537
|
}
|
|
538
538
|
|
|
539
|
-
template <class T>
|
|
539
|
+
template <class T, bool WRITE_STATISTICS>
|
|
540
540
|
void BitpackingCompress(CompressionState &state_p, Vector &scan_vector, idx_t count) {
|
|
541
|
-
auto &state = (BitpackingCompressState<T> &)state_p;
|
|
541
|
+
auto &state = (BitpackingCompressState<T, WRITE_STATISTICS> &)state_p;
|
|
542
542
|
UnifiedVectorFormat vdata;
|
|
543
543
|
scan_vector.ToUnifiedFormat(count, vdata);
|
|
544
544
|
state.Append(vdata, count);
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
-
template <class T>
|
|
547
|
+
template <class T, bool WRITE_STATISTICS>
|
|
548
548
|
void BitpackingFinalizeCompress(CompressionState &state_p) {
|
|
549
|
-
auto &state = (BitpackingCompressState<T> &)state_p;
|
|
549
|
+
auto &state = (BitpackingCompressState<T, WRITE_STATISTICS> &)state_p;
|
|
550
550
|
state.Finalize();
|
|
551
551
|
}
|
|
552
552
|
|
|
@@ -880,11 +880,12 @@ void BitpackingSkip(ColumnSegment &segment, ColumnScanState &state, idx_t skip_c
|
|
|
880
880
|
//===--------------------------------------------------------------------===//
|
|
881
881
|
// Get Function
|
|
882
882
|
//===--------------------------------------------------------------------===//
|
|
883
|
-
template <class T>
|
|
883
|
+
template <class T, bool WRITE_STATISTICS = true>
|
|
884
884
|
CompressionFunction GetBitpackingFunction(PhysicalType data_type) {
|
|
885
885
|
return CompressionFunction(CompressionType::COMPRESSION_BITPACKING, data_type, BitpackingInitAnalyze<T>,
|
|
886
|
-
BitpackingAnalyze<T>, BitpackingFinalAnalyze<T>,
|
|
887
|
-
|
|
886
|
+
BitpackingAnalyze<T>, BitpackingFinalAnalyze<T>,
|
|
887
|
+
BitpackingInitCompression<T, WRITE_STATISTICS>, BitpackingCompress<T, WRITE_STATISTICS>,
|
|
888
|
+
BitpackingFinalizeCompress<T, WRITE_STATISTICS>, BitpackingInitScan<T>,
|
|
888
889
|
BitpackingScan<T>, BitpackingScanPartial<T>, BitpackingFetchRow<T>, BitpackingSkip<T>);
|
|
889
890
|
}
|
|
890
891
|
|
|
@@ -907,6 +908,8 @@ CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
|
907
908
|
return GetBitpackingFunction<uint32_t>(type);
|
|
908
909
|
case PhysicalType::UINT64:
|
|
909
910
|
return GetBitpackingFunction<uint64_t>(type);
|
|
911
|
+
case PhysicalType::LIST:
|
|
912
|
+
return GetBitpackingFunction<uint64_t, false>(type);
|
|
910
913
|
default:
|
|
911
914
|
throw InternalException("Unsupported type for Bitpacking");
|
|
912
915
|
}
|
|
@@ -923,6 +926,7 @@ bool BitpackingFun::TypeIsSupported(PhysicalType type) {
|
|
|
923
926
|
case PhysicalType::UINT16:
|
|
924
927
|
case PhysicalType::UINT32:
|
|
925
928
|
case PhysicalType::UINT64:
|
|
929
|
+
case PhysicalType::LIST:
|
|
926
930
|
return true;
|
|
927
931
|
default:
|
|
928
932
|
return false;
|
|
@@ -153,13 +153,7 @@ void FixedSizeScan(ColumnSegment &segment, ColumnScanState &state, idx_t scan_co
|
|
|
153
153
|
auto source_data = data + start * sizeof(T);
|
|
154
154
|
|
|
155
155
|
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
156
|
-
|
|
157
|
-
// list columns are modified in-place during the scans to correct the offsets
|
|
158
|
-
// so we can't do a zero-copy there
|
|
159
|
-
memcpy(FlatVector::GetData(result), source_data, scan_count * sizeof(T));
|
|
160
|
-
} else {
|
|
161
|
-
FlatVector::SetData(result, source_data);
|
|
162
|
-
}
|
|
156
|
+
FlatVector::SetData(result, source_data);
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
//===--------------------------------------------------------------------===//
|
|
@@ -186,48 +180,52 @@ static unique_ptr<CompressionAppendState> FixedSizeInitAppend(ColumnSegment &seg
|
|
|
186
180
|
return make_unique<CompressionAppendState>(std::move(handle));
|
|
187
181
|
}
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
183
|
+
struct StandardFixedSizeAppend {
|
|
184
|
+
template <class T>
|
|
185
|
+
static void Append(SegmentStatistics &stats, data_ptr_t target, idx_t target_offset, UnifiedVectorFormat &adata,
|
|
186
|
+
idx_t offset, idx_t count) {
|
|
187
|
+
auto sdata = (T *)adata.data;
|
|
188
|
+
auto tdata = (T *)target;
|
|
189
|
+
if (!adata.validity.AllValid()) {
|
|
190
|
+
for (idx_t i = 0; i < count; i++) {
|
|
191
|
+
auto source_idx = adata.sel->get_index(offset + i);
|
|
192
|
+
auto target_idx = target_offset + i;
|
|
193
|
+
bool is_null = !adata.validity.RowIsValid(source_idx);
|
|
194
|
+
if (!is_null) {
|
|
195
|
+
NumericStatistics::Update<T>(stats, sdata[source_idx]);
|
|
196
|
+
tdata[target_idx] = sdata[source_idx];
|
|
197
|
+
} else {
|
|
198
|
+
// we insert a NullValue<T> in the null gap for debuggability
|
|
199
|
+
// this value should never be used or read anywhere
|
|
200
|
+
tdata[target_idx] = NullValue<T>();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
for (idx_t i = 0; i < count; i++) {
|
|
205
|
+
auto source_idx = adata.sel->get_index(offset + i);
|
|
206
|
+
auto target_idx = target_offset + i;
|
|
200
207
|
NumericStatistics::Update<T>(stats, sdata[source_idx]);
|
|
201
208
|
tdata[target_idx] = sdata[source_idx];
|
|
202
|
-
} else {
|
|
203
|
-
// we insert a NullValue<T> in the null gap for debuggability
|
|
204
|
-
// this value should never be used or read anywhere
|
|
205
|
-
tdata[target_idx] = NullValue<T>();
|
|
206
209
|
}
|
|
207
210
|
}
|
|
208
|
-
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
struct ListFixedSizeAppend {
|
|
215
|
+
template <class T>
|
|
216
|
+
static void Append(SegmentStatistics &stats, data_ptr_t target, idx_t target_offset, UnifiedVectorFormat &adata,
|
|
217
|
+
idx_t offset, idx_t count) {
|
|
218
|
+
auto sdata = (uint64_t *)adata.data;
|
|
219
|
+
auto tdata = (uint64_t *)target;
|
|
209
220
|
for (idx_t i = 0; i < count; i++) {
|
|
210
221
|
auto source_idx = adata.sel->get_index(offset + i);
|
|
211
222
|
auto target_idx = target_offset + i;
|
|
212
|
-
NumericStatistics::Update<T>(stats, sdata[source_idx]);
|
|
213
223
|
tdata[target_idx] = sdata[source_idx];
|
|
214
224
|
}
|
|
215
225
|
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
template <>
|
|
219
|
-
void AppendLoop<list_entry_t>(SegmentStatistics &stats, data_ptr_t target, idx_t target_offset,
|
|
220
|
-
UnifiedVectorFormat &adata, idx_t offset, idx_t count) {
|
|
221
|
-
auto sdata = (list_entry_t *)adata.data;
|
|
222
|
-
auto tdata = (list_entry_t *)target;
|
|
223
|
-
for (idx_t i = 0; i < count; i++) {
|
|
224
|
-
auto source_idx = adata.sel->get_index(offset + i);
|
|
225
|
-
auto target_idx = target_offset + i;
|
|
226
|
-
tdata[target_idx] = sdata[source_idx];
|
|
227
|
-
}
|
|
228
|
-
}
|
|
226
|
+
};
|
|
229
227
|
|
|
230
|
-
template <class T>
|
|
228
|
+
template <class T, class OP>
|
|
231
229
|
idx_t FixedSizeAppend(CompressionAppendState &append_state, ColumnSegment &segment, SegmentStatistics &stats,
|
|
232
230
|
UnifiedVectorFormat &data, idx_t offset, idx_t count) {
|
|
233
231
|
D_ASSERT(segment.GetBlockOffset() == 0);
|
|
@@ -236,7 +234,7 @@ idx_t FixedSizeAppend(CompressionAppendState &append_state, ColumnSegment &segme
|
|
|
236
234
|
idx_t max_tuple_count = segment.SegmentSize() / sizeof(T);
|
|
237
235
|
idx_t copy_count = MinValue<idx_t>(count, max_tuple_count - segment.count);
|
|
238
236
|
|
|
239
|
-
|
|
237
|
+
OP::template Append<T>(stats, target_ptr, segment.count, data, offset, copy_count);
|
|
240
238
|
segment.count += copy_count;
|
|
241
239
|
return copy_count;
|
|
242
240
|
}
|
|
@@ -249,14 +247,14 @@ idx_t FixedSizeFinalizeAppend(ColumnSegment &segment, SegmentStatistics &stats)
|
|
|
249
247
|
//===--------------------------------------------------------------------===//
|
|
250
248
|
// Get Function
|
|
251
249
|
//===--------------------------------------------------------------------===//
|
|
252
|
-
template <class T>
|
|
250
|
+
template <class T, class APPENDER = StandardFixedSizeAppend>
|
|
253
251
|
CompressionFunction FixedSizeGetFunction(PhysicalType data_type) {
|
|
254
252
|
return CompressionFunction(CompressionType::COMPRESSION_UNCOMPRESSED, data_type, FixedSizeInitAnalyze,
|
|
255
253
|
FixedSizeAnalyze, FixedSizeFinalAnalyze<T>, UncompressedFunctions::InitCompression,
|
|
256
254
|
UncompressedFunctions::Compress, UncompressedFunctions::FinalizeCompress,
|
|
257
255
|
FixedSizeInitScan, FixedSizeScan<T>, FixedSizeScanPartial<T>, FixedSizeFetchRow<T>,
|
|
258
|
-
UncompressedFunctions::EmptySkip, nullptr, FixedSizeInitAppend,
|
|
259
|
-
FixedSizeFinalizeAppend<T>, nullptr);
|
|
256
|
+
UncompressedFunctions::EmptySkip, nullptr, FixedSizeInitAppend,
|
|
257
|
+
FixedSizeAppend<T, APPENDER>, FixedSizeFinalizeAppend<T>, nullptr);
|
|
260
258
|
}
|
|
261
259
|
|
|
262
260
|
CompressionFunction FixedSizeUncompressed::GetFunction(PhysicalType data_type) {
|
|
@@ -287,7 +285,7 @@ CompressionFunction FixedSizeUncompressed::GetFunction(PhysicalType data_type) {
|
|
|
287
285
|
case PhysicalType::INTERVAL:
|
|
288
286
|
return FixedSizeGetFunction<interval_t>(data_type);
|
|
289
287
|
case PhysicalType::LIST:
|
|
290
|
-
return FixedSizeGetFunction<
|
|
288
|
+
return FixedSizeGetFunction<uint64_t, ListFixedSizeAppend>(data_type);
|
|
291
289
|
default:
|
|
292
290
|
throw InternalException("Unsupported type for FixedSizeUncompressed::GetFunction");
|
|
293
291
|
}
|
|
@@ -118,12 +118,12 @@ struct RLEConstants {
|
|
|
118
118
|
static constexpr const idx_t RLE_HEADER_SIZE = sizeof(uint64_t);
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
template <class T>
|
|
121
|
+
template <class T, bool WRITE_STATISTICS>
|
|
122
122
|
struct RLECompressState : public CompressionState {
|
|
123
123
|
struct RLEWriter {
|
|
124
124
|
template <class VALUE_TYPE>
|
|
125
125
|
static void Operation(VALUE_TYPE value, rle_count_t count, void *dataptr, bool is_null) {
|
|
126
|
-
auto state = (RLECompressState<T> *)dataptr;
|
|
126
|
+
auto state = (RLECompressState<T, WRITE_STATISTICS> *)dataptr;
|
|
127
127
|
state->WriteValue(value, count, is_null);
|
|
128
128
|
}
|
|
129
129
|
};
|
|
@@ -160,7 +160,7 @@ struct RLECompressState : public CompressionState {
|
|
|
160
160
|
auto data = (T *)vdata.data;
|
|
161
161
|
for (idx_t i = 0; i < count; i++) {
|
|
162
162
|
auto idx = vdata.sel->get_index(i);
|
|
163
|
-
state.template Update<RLECompressState<T>::RLEWriter>(data, vdata.validity, idx);
|
|
163
|
+
state.template Update<RLECompressState<T, WRITE_STATISTICS>::RLEWriter>(data, vdata.validity, idx);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -174,7 +174,7 @@ struct RLECompressState : public CompressionState {
|
|
|
174
174
|
entry_count++;
|
|
175
175
|
|
|
176
176
|
// update meta data
|
|
177
|
-
if (!is_null) {
|
|
177
|
+
if (WRITE_STATISTICS && !is_null) {
|
|
178
178
|
NumericStatistics::Update<T>(current_segment->stats, value);
|
|
179
179
|
}
|
|
180
180
|
current_segment->count += count;
|
|
@@ -206,7 +206,7 @@ struct RLECompressState : public CompressionState {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
void Finalize() {
|
|
209
|
-
state.template Flush<RLECompressState<T>::RLEWriter>();
|
|
209
|
+
state.template Flush<RLECompressState<T, WRITE_STATISTICS>::RLEWriter>();
|
|
210
210
|
|
|
211
211
|
FlushSegment();
|
|
212
212
|
current_segment.reset();
|
|
@@ -222,23 +222,23 @@ struct RLECompressState : public CompressionState {
|
|
|
222
222
|
idx_t max_rle_count;
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
-
template <class T>
|
|
225
|
+
template <class T, bool WRITE_STATISTICS>
|
|
226
226
|
unique_ptr<CompressionState> RLEInitCompression(ColumnDataCheckpointer &checkpointer, unique_ptr<AnalyzeState> state) {
|
|
227
|
-
return make_unique<RLECompressState<T>>(checkpointer);
|
|
227
|
+
return make_unique<RLECompressState<T, WRITE_STATISTICS>>(checkpointer);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
template <class T>
|
|
230
|
+
template <class T, bool WRITE_STATISTICS>
|
|
231
231
|
void RLECompress(CompressionState &state_p, Vector &scan_vector, idx_t count) {
|
|
232
|
-
auto &state = (RLECompressState<T> &)state_p;
|
|
232
|
+
auto &state = (RLECompressState<T, WRITE_STATISTICS> &)state_p;
|
|
233
233
|
UnifiedVectorFormat vdata;
|
|
234
234
|
scan_vector.ToUnifiedFormat(count, vdata);
|
|
235
235
|
|
|
236
236
|
state.Append(vdata, count);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
template <class T>
|
|
239
|
+
template <class T, bool WRITE_STATISTICS>
|
|
240
240
|
void RLEFinalizeCompress(CompressionState &state_p) {
|
|
241
|
-
auto &state = (RLECompressState<T> &)state_p;
|
|
241
|
+
auto &state = (RLECompressState<T, WRITE_STATISTICS> &)state_p;
|
|
242
242
|
state.Finalize();
|
|
243
243
|
}
|
|
244
244
|
|
|
@@ -341,10 +341,11 @@ void RLEFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id,
|
|
|
341
341
|
//===--------------------------------------------------------------------===//
|
|
342
342
|
// Get Function
|
|
343
343
|
//===--------------------------------------------------------------------===//
|
|
344
|
-
template <class T>
|
|
344
|
+
template <class T, bool WRITE_STATISTICS = true>
|
|
345
345
|
CompressionFunction GetRLEFunction(PhysicalType data_type) {
|
|
346
346
|
return CompressionFunction(CompressionType::COMPRESSION_RLE, data_type, RLEInitAnalyze<T>, RLEAnalyze<T>,
|
|
347
|
-
RLEFinalAnalyze<T>, RLEInitCompression<T
|
|
347
|
+
RLEFinalAnalyze<T>, RLEInitCompression<T, WRITE_STATISTICS>,
|
|
348
|
+
RLECompress<T, WRITE_STATISTICS>, RLEFinalizeCompress<T, WRITE_STATISTICS>,
|
|
348
349
|
RLEInitScan<T>, RLEScan<T>, RLEScanPartial<T>, RLEFetchRow<T>, RLESkip<T>);
|
|
349
350
|
}
|
|
350
351
|
|
|
@@ -373,6 +374,8 @@ CompressionFunction RLEFun::GetFunction(PhysicalType type) {
|
|
|
373
374
|
return GetRLEFunction<float>(type);
|
|
374
375
|
case PhysicalType::DOUBLE:
|
|
375
376
|
return GetRLEFunction<double>(type);
|
|
377
|
+
case PhysicalType::LIST:
|
|
378
|
+
return GetRLEFunction<uint64_t, false>(type);
|
|
376
379
|
default:
|
|
377
380
|
throw InternalException("Unsupported type for RLE");
|
|
378
381
|
}
|
|
@@ -392,6 +395,7 @@ bool RLEFun::TypeIsSupported(PhysicalType type) {
|
|
|
392
395
|
case PhysicalType::UINT64:
|
|
393
396
|
case PhysicalType::FLOAT:
|
|
394
397
|
case PhysicalType::DOUBLE:
|
|
398
|
+
case PhysicalType::LIST:
|
|
395
399
|
return true;
|
|
396
400
|
default:
|
|
397
401
|
return false;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
namespace duckdb {
|
|
13
13
|
|
|
14
14
|
BaseStatistics::BaseStatistics(LogicalType type, StatisticsType stats_type)
|
|
15
|
-
: type(std::move(type)), stats_type(stats_type) {
|
|
15
|
+
: type(std::move(type)), distinct_count(0), stats_type(stats_type) {
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
BaseStatistics::~BaseStatistics() {
|
|
@@ -72,9 +72,9 @@ void BaseStatistics::Merge(const BaseStatistics &other) {
|
|
|
72
72
|
idx_t BaseStatistics::GetDistinctCount() {
|
|
73
73
|
if (distinct_stats) {
|
|
74
74
|
auto &d_stats = (DistinctStatistics &)*distinct_stats;
|
|
75
|
-
|
|
75
|
+
distinct_count = d_stats.GetCount();
|
|
76
76
|
}
|
|
77
|
-
return
|
|
77
|
+
return distinct_count;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
unique_ptr<BaseStatistics> BaseStatistics::CreateEmpty(LogicalType type, StatisticsType stats_type) {
|