duckdb 0.7.2-dev1803.0 → 0.7.2-dev1898.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.
Files changed (158) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/src/catalog/catalog.cpp +27 -27
  3. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +6 -6
  4. package/src/duckdb/src/catalog/catalog_set.cpp +27 -25
  5. package/src/duckdb/src/catalog/default/default_functions.cpp +6 -6
  6. package/src/duckdb/src/catalog/default/default_types.cpp +4 -4
  7. package/src/duckdb/src/catalog/default/default_views.cpp +4 -4
  8. package/src/duckdb/src/catalog/dependency_list.cpp +7 -6
  9. package/src/duckdb/src/catalog/dependency_manager.cpp +44 -38
  10. package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +11 -6
  11. package/src/duckdb/src/common/sort/sorted_block.cpp +9 -4
  12. package/src/duckdb/src/common/types/batched_data_collection.cpp +2 -1
  13. package/src/duckdb/src/common/types/column_data_allocator.cpp +1 -0
  14. package/src/duckdb/src/common/types/vector.cpp +2 -2
  15. package/src/duckdb/src/common/vector_operations/vector_copy.cpp +14 -11
  16. package/src/duckdb/src/execution/operator/aggregate/distinct_aggregate_data.cpp +1 -1
  17. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +51 -50
  18. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +4 -0
  19. package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +14 -13
  20. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +20 -20
  21. package/src/duckdb/src/execution/operator/schema/physical_create_table.cpp +2 -2
  22. package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +1 -1
  23. package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +3 -3
  24. package/src/duckdb/src/execution/physical_plan/plan_delete.cpp +1 -1
  25. package/src/duckdb/src/execution/physical_plan/plan_insert.cpp +1 -1
  26. package/src/duckdb/src/execution/physical_plan/plan_update.cpp +1 -1
  27. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +172 -63
  28. package/src/duckdb/src/function/cast/cast_function_set.cpp +2 -1
  29. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +15 -9
  30. package/src/duckdb/src/function/scalar/sequence/nextval.cpp +29 -29
  31. package/src/duckdb/src/function/scalar/string/damerau_levenshtein.cpp +106 -0
  32. package/src/duckdb/src/function/scalar/string/regexp.cpp +145 -28
  33. package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
  34. package/src/duckdb/src/function/table/checkpoint.cpp +4 -4
  35. package/src/duckdb/src/function/table/system/duckdb_columns.cpp +24 -24
  36. package/src/duckdb/src/function/table/system/duckdb_constraints.cpp +7 -6
  37. package/src/duckdb/src/function/table/system/duckdb_databases.cpp +1 -1
  38. package/src/duckdb/src/function/table/system/duckdb_dependencies.cpp +11 -11
  39. package/src/duckdb/src/function/table/system/pragma_database_size.cpp +1 -1
  40. package/src/duckdb/src/function/table/system/pragma_table_info.cpp +17 -18
  41. package/src/duckdb/src/function/table/table_scan.cpp +8 -11
  42. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  43. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +9 -9
  44. package/src/duckdb/src/include/duckdb/catalog/catalog_entry_map.hpp +38 -0
  45. package/src/duckdb/src/include/duckdb/catalog/catalog_transaction.hpp +4 -3
  46. package/src/duckdb/src/include/duckdb/catalog/default/default_functions.hpp +2 -2
  47. package/src/duckdb/src/include/duckdb/catalog/default/default_types.hpp +2 -2
  48. package/src/duckdb/src/include/duckdb/catalog/default/default_views.hpp +2 -2
  49. package/src/duckdb/src/include/duckdb/catalog/dependency.hpp +4 -5
  50. package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +4 -5
  51. package/src/duckdb/src/include/duckdb/catalog/dependency_manager.hpp +10 -9
  52. package/src/duckdb/src/include/duckdb/common/allocator.hpp +2 -1
  53. package/src/duckdb/src/include/duckdb/common/field_writer.hpp +1 -1
  54. package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -0
  55. package/src/duckdb/src/include/duckdb/common/optional_ptr.hpp +29 -6
  56. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +6 -5
  57. package/src/duckdb/src/include/duckdb/common/serializer.hpp +1 -1
  58. package/src/duckdb/src/include/duckdb/common/types/row_data_collection.hpp +1 -0
  59. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_insert.hpp +2 -2
  60. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +5 -5
  61. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_create_table.hpp +2 -2
  62. package/src/duckdb/src/include/duckdb/function/cast/default_casts.hpp +3 -2
  63. package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +4 -0
  64. package/src/duckdb/src/include/duckdb/main/client_config.hpp +5 -0
  65. package/src/duckdb/src/include/duckdb/main/database_manager.hpp +4 -3
  66. package/src/duckdb/src/include/duckdb/main/query_result.hpp +3 -2
  67. package/src/duckdb/src/include/duckdb/main/settings.hpp +19 -0
  68. package/src/duckdb/src/include/duckdb/optimizer/filter_combiner.hpp +7 -7
  69. package/src/duckdb/src/include/duckdb/optimizer/matcher/expression_matcher.hpp +11 -11
  70. package/src/duckdb/src/include/duckdb/optimizer/matcher/set_matcher.hpp +8 -8
  71. package/src/duckdb/src/include/duckdb/optimizer/rule/arithmetic_simplification.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/optimizer/rule/case_simplification.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/optimizer/rule/comparison_simplification.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/optimizer/rule/conjunction_simplification.hpp +2 -2
  75. package/src/duckdb/src/include/duckdb/optimizer/rule/constant_folding.hpp +1 -1
  76. package/src/duckdb/src/include/duckdb/optimizer/rule/date_part_simplification.hpp +1 -1
  77. package/src/duckdb/src/include/duckdb/optimizer/rule/distributivity.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/optimizer/rule/empty_needle_removal.hpp +1 -1
  79. package/src/duckdb/src/include/duckdb/optimizer/rule/enum_comparison.hpp +1 -1
  80. package/src/duckdb/src/include/duckdb/optimizer/rule/equal_or_null_simplification.hpp +1 -1
  81. package/src/duckdb/src/include/duckdb/optimizer/rule/in_clause_simplification.hpp +1 -1
  82. package/src/duckdb/src/include/duckdb/optimizer/rule/like_optimizations.hpp +1 -1
  83. package/src/duckdb/src/include/duckdb/optimizer/rule/move_constants.hpp +1 -1
  84. package/src/duckdb/src/include/duckdb/optimizer/rule/ordered_aggregate_optimizer.hpp +1 -1
  85. package/src/duckdb/src/include/duckdb/optimizer/rule/regex_optimizations.hpp +1 -1
  86. package/src/duckdb/src/include/duckdb/optimizer/rule.hpp +2 -2
  87. package/src/duckdb/src/include/duckdb/parser/base_expression.hpp +1 -1
  88. package/src/duckdb/src/include/duckdb/parser/expression_map.hpp +19 -6
  89. package/src/duckdb/src/include/duckdb/parser/expression_util.hpp +1 -1
  90. package/src/duckdb/src/include/duckdb/parser/parser.hpp +1 -7
  91. package/src/duckdb/src/include/duckdb/parser/parser_options.hpp +23 -0
  92. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +5 -3
  93. package/src/duckdb/src/include/duckdb/planner/expression.hpp +5 -2
  94. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -1
  95. package/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp +3 -3
  96. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +10 -2
  97. package/src/duckdb/src/include/duckdb/storage/buffer/buffer_pool.hpp +1 -0
  98. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +49 -126
  99. package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +5 -5
  100. package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +159 -0
  101. package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +1 -0
  102. package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +6 -5
  103. package/src/duckdb/src/main/client_context.cpp +5 -3
  104. package/src/duckdb/src/main/config.cpp +2 -0
  105. package/src/duckdb/src/main/database.cpp +2 -1
  106. package/src/duckdb/src/main/database_manager.cpp +4 -4
  107. package/src/duckdb/src/main/settings/settings.cpp +36 -0
  108. package/src/duckdb/src/optimizer/common_aggregate_optimizer.cpp +2 -2
  109. package/src/duckdb/src/optimizer/cse_optimizer.cpp +4 -4
  110. package/src/duckdb/src/optimizer/deliminator.cpp +13 -11
  111. package/src/duckdb/src/optimizer/expression_rewriter.cpp +2 -2
  112. package/src/duckdb/src/optimizer/filter_combiner.cpp +67 -65
  113. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +1 -0
  114. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +26 -25
  115. package/src/duckdb/src/optimizer/matcher/expression_matcher.cpp +23 -21
  116. package/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp +7 -6
  117. package/src/duckdb/src/optimizer/rule/case_simplification.cpp +2 -2
  118. package/src/duckdb/src/optimizer/rule/comparison_simplification.cpp +6 -7
  119. package/src/duckdb/src/optimizer/rule/conjunction_simplification.cpp +9 -8
  120. package/src/duckdb/src/optimizer/rule/constant_folding.cpp +7 -7
  121. package/src/duckdb/src/optimizer/rule/date_part_simplification.cpp +3 -3
  122. package/src/duckdb/src/optimizer/rule/distributivity.cpp +5 -5
  123. package/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp +6 -6
  124. package/src/duckdb/src/optimizer/rule/enum_comparison.cpp +4 -4
  125. package/src/duckdb/src/optimizer/rule/equal_or_null_simplification.cpp +23 -26
  126. package/src/duckdb/src/optimizer/rule/in_clause_simplification_rule.cpp +2 -3
  127. package/src/duckdb/src/optimizer/rule/like_optimizations.cpp +3 -3
  128. package/src/duckdb/src/optimizer/rule/move_constants.cpp +6 -6
  129. package/src/duckdb/src/optimizer/rule/ordered_aggregate_optimizer.cpp +2 -2
  130. package/src/duckdb/src/optimizer/rule/regex_optimizations.cpp +3 -3
  131. package/src/duckdb/src/parser/expression_util.cpp +6 -6
  132. package/src/duckdb/src/parser/parser.cpp +1 -1
  133. package/src/duckdb/src/parser/transform/expression/transform_operator.cpp +7 -3
  134. package/src/duckdb/src/parser/transform/helpers/transform_groupby.cpp +3 -3
  135. package/src/duckdb/src/parser/transformer.cpp +6 -5
  136. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +2 -2
  137. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +3 -3
  138. package/src/duckdb/src/planner/binder/query_node/bind_setop_node.cpp +5 -5
  139. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +2 -2
  140. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +4 -4
  141. package/src/duckdb/src/planner/expression_binder/order_binder.cpp +3 -3
  142. package/src/duckdb/src/storage/buffer/block_handle.cpp +3 -2
  143. package/src/duckdb/src/storage/buffer/block_manager.cpp +3 -1
  144. package/src/duckdb/src/storage/buffer/buffer_handle.cpp +1 -0
  145. package/src/duckdb/src/storage/buffer/buffer_pool_reservation.cpp +3 -0
  146. package/src/duckdb/src/storage/buffer_manager.cpp +35 -726
  147. package/src/duckdb/src/storage/checkpoint_manager.cpp +2 -2
  148. package/src/duckdb/src/storage/meta_block_reader.cpp +6 -5
  149. package/src/duckdb/src/storage/standard_buffer_manager.cpp +801 -0
  150. package/src/duckdb/src/storage/wal_replay.cpp +2 -2
  151. package/src/duckdb/src/transaction/meta_transaction.cpp +13 -13
  152. package/src/duckdb/src/transaction/transaction.cpp +1 -1
  153. package/src/duckdb/src/transaction/transaction_context.cpp +1 -1
  154. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +949 -947
  155. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +16431 -16385
  156. package/src/duckdb/third_party/libpg_query/src_backend_parser_scan.cpp +503 -493
  157. package/src/duckdb/ub_src_function_scalar_string.cpp +2 -0
  158. package/src/duckdb/ub_src_storage.cpp +2 -0
@@ -22,9 +22,9 @@ class SelectNode;
22
22
  class OrderBinder {
23
23
  public:
24
24
  OrderBinder(vector<Binder *> binders, idx_t projection_index, case_insensitive_map_t<idx_t> &alias_map,
25
- expression_map_t<idx_t> &projection_map, idx_t max_count);
25
+ parsed_expression_map_t<idx_t> &projection_map, idx_t max_count);
26
26
  OrderBinder(vector<Binder *> binders, idx_t projection_index, SelectNode &node,
27
- case_insensitive_map_t<idx_t> &alias_map, expression_map_t<idx_t> &projection_map);
27
+ case_insensitive_map_t<idx_t> &alias_map, parsed_expression_map_t<idx_t> &projection_map);
28
28
 
29
29
  public:
30
30
  unique_ptr<Expression> Bind(unique_ptr<ParsedExpression> expr);
@@ -51,7 +51,7 @@ private:
51
51
  idx_t max_count;
52
52
  vector<unique_ptr<ParsedExpression>> *extra_list;
53
53
  case_insensitive_map_t<idx_t> &alias_map;
54
- expression_map_t<idx_t> &projection_map;
54
+ parsed_expression_map_t<idx_t> &projection_map;
55
55
  };
56
56
 
57
57
  } // namespace duckdb
@@ -26,8 +26,7 @@ struct BufferPoolReservation {
26
26
  idx_t size {0};
27
27
  BufferPool &pool;
28
28
 
29
- BufferPoolReservation(BufferPool &pool) : pool(pool) {
30
- }
29
+ BufferPoolReservation(BufferPool &pool);
31
30
  BufferPoolReservation(const BufferPoolReservation &) = delete;
32
31
  BufferPoolReservation &operator=(const BufferPoolReservation &) = delete;
33
32
 
@@ -55,6 +54,7 @@ class BlockHandle {
55
54
  friend struct BufferEvictionNode;
56
55
  friend class BufferHandle;
57
56
  friend class BufferManager;
57
+ friend class StandardBufferManager;
58
58
  friend class BufferPool;
59
59
 
60
60
  public:
@@ -70,6 +70,14 @@ public:
70
70
  return block_id;
71
71
  }
72
72
 
73
+ void ResizeBuffer(idx_t block_size, int64_t memory_delta) {
74
+ D_ASSERT(buffer);
75
+ // resize and adjust current memory
76
+ buffer->Resize(block_size);
77
+ memory_usage += memory_delta;
78
+ D_ASSERT(memory_usage == buffer->AllocSize());
79
+ }
80
+
73
81
  int32_t Readers() const {
74
82
  return readers;
75
83
  }
@@ -30,6 +30,7 @@ class BufferPool {
30
30
  friend class BlockHandle;
31
31
  friend class BlockManager;
32
32
  friend class BufferManager;
33
+ friend class StandardBufferManager;
33
34
 
34
35
  public:
35
36
  explicit BufferPool(idx_t maximum_memory);
@@ -8,156 +8,79 @@
8
8
 
9
9
  #pragma once
10
10
 
11
- #include "duckdb/common/allocator.hpp"
12
- #include "duckdb/common/atomic.hpp"
13
- #include "duckdb/common/file_system.hpp"
14
- #include "duckdb/common/mutex.hpp"
15
- #include "duckdb/common/unordered_map.hpp"
16
- #include "duckdb/storage/block_manager.hpp"
17
- #include "duckdb/storage/buffer/block_handle.hpp"
11
+ #include "duckdb/storage/buffer_manager.hpp"
18
12
  #include "duckdb/storage/buffer/buffer_handle.hpp"
19
- #include "duckdb/storage/buffer/buffer_pool.hpp"
13
+ #include "duckdb/storage/block_manager.hpp"
14
+ #include "duckdb/common/file_system.hpp"
20
15
  #include "duckdb/storage/buffer/temporary_file_information.hpp"
16
+ #include "duckdb/main/config.hpp"
21
17
 
22
18
  namespace duckdb {
23
- class BlockManager;
24
- class DatabaseInstance;
25
- class TemporaryDirectoryHandle;
26
- struct EvictionQueue;
27
19
 
28
- //! The BufferManager is in charge of handling memory management for a single database. It cooperatively shares a
29
- //! BufferPool with other BufferManagers, belonging to different databases. It hands out memory buffers that can
30
- //! be used by the database internally, and offers configuration options specific to a database, which need not be
31
- //! shared by the BufferPool, including whether to support swapping temp buffers to disk, and where to swap them to.
20
+ class Allocator;
21
+ class BufferPool;
22
+
32
23
  class BufferManager {
33
24
  friend class BufferHandle;
34
25
  friend class BlockHandle;
35
26
  friend class BlockManager;
36
27
 
37
28
  public:
38
- BufferManager(DatabaseInstance &db, string temp_directory);
39
- virtual ~BufferManager();
40
-
41
- //! Registers an in-memory buffer that cannot be unloaded until it is destroyed
42
- //! This buffer can be small (smaller than BLOCK_SIZE)
43
- //! Unpin and pin are nops on this block of memory
44
- shared_ptr<BlockHandle> RegisterSmallMemory(idx_t block_size);
45
-
46
- //! Allocate an in-memory buffer with a single pin.
47
- //! The allocated memory is released when the buffer handle is destroyed.
48
- DUCKDB_API BufferHandle Allocate(idx_t block_size, bool can_destroy = true,
49
- shared_ptr<BlockHandle> *block = nullptr);
29
+ BufferManager() {
30
+ }
31
+ virtual ~BufferManager() {
32
+ }
50
33
 
34
+ public:
35
+ static unique_ptr<BufferManager> CreateStandardBufferManager(DatabaseInstance &db, DBConfig &config);
36
+ virtual BufferHandle Allocate(idx_t block_size, bool can_destroy = true,
37
+ shared_ptr<BlockHandle> *block = nullptr) = 0;
51
38
  //! Reallocate an in-memory buffer that is pinned.
52
- void ReAllocate(shared_ptr<BlockHandle> &handle, idx_t block_size);
53
-
54
- BufferHandle Pin(shared_ptr<BlockHandle> &handle);
55
- void Unpin(shared_ptr<BlockHandle> &handle);
56
-
57
- DUCKDB_API static BufferManager &GetBufferManager(ClientContext &context);
58
- DUCKDB_API static BufferManager &GetBufferManager(DatabaseInstance &db);
59
- DUCKDB_API static BufferManager &GetBufferManager(AttachedDatabase &db);
60
-
39
+ virtual void ReAllocate(shared_ptr<BlockHandle> &handle, idx_t block_size) = 0;
40
+ virtual BufferHandle Pin(shared_ptr<BlockHandle> &handle) = 0;
41
+ virtual void Unpin(shared_ptr<BlockHandle> &handle) = 0;
61
42
  //! Returns the currently allocated memory
62
- idx_t GetUsedMemory() {
63
- return buffer_pool.current_memory;
64
- }
43
+ virtual idx_t GetUsedMemory() const = 0;
65
44
  //! Returns the maximum available memory
66
- idx_t GetMaxMemory() {
67
- return buffer_pool.maximum_memory;
68
- }
69
-
45
+ virtual idx_t GetMaxMemory() const = 0;
46
+ virtual shared_ptr<BlockHandle> RegisterSmallMemory(idx_t block_size);
47
+ virtual DUCKDB_API Allocator &GetBufferAllocator();
48
+ virtual DUCKDB_API void ReserveMemory(idx_t size);
49
+ virtual DUCKDB_API void FreeReservedMemory(idx_t size);
50
+ //! Set a new memory limit to the buffer manager, throws an exception if the new limit is too low and not enough
51
+ //! blocks can be evicted
52
+ virtual void SetLimit(idx_t limit = (idx_t)-1);
53
+ virtual vector<TemporaryFileInformation> GetTemporaryFiles();
54
+ virtual const string &GetTemporaryDirectory();
55
+ virtual void SetTemporaryDirectory(const string &new_dir);
56
+ virtual DatabaseInstance &GetDatabase();
57
+ virtual bool HasTemporaryDirectory() const;
58
+ //! Construct a managed buffer.
59
+ virtual unique_ptr<FileBuffer> ConstructManagedBuffer(idx_t size, unique_ptr<FileBuffer> &&source,
60
+ FileBufferType type = FileBufferType::MANAGED_BUFFER);
70
61
  //! Increases the currently allocated memory, but the actual allocation does not go through the buffer manager
71
- void IncreaseUsedMemory(idx_t size);
62
+ virtual void IncreaseUsedMemory(idx_t size, bool unsafe = false) = 0;
72
63
  //! Decrease the currently allocated memory, but the actual deallocation does not go through the buffer manager
73
- void DecreaseUsedMemory(idx_t size);
74
-
75
- const string &GetTemporaryDirectory() {
76
- return temp_directory;
77
- }
78
-
79
- void SetTemporaryDirectory(string new_dir);
80
-
81
- DUCKDB_API Allocator &GetBufferAllocator();
64
+ virtual void DecreaseUsedMemory(idx_t size) = 0;
65
+ //! Get the underlying buffer pool responsible for managing the buffers
66
+ virtual BufferPool &GetBufferPool();
82
67
 
83
- DatabaseInstance &GetDatabase() {
84
- return db;
85
- }
68
+ // Static methods
86
69
 
87
- BufferPool &GetBufferPool() {
88
- return buffer_pool;
89
- }
70
+ DUCKDB_API static BufferManager &GetBufferManager(DatabaseInstance &db);
71
+ DUCKDB_API static BufferManager &GetBufferManager(ClientContext &context);
72
+ DUCKDB_API static BufferManager &GetBufferManager(AttachedDatabase &db);
90
73
 
91
74
  static idx_t GetAllocSize(idx_t block_size) {
92
75
  return AlignValue<idx_t, Storage::SECTOR_SIZE>(block_size + Storage::BLOCK_HEADER_SIZE);
93
76
  }
94
77
 
95
- //! Construct a managed buffer.
96
- unique_ptr<FileBuffer> ConstructManagedBuffer(idx_t size, unique_ptr<FileBuffer> &&source,
97
- FileBufferType type = FileBufferType::MANAGED_BUFFER);
98
-
99
- DUCKDB_API void ReserveMemory(idx_t size);
100
- DUCKDB_API void FreeReservedMemory(idx_t size);
101
-
102
- //! Set a new memory limit to the buffer pool, throws an exception if the new limit is too low and not enough
103
- //! blocks can be evicted. (Sugar for calling method directly on the BufferPool.)
104
- void SetLimit(idx_t limit = (idx_t)-1) {
105
- buffer_pool.SetLimit(limit, InMemoryWarning());
106
- }
107
- //! Returns a list of all temporary files
108
- vector<TemporaryFileInformation> GetTemporaryFiles();
109
-
110
- private:
111
- //! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or
112
- //! not the buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so
113
- //! it can be reloaded. The resulting buffer will already be allocated, but needs to be pinned in order to be used.
114
- //! This needs to be private to prevent creating blocks without ever pinning them:
115
- //! blocks that are never pinned are never added to the eviction queue
116
- shared_ptr<BlockHandle> RegisterMemory(idx_t block_size, bool can_destroy);
117
-
118
- //! Write a temporary buffer to disk
119
- void WriteTemporaryBuffer(block_id_t block_id, FileBuffer &buffer);
120
- //! Read a temporary buffer from disk
121
- unique_ptr<FileBuffer> ReadTemporaryBuffer(block_id_t id, unique_ptr<FileBuffer> buffer = nullptr);
122
- //! Get the path of the temporary buffer
123
- string GetTemporaryPath(block_id_t id);
124
-
125
- void DeleteTemporaryFile(block_id_t id);
126
-
127
- void RequireTemporaryDirectory();
128
-
129
- const char *InMemoryWarning();
130
-
131
- static data_ptr_t BufferAllocatorAllocate(PrivateAllocatorData *private_data, idx_t size);
132
- static void BufferAllocatorFree(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size);
133
- static data_ptr_t BufferAllocatorRealloc(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t old_size,
134
- idx_t size);
135
-
136
- //! When the BlockHandle reaches 0 readers, this creates a new FileBuffer for this BlockHandle and
137
- //! overwrites the data within with garbage. Any readers that do not hold the pin will notice
138
- void VerifyZeroReaders(shared_ptr<BlockHandle> &handle);
139
-
140
- //! Helper
141
- template <typename... ARGS>
142
- TempBufferPoolReservation EvictBlocksOrThrow(idx_t extra_memory, unique_ptr<FileBuffer> *buffer, ARGS...);
143
-
144
- private:
145
- //! The database instance
146
- DatabaseInstance &db;
147
- //! The buffer pool
148
- BufferPool &buffer_pool;
149
- //! The directory name where temporary files are stored
150
- string temp_directory;
151
- //! Lock for creating the temp handle
152
- mutex temp_handle_lock;
153
- //! Handle for the temporary directory
154
- unique_ptr<TemporaryDirectoryHandle> temp_directory_handle;
155
- //! The temporary id used for managed buffers
156
- atomic<block_id_t> temporary_id;
157
- //! Allocator associated with the buffer manager, that passes all allocations through this buffer manager
158
- Allocator buffer_allocator;
159
- //! Block manager for temp data
160
- unique_ptr<BlockManager> temp_block_manager;
78
+ protected:
79
+ virtual void PurgeQueue() = 0;
80
+ virtual void AddToEvictionQueue(shared_ptr<BlockHandle> &handle);
81
+ virtual void WriteTemporaryBuffer(block_id_t block_id, FileBuffer &buffer);
82
+ virtual unique_ptr<FileBuffer> ReadTemporaryBuffer(block_id_t id, unique_ptr<FileBuffer> buffer);
83
+ virtual void DeleteTemporaryFile(block_id_t id);
161
84
  };
162
85
 
163
86
  } // namespace duckdb
@@ -37,13 +37,13 @@ public:
37
37
  void ReadData(data_ptr_t buffer, idx_t read_size) override;
38
38
 
39
39
  ClientContext &GetContext() override;
40
- Catalog *GetCatalog() override;
41
- void SetCatalog(Catalog *catalog_p);
42
- void SetContext(ClientContext *context_p);
40
+ optional_ptr<Catalog> GetCatalog() override;
41
+ void SetCatalog(Catalog &catalog_p);
42
+ void SetContext(ClientContext &context_p);
43
43
 
44
44
  private:
45
45
  void ReadNewBlock(block_id_t id);
46
- Catalog *catalog = nullptr;
47
- ClientContext *context = nullptr;
46
+ optional_ptr<ClientContext> context;
47
+ optional_ptr<Catalog> catalog;
48
48
  };
49
49
  } // namespace duckdb
@@ -0,0 +1,159 @@
1
+ //===----------------------------------------------------------------------===//
2
+ // DuckDB
3
+ //
4
+ // duckdb/storage/standard_buffer_manager.hpp
5
+ //
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+
9
+ #pragma once
10
+
11
+ #include "duckdb/common/allocator.hpp"
12
+ #include "duckdb/common/atomic.hpp"
13
+ #include "duckdb/common/file_system.hpp"
14
+ #include "duckdb/common/mutex.hpp"
15
+ #include "duckdb/storage/block_manager.hpp"
16
+
17
+ #include "duckdb/storage/buffer/block_handle.hpp"
18
+ #include "duckdb/storage/buffer_manager.hpp"
19
+ #include "duckdb/storage/buffer/buffer_pool.hpp"
20
+
21
+ namespace duckdb {
22
+ class BlockManager;
23
+ class DatabaseInstance;
24
+ class TemporaryDirectoryHandle;
25
+ struct EvictionQueue;
26
+
27
+ //! The BufferManager is in charge of handling memory management for a single database. It cooperatively shares a
28
+ //! BufferPool with other BufferManagers, belonging to different databases. It hands out memory buffers that can
29
+ //! be used by the database internally, and offers configuration options specific to a database, which need not be
30
+ //! shared by the BufferPool, including whether to support swapping temp buffers to disk, and where to swap them to.
31
+ class StandardBufferManager : public BufferManager {
32
+ friend class BufferHandle;
33
+ friend class BlockHandle;
34
+ friend class BlockManager;
35
+
36
+ public:
37
+ StandardBufferManager(DatabaseInstance &db, string temp_directory);
38
+ virtual ~StandardBufferManager();
39
+
40
+ public:
41
+ static unique_ptr<StandardBufferManager> CreateBufferManager(DatabaseInstance &db, string temp_directory);
42
+ //! Registers an in-memory buffer that cannot be unloaded until it is destroyed
43
+ //! This buffer can be small (smaller than BLOCK_SIZE)
44
+ //! Unpin and pin are nops on this block of memory
45
+ shared_ptr<BlockHandle> RegisterSmallMemory(idx_t block_size) final override;
46
+
47
+ idx_t GetUsedMemory() const final override;
48
+ void IncreaseUsedMemory(idx_t amount, bool unsafe = false) final override;
49
+ void DecreaseUsedMemory(idx_t amount) final override;
50
+ idx_t GetMaxMemory() const final override;
51
+
52
+ //! Allocate an in-memory buffer with a single pin.
53
+ //! The allocated memory is released when the buffer handle is destroyed.
54
+ DUCKDB_API BufferHandle Allocate(idx_t block_size, bool can_destroy = true,
55
+ shared_ptr<BlockHandle> *block = nullptr) final override;
56
+
57
+ //! Reallocate an in-memory buffer that is pinned.
58
+ void ReAllocate(shared_ptr<BlockHandle> &handle, idx_t block_size) final override;
59
+
60
+ BufferHandle Pin(shared_ptr<BlockHandle> &handle) final override;
61
+ void Unpin(shared_ptr<BlockHandle> &handle) final override;
62
+
63
+ //! Set a new memory limit to the buffer manager, throws an exception if the new limit is too low and not enough
64
+ //! blocks can be evicted
65
+ void SetLimit(idx_t limit = (idx_t)-1) final override;
66
+
67
+ //! Returns a list of all temporary files
68
+ vector<TemporaryFileInformation> GetTemporaryFiles() final override;
69
+
70
+ const string &GetTemporaryDirectory() final override {
71
+ return temp_directory;
72
+ }
73
+
74
+ void SetTemporaryDirectory(const string &new_dir) final override;
75
+
76
+ DUCKDB_API Allocator &GetBufferAllocator() final override;
77
+
78
+ DatabaseInstance &GetDatabase() final override {
79
+ return db;
80
+ }
81
+
82
+ //! Construct a managed buffer.
83
+ unique_ptr<FileBuffer> ConstructManagedBuffer(idx_t size, unique_ptr<FileBuffer> &&source,
84
+ FileBufferType type = FileBufferType::MANAGED_BUFFER) override;
85
+
86
+ DUCKDB_API void ReserveMemory(idx_t size) final override;
87
+ DUCKDB_API void FreeReservedMemory(idx_t size) final override;
88
+ bool HasTemporaryDirectory() const final override;
89
+
90
+ protected:
91
+ //! Helper
92
+ template <typename... ARGS>
93
+ TempBufferPoolReservation EvictBlocksOrThrow(idx_t memory_delta, unique_ptr<FileBuffer> *buffer, ARGS...);
94
+
95
+ //! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or
96
+ //! not the buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so
97
+ //! it can be reloaded. The resulting buffer will already be allocated, but needs to be pinned in order to be used.
98
+ //! This needs to be private to prevent creating blocks without ever pinning them:
99
+ //! blocks that are never pinned are never added to the eviction queue
100
+ shared_ptr<BlockHandle> RegisterMemory(idx_t block_size, bool can_destroy);
101
+
102
+ //! Evict blocks until the currently used memory + extra_memory fit, returns false if this was not possible
103
+ //! (i.e. not enough blocks could be evicted)
104
+ //! If the "buffer" argument is specified AND the system can find a buffer to re-use for the given allocation size
105
+ //! "buffer" will be made to point to the re-usable memory. Note that this is not guaranteed.
106
+ //! Returns a pair. result.first indicates if eviction was successful. result.second contains the
107
+ //! reservation handle, which can be moved to the BlockHandle that will own the reservation.
108
+ BufferPool::EvictionResult EvictBlocks(idx_t extra_memory, idx_t memory_limit,
109
+ unique_ptr<FileBuffer> *buffer = nullptr);
110
+
111
+ //! Garbage collect eviction queue
112
+ void PurgeQueue() final override;
113
+
114
+ BufferPool &GetBufferPool() final override;
115
+
116
+ //! Write a temporary buffer to disk
117
+ void WriteTemporaryBuffer(block_id_t block_id, FileBuffer &buffer) final override;
118
+ //! Read a temporary buffer from disk
119
+ unique_ptr<FileBuffer> ReadTemporaryBuffer(block_id_t id, unique_ptr<FileBuffer> buffer = nullptr) final override;
120
+ //! Get the path of the temporary buffer
121
+ string GetTemporaryPath(block_id_t id);
122
+
123
+ void DeleteTemporaryFile(block_id_t id) final override;
124
+
125
+ void RequireTemporaryDirectory();
126
+
127
+ void AddToEvictionQueue(shared_ptr<BlockHandle> &handle) final override;
128
+
129
+ const char *InMemoryWarning();
130
+
131
+ static data_ptr_t BufferAllocatorAllocate(PrivateAllocatorData *private_data, idx_t size);
132
+ static void BufferAllocatorFree(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size);
133
+ static data_ptr_t BufferAllocatorRealloc(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t old_size,
134
+ idx_t size);
135
+
136
+ //! When the BlockHandle reaches 0 readers, this creates a new FileBuffer for this BlockHandle and
137
+ //! overwrites the data within with garbage. Any readers that do not hold the pin will notice
138
+ void VerifyZeroReaders(shared_ptr<BlockHandle> &handle);
139
+
140
+ protected:
141
+ //! The database instance
142
+ DatabaseInstance &db;
143
+ //! The buffer pool
144
+ BufferPool &buffer_pool;
145
+ //! The directory name where temporary files are stored
146
+ string temp_directory;
147
+ //! Lock for creating the temp handle
148
+ mutex temp_handle_lock;
149
+ //! Handle for the temporary directory
150
+ unique_ptr<TemporaryDirectoryHandle> temp_directory_handle;
151
+ //! The temporary id used for managed buffers
152
+ atomic<block_id_t> temporary_id;
153
+ //! Allocator associated with the buffer manager, that passes all allocations through this buffer manager
154
+ Allocator buffer_allocator;
155
+ //! Block manager for temp data
156
+ unique_ptr<BlockManager> temp_block_manager;
157
+ };
158
+
159
+ } // namespace duckdb
@@ -16,6 +16,7 @@
16
16
  #include "duckdb/storage/storage_lock.hpp"
17
17
  #include "duckdb/function/compression_function.hpp"
18
18
  #include "duckdb/storage/table/segment_base.hpp"
19
+ #include "duckdb/storage/buffer/block_handle.hpp"
19
20
 
20
21
  namespace duckdb {
21
22
  class ColumnSegment;
@@ -13,6 +13,7 @@
13
13
  #include "duckdb/main/valid_checker.hpp"
14
14
  #include "duckdb/common/types/timestamp.hpp"
15
15
  #include "duckdb/common/unordered_map.hpp"
16
+ #include "duckdb/common/optional_ptr.hpp"
16
17
 
17
18
  namespace duckdb {
18
19
  class AttachedDatabase;
@@ -42,7 +43,7 @@ public:
42
43
  return start_timestamp;
43
44
  }
44
45
 
45
- Transaction &GetTransaction(AttachedDatabase *db);
46
+ Transaction &GetTransaction(AttachedDatabase &db);
46
47
 
47
48
  string Commit();
48
49
  void Rollback();
@@ -50,8 +51,8 @@ public:
50
51
  idx_t GetActiveQuery();
51
52
  void SetActiveQuery(transaction_t query_number);
52
53
 
53
- void ModifyDatabase(AttachedDatabase *db);
54
- AttachedDatabase *ModifiedDatabase() {
54
+ void ModifyDatabase(AttachedDatabase &db);
55
+ optional_ptr<AttachedDatabase> ModifiedDatabase() {
55
56
  return modified_database;
56
57
  }
57
58
 
@@ -59,9 +60,9 @@ private:
59
60
  //! The set of active transactions for each database
60
61
  unordered_map<AttachedDatabase *, Transaction *> transactions;
61
62
  //! The set of transactions in order of when they were started
62
- vector<AttachedDatabase *> all_transactions;
63
+ vector<optional_ptr<AttachedDatabase>> all_transactions;
63
64
  //! The database we are modifying - we can only modify one database per transaction
64
- AttachedDatabase *modified_database;
65
+ optional_ptr<AttachedDatabase> modified_database;
65
66
  };
66
67
 
67
68
  } // namespace duckdb
@@ -390,7 +390,7 @@ unique_ptr<PendingQueryResult> ClientContext::PendingPreparedStatement(ClientCon
390
390
  "Cannot execute statement of type \"%s\" on database \"%s\" which is attached in read-only mode!",
391
391
  StatementTypeToString(statement.statement_type), modified_database));
392
392
  }
393
- transaction.ModifyDatabase(entry);
393
+ transaction.ModifyDatabase(*entry);
394
394
  }
395
395
 
396
396
  // bind the bound values before execution
@@ -1144,9 +1144,11 @@ bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result)
1144
1144
  }
1145
1145
 
1146
1146
  ParserOptions ClientContext::GetParserOptions() const {
1147
+ auto &client_config = ClientConfig::GetConfig(*this);
1147
1148
  ParserOptions options;
1148
- options.preserve_identifier_case = ClientConfig::GetConfig(*this).preserve_identifier_case;
1149
- options.max_expression_depth = ClientConfig::GetConfig(*this).max_expression_depth;
1149
+ options.preserve_identifier_case = client_config.preserve_identifier_case;
1150
+ options.integer_division = client_config.integer_division;
1151
+ options.max_expression_depth = client_config.max_expression_depth;
1150
1152
  options.extensions = &DBConfig::GetConfig(*this).parser_extensions;
1151
1153
  return options;
1152
1154
  }
@@ -78,10 +78,12 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
78
78
  DUCKDB_LOCAL(HomeDirectorySetting),
79
79
  DUCKDB_LOCAL(LogQueryPathSetting),
80
80
  DUCKDB_GLOBAL(ImmediateTransactionModeSetting),
81
+ DUCKDB_LOCAL(IntegerDivisionSetting),
81
82
  DUCKDB_LOCAL(MaximumExpressionDepthSetting),
82
83
  DUCKDB_GLOBAL(MaximumMemorySetting),
83
84
  DUCKDB_GLOBAL_ALIAS("memory_limit", MaximumMemorySetting),
84
85
  DUCKDB_GLOBAL_ALIAS("null_order", DefaultNullOrderSetting),
86
+ DUCKDB_LOCAL(OrderedAggregateThreshold),
85
87
  DUCKDB_GLOBAL(PasswordSetting),
86
88
  DUCKDB_LOCAL(PerfectHashThresholdSetting),
87
89
  DUCKDB_LOCAL(PivotLimitSetting),
@@ -18,6 +18,7 @@
18
18
  #include "duckdb/storage/magic_bytes.hpp"
19
19
  #include "duckdb/storage/storage_extension.hpp"
20
20
  #include "duckdb/execution/operator/helper/physical_set.hpp"
21
+ #include "duckdb/storage/standard_buffer_manager.hpp"
21
22
 
22
23
  #ifndef DUCKDB_NO_THREADS
23
24
  #include "duckdb/common/thread.hpp"
@@ -200,7 +201,7 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
200
201
  }
201
202
 
202
203
  db_manager = make_uniq<DatabaseManager>(*this);
203
- buffer_manager = make_uniq<BufferManager>(*this, config.options.temporary_directory);
204
+ buffer_manager = make_uniq<StandardBufferManager>(*this, config.options.temporary_directory);
204
205
  scheduler = make_uniq<TaskScheduler>(*this);
205
206
  object_cache = make_uniq<ObjectCache>();
206
207
  connection_manager = make_uniq<ConnectionManager>();
@@ -23,7 +23,7 @@ void DatabaseManager::InitializeSystemCatalog() {
23
23
  system->Initialize();
24
24
  }
25
25
 
26
- AttachedDatabase *DatabaseManager::GetDatabase(ClientContext &context, const string &name) {
26
+ optional_ptr<AttachedDatabase> DatabaseManager::GetDatabase(ClientContext &context, const string &name) {
27
27
  if (StringUtil::Lower(name) == TEMP_CATALOG) {
28
28
  return context.client_data->temporary_objects.get();
29
29
  }
@@ -50,7 +50,7 @@ void DatabaseManager::DetachDatabase(ClientContext &context, const string &name,
50
50
  }
51
51
  }
52
52
 
53
- AttachedDatabase *DatabaseManager::GetDatabaseFromPath(ClientContext &context, const string &path) {
53
+ optional_ptr<AttachedDatabase> DatabaseManager::GetDatabaseFromPath(ClientContext &context, const string &path) {
54
54
  auto databases = GetDatabases(context);
55
55
  for (auto db : databases) {
56
56
  if (db->IsSystem()) {
@@ -81,8 +81,8 @@ const string &DatabaseManager::GetDefaultDatabase(ClientContext &context) {
81
81
  return default_entry.catalog;
82
82
  }
83
83
 
84
- vector<AttachedDatabase *> DatabaseManager::GetDatabases(ClientContext &context) {
85
- vector<AttachedDatabase *> result;
84
+ vector<optional_ptr<AttachedDatabase>> DatabaseManager::GetDatabases(ClientContext &context) {
85
+ vector<optional_ptr<AttachedDatabase>> result;
86
86
  databases->Scan(context, [&](CatalogEntry *entry) { result.push_back((AttachedDatabase *)entry); });
87
87
  result.push_back(system.get());
88
88
  result.push_back(context.client_data->temporary_objects.get());
@@ -141,6 +141,26 @@ Value DebugForceNoCrossProduct::GetSetting(ClientContext &context) {
141
141
  return Value::BOOLEAN(ClientConfig::GetConfig(context).force_no_cross_product);
142
142
  }
143
143
 
144
+ //===--------------------------------------------------------------------===//
145
+ // Debug Ordered Aggregate Threshold
146
+ //===--------------------------------------------------------------------===//
147
+
148
+ void OrderedAggregateThreshold::ResetLocal(ClientContext &context) {
149
+ ClientConfig::GetConfig(context).ordered_aggregate_threshold = ClientConfig().ordered_aggregate_threshold;
150
+ }
151
+
152
+ void OrderedAggregateThreshold::SetLocal(ClientContext &context, const Value &input) {
153
+ const auto param = input.GetValue<uint64_t>();
154
+ if (!param) {
155
+ throw ParserException("Invalid option for PRAGMA ordered_aggregate_threshold, value must be positive");
156
+ }
157
+ ClientConfig::GetConfig(context).ordered_aggregate_threshold = param;
158
+ }
159
+
160
+ Value OrderedAggregateThreshold::GetSetting(ClientContext &context) {
161
+ return Value::UBIGINT(ClientConfig::GetConfig(context).ordered_aggregate_threshold);
162
+ }
163
+
144
164
  //===--------------------------------------------------------------------===//
145
165
  // Debug Window Mode
146
166
  //===--------------------------------------------------------------------===//
@@ -660,6 +680,22 @@ Value HomeDirectorySetting::GetSetting(ClientContext &context) {
660
680
  return Value(config.home_directory);
661
681
  }
662
682
 
683
+ //===--------------------------------------------------------------------===//
684
+ // Integer Division
685
+ //===--------------------------------------------------------------------===//
686
+ void IntegerDivisionSetting::ResetLocal(ClientContext &context) {
687
+ ClientConfig::GetConfig(context).integer_division = ClientConfig().integer_division;
688
+ }
689
+
690
+ void IntegerDivisionSetting::SetLocal(ClientContext &context, const Value &input) {
691
+ auto &config = ClientConfig::GetConfig(context);
692
+ config.integer_division = input.GetValue<bool>();
693
+ }
694
+
695
+ Value IntegerDivisionSetting::GetSetting(ClientContext &context) {
696
+ auto &config = ClientConfig::GetConfig(context);
697
+ return Value(config.integer_division);
698
+ }
663
699
  //===--------------------------------------------------------------------===//
664
700
  // Log Query Path
665
701
  //===--------------------------------------------------------------------===//
@@ -33,10 +33,10 @@ void CommonAggregateOptimizer::ExtractCommonAggregates(LogicalAggregate &aggr) {
33
33
  idx_t total_erased = 0;
34
34
  for (idx_t i = 0; i < aggr.expressions.size(); i++) {
35
35
  idx_t original_index = i + total_erased;
36
- auto entry = aggregate_remap.find(aggr.expressions[i].get());
36
+ auto entry = aggregate_remap.find(*aggr.expressions[i]);
37
37
  if (entry == aggregate_remap.end()) {
38
38
  // aggregate does not exist yet: add it to the map
39
- aggregate_remap[aggr.expressions[i].get()] = i;
39
+ aggregate_remap[*aggr.expressions[i]] = i;
40
40
  if (i != original_index) {
41
41
  // this aggregate is not erased, however an agregate BEFORE it has been erased
42
42
  // so we need to remap this aggregaet