duckdb 0.8.2-dev3458.0 → 0.8.2-dev3949.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 (180) hide show
  1. package/binding.gyp +2 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/icu/icu_extension.cpp +5 -5
  4. package/src/duckdb/extension/json/include/json_deserializer.hpp +7 -16
  5. package/src/duckdb/extension/json/include/json_serializer.hpp +9 -15
  6. package/src/duckdb/extension/json/json_deserializer.cpp +29 -67
  7. package/src/duckdb/extension/json/json_scan.cpp +1 -1
  8. package/src/duckdb/extension/json/json_serializer.cpp +26 -69
  9. package/src/duckdb/src/common/enum_util.cpp +119 -7
  10. package/src/duckdb/src/common/extra_type_info.cpp +7 -3
  11. package/src/duckdb/src/common/radix_partitioning.cpp +8 -31
  12. package/src/duckdb/src/common/row_operations/row_aggregate.cpp +18 -3
  13. package/src/duckdb/src/common/serializer/binary_deserializer.cpp +62 -77
  14. package/src/duckdb/src/common/serializer/binary_serializer.cpp +84 -84
  15. package/src/duckdb/src/common/serializer/format_serializer.cpp +1 -1
  16. package/src/duckdb/src/common/sort/partition_state.cpp +41 -33
  17. package/src/duckdb/src/common/types/data_chunk.cpp +44 -8
  18. package/src/duckdb/src/common/types/hyperloglog.cpp +21 -0
  19. package/src/duckdb/src/common/types/interval.cpp +3 -0
  20. package/src/duckdb/src/common/types/row/partitioned_tuple_data.cpp +252 -126
  21. package/src/duckdb/src/common/types/row/row_layout.cpp +3 -31
  22. package/src/duckdb/src/common/types/row/tuple_data_allocator.cpp +40 -32
  23. package/src/duckdb/src/common/types/row/tuple_data_collection.cpp +39 -26
  24. package/src/duckdb/src/common/types/row/tuple_data_layout.cpp +11 -1
  25. package/src/duckdb/src/common/types/row/tuple_data_segment.cpp +21 -16
  26. package/src/duckdb/src/common/types/value.cpp +63 -42
  27. package/src/duckdb/src/common/types/vector.cpp +33 -67
  28. package/src/duckdb/src/core_functions/scalar/list/list_lambdas.cpp +3 -2
  29. package/src/duckdb/src/execution/aggregate_hashtable.cpp +222 -364
  30. package/src/duckdb/src/execution/join_hashtable.cpp +5 -6
  31. package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +240 -310
  32. package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +202 -173
  33. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +36 -2
  34. package/src/duckdb/src/execution/operator/{persistent → csv_scanner}/base_csv_reader.cpp +58 -162
  35. package/src/duckdb/src/execution/operator/csv_scanner/buffered_csv_reader.cpp +434 -0
  36. package/src/duckdb/src/execution/operator/csv_scanner/csv_buffer.cpp +80 -0
  37. package/src/duckdb/src/execution/operator/csv_scanner/csv_buffer_manager.cpp +90 -0
  38. package/src/duckdb/src/execution/operator/csv_scanner/csv_file_handle.cpp +95 -0
  39. package/src/duckdb/src/execution/operator/{persistent → csv_scanner}/csv_reader_options.cpp +47 -28
  40. package/src/duckdb/src/execution/operator/csv_scanner/csv_state_machine.cpp +35 -0
  41. package/src/duckdb/src/execution/operator/csv_scanner/csv_state_machine_cache.cpp +107 -0
  42. package/src/duckdb/src/execution/operator/{persistent → csv_scanner}/parallel_csv_reader.cpp +44 -44
  43. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp +52 -0
  44. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +336 -0
  45. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp +165 -0
  46. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_detection.cpp +398 -0
  47. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_refinement.cpp +175 -0
  48. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp +39 -0
  49. package/src/duckdb/src/execution/operator/join/physical_asof_join.cpp +1 -1
  50. package/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp +1 -2
  51. package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +614 -574
  52. package/src/duckdb/src/execution/window_executor.cpp +6 -5
  53. package/src/duckdb/src/function/cast/cast_function_set.cpp +1 -0
  54. package/src/duckdb/src/function/scalar/strftime_format.cpp +4 -4
  55. package/src/duckdb/src/function/table/copy_csv.cpp +94 -96
  56. package/src/duckdb/src/function/table/read_csv.cpp +150 -136
  57. package/src/duckdb/src/function/table/table_scan.cpp +0 -2
  58. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  59. package/src/duckdb/src/include/duckdb/common/enum_util.hpp +24 -0
  60. package/src/duckdb/src/include/duckdb/common/file_opener.hpp +9 -0
  61. package/src/duckdb/src/include/duckdb/common/fixed_size_map.hpp +208 -0
  62. package/src/duckdb/src/include/duckdb/common/optional_idx.hpp +3 -0
  63. package/src/duckdb/src/include/duckdb/common/perfect_map_set.hpp +2 -1
  64. package/src/duckdb/src/include/duckdb/common/printer.hpp +11 -0
  65. package/src/duckdb/src/include/duckdb/common/serializer/binary_deserializer.hpp +43 -30
  66. package/src/duckdb/src/include/duckdb/common/serializer/binary_serializer.hpp +36 -35
  67. package/src/duckdb/src/include/duckdb/common/serializer/deserialization_data.hpp +18 -0
  68. package/src/duckdb/src/include/duckdb/common/serializer/encoding_util.hpp +132 -0
  69. package/src/duckdb/src/include/duckdb/common/serializer/format_deserializer.hpp +125 -150
  70. package/src/duckdb/src/include/duckdb/common/serializer/format_serializer.hpp +119 -107
  71. package/src/duckdb/src/include/duckdb/common/serializer/serialization_traits.hpp +2 -1
  72. package/src/duckdb/src/include/duckdb/common/shared_ptr.hpp +8 -0
  73. package/src/duckdb/src/include/duckdb/common/sort/partition_state.hpp +13 -7
  74. package/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +5 -0
  75. package/src/duckdb/src/include/duckdb/common/types/hyperloglog.hpp +7 -1
  76. package/src/duckdb/src/include/duckdb/common/types/interval.hpp +7 -0
  77. package/src/duckdb/src/include/duckdb/common/types/row/partitioned_tuple_data.hpp +41 -9
  78. package/src/duckdb/src/include/duckdb/common/types/row/row_data_collection_scanner.hpp +5 -0
  79. package/src/duckdb/src/include/duckdb/common/types/row/row_layout.hpp +1 -23
  80. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_allocator.hpp +14 -8
  81. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_collection.hpp +6 -3
  82. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_layout.hpp +7 -0
  83. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_segment.hpp +13 -8
  84. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_states.hpp +3 -2
  85. package/src/duckdb/src/include/duckdb/common/types/vector.hpp +3 -3
  86. package/src/duckdb/src/include/duckdb/common/vector.hpp +2 -2
  87. package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +125 -146
  88. package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_hash_aggregate.hpp +5 -4
  89. package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_window.hpp +4 -3
  90. package/src/duckdb/src/include/duckdb/execution/operator/{persistent → scan/csv}/base_csv_reader.hpp +17 -17
  91. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/buffered_csv_reader.hpp +72 -0
  92. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_buffer.hpp +110 -0
  93. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_buffer_manager.hpp +103 -0
  94. package/src/duckdb/src/include/duckdb/execution/operator/{persistent → scan/csv}/csv_file_handle.hpp +8 -15
  95. package/src/duckdb/src/include/duckdb/execution/operator/{persistent → scan/csv}/csv_line_info.hpp +1 -1
  96. package/src/duckdb/src/include/duckdb/execution/operator/{persistent → scan/csv}/csv_reader_options.hpp +52 -28
  97. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_sniffer.hpp +127 -0
  98. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_state_machine.hpp +75 -0
  99. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/csv_state_machine_cache.hpp +51 -0
  100. package/src/duckdb/src/include/duckdb/execution/operator/{persistent → scan/csv}/parallel_csv_reader.hpp +21 -27
  101. package/src/duckdb/src/include/duckdb/execution/operator/scan/csv/quote_rules.hpp +21 -0
  102. package/src/duckdb/src/include/duckdb/execution/radix_partitioned_hashtable.hpp +18 -27
  103. package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +5 -6
  104. package/src/duckdb/src/include/duckdb/function/scalar/strftime_format.hpp +4 -4
  105. package/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +17 -12
  106. package/src/duckdb/src/include/duckdb/main/client_context_file_opener.hpp +1 -0
  107. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -1
  108. package/src/duckdb/src/include/duckdb/main/config.hpp +1 -0
  109. package/src/duckdb/src/include/duckdb/main/connection.hpp +2 -2
  110. package/src/duckdb/src/include/duckdb/main/relation/read_csv_relation.hpp +6 -6
  111. package/src/duckdb/src/include/duckdb/parallel/event.hpp +12 -1
  112. package/src/duckdb/src/include/duckdb/storage/block.hpp +6 -0
  113. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +3 -0
  114. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +7 -3
  115. package/src/duckdb/src/include/duckdb/storage/statistics/column_statistics.hpp +4 -0
  116. package/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp +5 -0
  117. package/src/duckdb/src/include/duckdb/storage/statistics/list_stats.hpp +3 -0
  118. package/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp +3 -0
  119. package/src/duckdb/src/include/duckdb/storage/statistics/string_stats.hpp +3 -0
  120. package/src/duckdb/src/include/duckdb/storage/statistics/struct_stats.hpp +3 -0
  121. package/src/duckdb/src/include/duckdb/storage/table/chunk_info.hpp +15 -3
  122. package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +4 -0
  123. package/src/duckdb/src/include/duckdb/storage/table/table_statistics.hpp +5 -0
  124. package/src/duckdb/src/include/duckdb/verification/deserialized_statement_verifier_v2.hpp +6 -0
  125. package/src/duckdb/src/include/duckdb/verification/statement_verifier.hpp +1 -0
  126. package/src/duckdb/src/include/duckdb.h +12 -0
  127. package/src/duckdb/src/main/capi/logical_types-c.cpp +22 -0
  128. package/src/duckdb/src/main/client_context_file_opener.cpp +17 -0
  129. package/src/duckdb/src/main/client_verify.cpp +1 -0
  130. package/src/duckdb/src/main/config.cpp +2 -2
  131. package/src/duckdb/src/main/connection.cpp +3 -3
  132. package/src/duckdb/src/main/relation/read_csv_relation.cpp +19 -13
  133. package/src/duckdb/src/parallel/pipeline_finish_event.cpp +1 -1
  134. package/src/duckdb/src/parser/tableref/pivotref.cpp +0 -16
  135. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +1 -1
  136. package/src/duckdb/src/planner/binder/statement/bind_export.cpp +41 -25
  137. package/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +4 -4
  138. package/src/duckdb/src/planner/expression/bound_window_expression.cpp +10 -10
  139. package/src/duckdb/src/planner/logical_operator.cpp +1 -1
  140. package/src/duckdb/src/planner/planner.cpp +1 -1
  141. package/src/duckdb/src/storage/checkpoint_manager.cpp +4 -3
  142. package/src/duckdb/src/storage/serialization/serialize_constraint.cpp +1 -1
  143. package/src/duckdb/src/storage/serialization/serialize_create_info.cpp +5 -5
  144. package/src/duckdb/src/storage/serialization/serialize_expression.cpp +10 -10
  145. package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +20 -20
  146. package/src/duckdb/src/storage/serialization/serialize_macro_function.cpp +2 -2
  147. package/src/duckdb/src/storage/serialization/serialize_nodes.cpp +118 -89
  148. package/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +3 -3
  149. package/src/duckdb/src/storage/serialization/serialize_parsed_expression.cpp +27 -27
  150. package/src/duckdb/src/storage/serialization/serialize_query_node.cpp +16 -16
  151. package/src/duckdb/src/storage/serialization/serialize_result_modifier.cpp +8 -8
  152. package/src/duckdb/src/storage/serialization/serialize_statement.cpp +1 -1
  153. package/src/duckdb/src/storage/serialization/serialize_storage.cpp +39 -0
  154. package/src/duckdb/src/storage/serialization/serialize_tableref.cpp +9 -9
  155. package/src/duckdb/src/storage/statistics/base_statistics.cpp +67 -4
  156. package/src/duckdb/src/storage/statistics/column_statistics.cpp +16 -0
  157. package/src/duckdb/src/storage/statistics/list_stats.cpp +21 -0
  158. package/src/duckdb/src/storage/statistics/numeric_stats.cpp +126 -1
  159. package/src/duckdb/src/storage/statistics/string_stats.cpp +23 -0
  160. package/src/duckdb/src/storage/statistics/struct_stats.cpp +27 -0
  161. package/src/duckdb/src/storage/storage_info.cpp +1 -1
  162. package/src/duckdb/src/storage/table/chunk_info.cpp +82 -3
  163. package/src/duckdb/src/storage/table/row_group.cpp +68 -1
  164. package/src/duckdb/src/storage/table/table_statistics.cpp +21 -0
  165. package/src/duckdb/src/storage/wal_replay.cpp +2 -2
  166. package/src/duckdb/src/verification/deserialized_statement_verifier_v2.cpp +15 -1
  167. package/src/duckdb/src/verification/statement_verifier.cpp +2 -0
  168. package/src/duckdb/third_party/utf8proc/include/utf8proc_wrapper.hpp +8 -0
  169. package/src/duckdb/ub_src_execution.cpp +0 -2
  170. package/src/duckdb/ub_src_execution_operator_csv_scanner.cpp +18 -0
  171. package/src/duckdb/ub_src_execution_operator_csv_scanner_sniffer.cpp +12 -0
  172. package/src/duckdb/ub_src_execution_operator_persistent.cpp +0 -12
  173. package/src/duckdb/ub_src_storage_serialization.cpp +2 -0
  174. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +0 -1487
  175. package/src/duckdb/src/execution/operator/persistent/csv_buffer.cpp +0 -72
  176. package/src/duckdb/src/execution/operator/persistent/csv_file_handle.cpp +0 -158
  177. package/src/duckdb/src/execution/partitionable_hashtable.cpp +0 -207
  178. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -133
  179. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_buffer.hpp +0 -74
  180. package/src/duckdb/src/include/duckdb/execution/partitionable_hashtable.hpp +0 -73
@@ -33,6 +33,10 @@ TupleDataAllocator::TupleDataAllocator(TupleDataAllocator &allocator)
33
33
  : buffer_manager(allocator.buffer_manager), layout(allocator.layout.Copy()) {
34
34
  }
35
35
 
36
+ BufferManager &TupleDataAllocator::GetBufferManager() {
37
+ return buffer_manager;
38
+ }
39
+
36
40
  Allocator &TupleDataAllocator::GetAllocator() {
37
41
  return buffer_manager.GetBufferAllocator();
38
42
  }
@@ -58,7 +62,7 @@ void TupleDataAllocator::Build(TupleDataSegment &segment, TupleDataPinState &pin
58
62
  }
59
63
 
60
64
  // Build the chunk parts for the incoming data
61
- vector<pair<idx_t, idx_t>> chunk_part_indices;
65
+ chunk_part_indices.clear();
62
66
  idx_t offset = 0;
63
67
  while (offset != append_count) {
64
68
  if (chunks.empty() || chunks.back().count == STANDARD_VECTOR_SIZE) {
@@ -68,23 +72,26 @@ void TupleDataAllocator::Build(TupleDataSegment &segment, TupleDataPinState &pin
68
72
 
69
73
  // Build the next part
70
74
  auto next = MinValue<idx_t>(append_count - offset, STANDARD_VECTOR_SIZE - chunk.count);
71
- chunk.AddPart(BuildChunkPart(pin_state, chunk_state, append_offset + offset, next), layout);
72
- chunk_part_indices.emplace_back(chunks.size() - 1, chunk.parts.size() - 1);
73
-
75
+ chunk.AddPart(BuildChunkPart(pin_state, chunk_state, append_offset + offset, next, chunk), layout);
74
76
  auto &chunk_part = chunk.parts.back();
75
77
  next = chunk_part.count;
78
+
76
79
  segment.count += next;
80
+ segment.data_size += chunk_part.count * layout.GetRowWidth();
81
+ if (!layout.AllConstant()) {
82
+ segment.data_size += chunk_part.total_heap_size;
83
+ }
77
84
 
78
85
  offset += next;
86
+ chunk_part_indices.emplace_back(chunks.size() - 1, chunk.parts.size() - 1);
79
87
  }
80
88
 
81
89
  // Now initialize the pointers to write the data to
82
- vector<TupleDataChunkPart *> parts;
83
- parts.reserve(chunk_part_indices.size());
90
+ chunk_parts.clear();
84
91
  for (auto &indices : chunk_part_indices) {
85
- parts.emplace_back(&segment.chunks[indices.first].parts[indices.second]);
92
+ chunk_parts.emplace_back(segment.chunks[indices.first].parts[indices.second]);
86
93
  }
87
- InitializeChunkStateInternal(pin_state, chunk_state, append_offset, false, true, false, parts);
94
+ InitializeChunkStateInternal(pin_state, chunk_state, append_offset, false, true, false, chunk_parts);
88
95
 
89
96
  // To reduce metadata, we try to merge chunk parts where possible
90
97
  // Due to the way chunk parts are constructed, only the last part of the first chunk is eligible for merging
@@ -94,9 +101,10 @@ void TupleDataAllocator::Build(TupleDataSegment &segment, TupleDataPinState &pin
94
101
  }
95
102
 
96
103
  TupleDataChunkPart TupleDataAllocator::BuildChunkPart(TupleDataPinState &pin_state, TupleDataChunkState &chunk_state,
97
- const idx_t append_offset, const idx_t append_count) {
104
+ const idx_t append_offset, const idx_t append_count,
105
+ TupleDataChunk &chunk) {
98
106
  D_ASSERT(append_count != 0);
99
- TupleDataChunkPart result;
107
+ TupleDataChunkPart result(*chunk.lock);
100
108
 
101
109
  // Allocate row block (if needed)
102
110
  if (row_blocks.empty() || row_blocks.back().RemainingCapacity() < layout.GetRowWidth()) {
@@ -176,10 +184,10 @@ void TupleDataAllocator::InitializeChunkState(TupleDataSegment &segment, TupleDa
176
184
  // when chunk 0 needs heap block 0, chunk 1 does not need any heap blocks, and chunk 2 needs heap block 0 again
177
185
  ReleaseOrStoreHandles(pin_state, segment, chunk, !chunk.heap_block_ids.empty());
178
186
 
179
- vector<TupleDataChunkPart *> parts;
187
+ unsafe_vector<reference<TupleDataChunkPart>> parts;
180
188
  parts.reserve(chunk.parts.size());
181
189
  for (auto &part : chunk.parts) {
182
- parts.emplace_back(&part);
190
+ parts.emplace_back(part);
183
191
  }
184
192
 
185
193
  InitializeChunkStateInternal(pin_state, chunk_state, 0, true, init_heap, init_heap, parts);
@@ -206,17 +214,19 @@ static inline void InitializeHeapSizes(const data_ptr_t row_locations[], idx_t h
206
214
 
207
215
  void TupleDataAllocator::InitializeChunkStateInternal(TupleDataPinState &pin_state, TupleDataChunkState &chunk_state,
208
216
  idx_t offset, bool recompute, bool init_heap_pointers,
209
- bool init_heap_sizes, vector<TupleDataChunkPart *> &parts) {
217
+ bool init_heap_sizes,
218
+ unsafe_vector<reference<TupleDataChunkPart>> &parts) {
210
219
  auto row_locations = FlatVector::GetData<data_ptr_t>(chunk_state.row_locations);
211
220
  auto heap_sizes = FlatVector::GetData<idx_t>(chunk_state.heap_sizes);
212
221
  auto heap_locations = FlatVector::GetData<data_ptr_t>(chunk_state.heap_locations);
213
222
 
214
- for (auto &part : parts) {
215
- const auto next = part->count;
223
+ for (auto &part_ref : parts) {
224
+ auto &part = part_ref.get();
225
+ const auto next = part.count;
216
226
 
217
227
  // Set up row locations for the scan
218
228
  const auto row_width = layout.GetRowWidth();
219
- const auto base_row_ptr = GetRowPointer(pin_state, *part);
229
+ const auto base_row_ptr = GetRowPointer(pin_state, part);
220
230
  for (idx_t i = 0; i < next; i++) {
221
231
  row_locations[offset + i] = base_row_ptr + i * row_width;
222
232
  }
@@ -226,9 +236,9 @@ void TupleDataAllocator::InitializeChunkStateInternal(TupleDataPinState &pin_sta
226
236
  continue;
227
237
  }
228
238
 
229
- if (part->total_heap_size == 0) {
239
+ if (part.total_heap_size == 0) {
230
240
  if (init_heap_sizes) { // No heap, but we need the heap sizes
231
- InitializeHeapSizes(row_locations, heap_sizes, offset, next, *part, layout.GetHeapSizeOffset());
241
+ InitializeHeapSizes(row_locations, heap_sizes, offset, next, part, layout.GetHeapSizeOffset());
232
242
  }
233
243
  offset += next;
234
244
  continue;
@@ -236,29 +246,29 @@ void TupleDataAllocator::InitializeChunkStateInternal(TupleDataPinState &pin_sta
236
246
 
237
247
  // Check if heap block has changed - re-compute the pointers within each row if so
238
248
  if (recompute && pin_state.properties != TupleDataPinProperties::ALREADY_PINNED) {
239
- const auto new_base_heap_ptr = GetBaseHeapPointer(pin_state, *part);
240
- if (part->base_heap_ptr != new_base_heap_ptr) {
241
- lock_guard<mutex> guard(part->lock);
242
- const auto old_base_heap_ptr = part->base_heap_ptr;
249
+ const auto new_base_heap_ptr = GetBaseHeapPointer(pin_state, part);
250
+ if (part.base_heap_ptr != new_base_heap_ptr) {
251
+ lock_guard<mutex> guard(part.lock);
252
+ const auto old_base_heap_ptr = part.base_heap_ptr;
243
253
  if (old_base_heap_ptr != new_base_heap_ptr) {
244
254
  Vector old_heap_ptrs(
245
- Value::POINTER(CastPointerToValue(old_base_heap_ptr + part->heap_block_offset)));
255
+ Value::POINTER(CastPointerToValue(old_base_heap_ptr + part.heap_block_offset)));
246
256
  Vector new_heap_ptrs(
247
- Value::POINTER(CastPointerToValue(new_base_heap_ptr + part->heap_block_offset)));
257
+ Value::POINTER(CastPointerToValue(new_base_heap_ptr + part.heap_block_offset)));
248
258
  RecomputeHeapPointers(old_heap_ptrs, *ConstantVector::ZeroSelectionVector(), row_locations,
249
259
  new_heap_ptrs, offset, next, layout, 0);
250
- part->base_heap_ptr = new_base_heap_ptr;
260
+ part.base_heap_ptr = new_base_heap_ptr;
251
261
  }
252
262
  }
253
263
  }
254
264
 
255
265
  if (init_heap_sizes) {
256
- InitializeHeapSizes(row_locations, heap_sizes, offset, next, *part, layout.GetHeapSizeOffset());
266
+ InitializeHeapSizes(row_locations, heap_sizes, offset, next, part, layout.GetHeapSizeOffset());
257
267
  }
258
268
 
259
269
  if (init_heap_pointers) {
260
270
  // Set the pointers where the heap data will be written (if needed)
261
- heap_locations[offset] = part->base_heap_ptr + part->heap_block_offset;
271
+ heap_locations[offset] = part.base_heap_ptr + part.heap_block_offset;
262
272
  for (idx_t i = 1; i < next; i++) {
263
273
  auto idx = offset + i;
264
274
  heap_locations[idx] = heap_locations[idx - 1] + heap_sizes[idx - 1];
@@ -387,11 +397,9 @@ void TupleDataAllocator::ReleaseOrStoreHandles(TupleDataPinState &pin_state, Tup
387
397
  ReleaseOrStoreHandles(pin_state, segment, DUMMY_CHUNK, true);
388
398
  }
389
399
 
390
- void TupleDataAllocator::ReleaseOrStoreHandlesInternal(TupleDataSegment &segment, vector<BufferHandle> &pinned_handles,
391
- unordered_map<uint32_t, BufferHandle> &handles,
392
- const unordered_set<uint32_t> &block_ids,
393
- vector<TupleDataBlock> &blocks,
394
- TupleDataPinProperties properties) {
400
+ void TupleDataAllocator::ReleaseOrStoreHandlesInternal(
401
+ TupleDataSegment &segment, unsafe_vector<BufferHandle> &pinned_handles, perfect_map_t<BufferHandle> &handles,
402
+ const perfect_set_t &block_ids, unsafe_vector<TupleDataBlock> &blocks, TupleDataPinProperties properties) {
395
403
  bool found_handle;
396
404
  do {
397
405
  found_handle = false;
@@ -27,6 +27,7 @@ TupleDataCollection::~TupleDataCollection() {
27
27
  void TupleDataCollection::Initialize() {
28
28
  D_ASSERT(!layout.GetTypes().empty());
29
29
  this->count = 0;
30
+ this->data_size = 0;
30
31
  scatter_functions.reserve(layout.ColumnCount());
31
32
  gather_functions.reserve(layout.ColumnCount());
32
33
  for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) {
@@ -67,23 +68,13 @@ idx_t TupleDataCollection::SizeInBytes() const {
67
68
  return total_size;
68
69
  }
69
70
 
70
- void TupleDataCollection::GetBlockPointers(vector<data_ptr_t> &block_pointers) const {
71
- D_ASSERT(segments.size() == 1);
72
- const auto &segment = segments[0];
73
- const auto block_count = segment.allocator->RowBlockCount();
74
- D_ASSERT(segment.pinned_row_handles.size() == block_count);
75
- block_pointers.resize(block_count);
76
- for (idx_t block_idx = 0; block_idx < block_count; block_idx++) {
77
- block_pointers[block_idx] = segment.pinned_row_handles[block_idx].Ptr();
78
- }
79
- }
80
-
81
71
  void TupleDataCollection::Unpin() {
82
72
  for (auto &segment : segments) {
83
73
  segment.Unpin();
84
74
  }
85
75
  }
86
76
 
77
+ // LCOV_EXCL_START
87
78
  void VerifyAppendColumns(const TupleDataLayout &layout, const vector<column_t> &column_ids) {
88
79
  #ifdef DEBUG
89
80
  for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) {
@@ -105,6 +96,7 @@ void VerifyAppendColumns(const TupleDataLayout &layout, const vector<column_t> &
105
96
  }
106
97
  #endif
107
98
  }
99
+ // LCOV_EXCL_STOP
108
100
 
109
101
  void TupleDataCollection::InitializeAppend(TupleDataAppendState &append_state, TupleDataPinProperties properties) {
110
102
  vector<column_t> column_ids;
@@ -260,11 +252,15 @@ void TupleDataCollection::GetVectorData(const TupleDataChunkState &chunk_state,
260
252
 
261
253
  void TupleDataCollection::Build(TupleDataPinState &pin_state, TupleDataChunkState &chunk_state,
262
254
  const idx_t append_offset, const idx_t append_count) {
263
- segments.back().allocator->Build(segments.back(), pin_state, chunk_state, append_offset, append_count);
255
+ auto &segment = segments.back();
256
+ const auto size_before = segment.SizeInBytes();
257
+ segment.allocator->Build(segment, pin_state, chunk_state, append_offset, append_count);
258
+ data_size += segment.SizeInBytes() - size_before;
264
259
  count += append_count;
265
260
  Verify();
266
261
  }
267
262
 
263
+ // LCOV_EXCL_START
268
264
  void VerifyHeapSizes(const data_ptr_t source_locations[], const idx_t heap_sizes[], const SelectionVector &append_sel,
269
265
  const idx_t append_count, const idx_t heap_size_offset) {
270
266
  #ifdef DEBUG
@@ -275,6 +271,7 @@ void VerifyHeapSizes(const data_ptr_t source_locations[], const idx_t heap_sizes
275
271
  }
276
272
  #endif
277
273
  }
274
+ // LCOV_EXCL_STOP
278
275
 
279
276
  void TupleDataCollection::CopyRows(TupleDataChunkState &chunk_state, TupleDataChunkState &input,
280
277
  const SelectionVector &append_sel, const idx_t append_count) const {
@@ -324,12 +321,17 @@ void TupleDataCollection::Combine(TupleDataCollection &other) {
324
321
  if (this->layout.GetTypes() != other.GetLayout().GetTypes()) {
325
322
  throw InternalException("Attempting to combine TupleDataCollection with mismatching types");
326
323
  }
327
- this->count += other.count;
328
324
  this->segments.reserve(this->segments.size() + other.segments.size());
329
325
  for (auto &other_seg : other.segments) {
330
- this->segments.emplace_back(std::move(other_seg));
326
+ AddSegment(std::move(other_seg));
331
327
  }
332
328
  other.Reset();
329
+ }
330
+
331
+ void TupleDataCollection::AddSegment(TupleDataSegment &&segment) {
332
+ count += segment.count;
333
+ data_size += segment.data_size;
334
+ segments.emplace_back(std::move(segment));
333
335
  Verify();
334
336
  }
335
337
 
@@ -339,6 +341,7 @@ void TupleDataCollection::Combine(unique_ptr<TupleDataCollection> other) {
339
341
 
340
342
  void TupleDataCollection::Reset() {
341
343
  count = 0;
344
+ data_size = 0;
342
345
  segments.clear();
343
346
 
344
347
  // Refreshes the TupleDataAllocator to prevent holding on to allocated data unnecessarily
@@ -395,6 +398,10 @@ bool TupleDataCollection::Scan(TupleDataScanState &state, DataChunk &result) {
395
398
  idx_t segment_index;
396
399
  idx_t chunk_index;
397
400
  if (!NextScanIndex(state, segment_index, chunk_index)) {
401
+ if (!segments.empty()) {
402
+ FinalizePinState(state.pin_state, segments[segment_index_before]);
403
+ }
404
+ result.SetCardinality(0);
398
405
  return false;
399
406
  }
400
407
  if (segment_index_before != DConstants::INVALID_INDEX && segment_index != segment_index_before) {
@@ -408,20 +415,21 @@ bool TupleDataCollection::Scan(TupleDataParallelScanState &gstate, TupleDataLoca
408
415
  lstate.pin_state.properties = gstate.scan_state.pin_state.properties;
409
416
 
410
417
  const auto segment_index_before = lstate.segment_index;
411
- idx_t segment_index;
412
- idx_t chunk_index;
413
418
  {
414
419
  lock_guard<mutex> guard(gstate.lock);
415
- if (!NextScanIndex(gstate.scan_state, segment_index, chunk_index)) {
420
+ if (!NextScanIndex(gstate.scan_state, lstate.segment_index, lstate.chunk_index)) {
421
+ if (!segments.empty()) {
422
+ FinalizePinState(lstate.pin_state, segments[segment_index_before]);
423
+ }
424
+ result.SetCardinality(0);
416
425
  return false;
417
426
  }
418
427
  }
419
- if (segment_index_before != DConstants::INVALID_INDEX && segment_index_before != segment_index) {
428
+ if (segment_index_before != DConstants::INVALID_INDEX && segment_index_before != lstate.segment_index) {
420
429
  FinalizePinState(lstate.pin_state, segments[lstate.segment_index]);
421
- lstate.segment_index = segment_index;
422
430
  }
423
- ScanAtIndex(lstate.pin_state, lstate.chunk_state, gstate.scan_state.chunk_state.column_ids, segment_index,
424
- chunk_index, result);
431
+ ScanAtIndex(lstate.pin_state, lstate.chunk_state, gstate.scan_state.chunk_state.column_ids, lstate.segment_index,
432
+ lstate.chunk_index, result);
425
433
  return true;
426
434
  }
427
435
 
@@ -430,8 +438,8 @@ void TupleDataCollection::FinalizePinState(TupleDataPinState &pin_state, TupleDa
430
438
  }
431
439
 
432
440
  void TupleDataCollection::FinalizePinState(TupleDataPinState &pin_state) {
433
- D_ASSERT(segments.size() == 1);
434
- allocator->ReleaseOrStoreHandles(pin_state, segments.back());
441
+ D_ASSERT(!segments.empty());
442
+ FinalizePinState(pin_state, segments.back());
435
443
  }
436
444
 
437
445
  bool TupleDataCollection::NextScanIndex(TupleDataScanState &state, idx_t &segment_index, idx_t &chunk_index) {
@@ -466,6 +474,7 @@ void TupleDataCollection::ScanAtIndex(TupleDataPinState &pin_state, TupleDataChu
466
474
  result.SetCardinality(chunk.count);
467
475
  }
468
476
 
477
+ // LCOV_EXCL_START
469
478
  string TupleDataCollection::ToString() {
470
479
  DataChunk chunk;
471
480
  InitializeChunk(chunk);
@@ -493,12 +502,15 @@ void TupleDataCollection::Print() {
493
502
 
494
503
  void TupleDataCollection::Verify() const {
495
504
  #ifdef DEBUG
496
- idx_t total_segment_count = 0;
505
+ idx_t total_count = 0;
506
+ idx_t total_size = 0;
497
507
  for (const auto &segment : segments) {
498
508
  segment.Verify();
499
- total_segment_count += segment.count;
509
+ total_count += segment.count;
510
+ total_size += segment.data_size;
500
511
  }
501
- D_ASSERT(total_segment_count == this->count);
512
+ D_ASSERT(total_count == this->count);
513
+ D_ASSERT(total_size == this->data_size);
502
514
  #endif
503
515
  }
504
516
 
@@ -509,5 +521,6 @@ void TupleDataCollection::VerifyEverythingPinned() const {
509
521
  }
510
522
  #endif
511
523
  }
524
+ // LCOV_EXCL_STOP
512
525
 
513
526
  } // namespace duckdb
@@ -5,7 +5,8 @@
5
5
  namespace duckdb {
6
6
 
7
7
  TupleDataLayout::TupleDataLayout()
8
- : flag_width(0), data_width(0), aggr_width(0), row_width(0), all_constant(true), heap_size_offset(0) {
8
+ : flag_width(0), data_width(0), aggr_width(0), row_width(0), all_constant(true), heap_size_offset(0),
9
+ has_destructor(false) {
9
10
  }
10
11
 
11
12
  TupleDataLayout TupleDataLayout::Copy() const {
@@ -25,6 +26,7 @@ TupleDataLayout TupleDataLayout::Copy() const {
25
26
  result.offsets = this->offsets;
26
27
  result.all_constant = this->all_constant;
27
28
  result.heap_size_offset = this->heap_size_offset;
29
+ result.has_destructor = this->has_destructor;
28
30
  return result;
29
31
  }
30
32
 
@@ -106,6 +108,14 @@ void TupleDataLayout::Initialize(vector<LogicalType> types_p, Aggregates aggrega
106
108
  row_width = AlignValue(row_width);
107
109
  }
108
110
  #endif
111
+
112
+ has_destructor = false;
113
+ for (auto &aggr : GetAggregates()) {
114
+ if (aggr.function.destructor) {
115
+ has_destructor = true;
116
+ break;
117
+ }
118
+ }
109
119
  }
110
120
 
111
121
  void TupleDataLayout::Initialize(vector<LogicalType> types_p, bool align, bool heap_offset_p) {
@@ -4,7 +4,7 @@
4
4
 
5
5
  namespace duckdb {
6
6
 
7
- TupleDataChunkPart::TupleDataChunkPart() {
7
+ TupleDataChunkPart::TupleDataChunkPart(mutex &lock_p) : lock(lock_p) {
8
8
  }
9
9
 
10
10
  void SwapTupleDataChunkPart(TupleDataChunkPart &a, TupleDataChunkPart &b) {
@@ -15,10 +15,10 @@ void SwapTupleDataChunkPart(TupleDataChunkPart &a, TupleDataChunkPart &b) {
15
15
  std::swap(a.base_heap_ptr, b.base_heap_ptr);
16
16
  std::swap(a.total_heap_size, b.total_heap_size);
17
17
  std::swap(a.count, b.count);
18
- // Cannot swap the lock, but not needed as move constructor only happens during append, lock only needed for scans
18
+ std::swap(a.lock, b.lock);
19
19
  }
20
20
 
21
- TupleDataChunkPart::TupleDataChunkPart(TupleDataChunkPart &&other) noexcept {
21
+ TupleDataChunkPart::TupleDataChunkPart(TupleDataChunkPart &&other) noexcept : lock((other.lock)) {
22
22
  SwapTupleDataChunkPart(*this, other);
23
23
  }
24
24
 
@@ -27,7 +27,8 @@ TupleDataChunkPart &TupleDataChunkPart::operator=(TupleDataChunkPart &&other) no
27
27
  return *this;
28
28
  }
29
29
 
30
- TupleDataChunk::TupleDataChunk() : count(0) {
30
+ TupleDataChunk::TupleDataChunk() : count(0), lock(make_unsafe_uniq<mutex>()) {
31
+ parts.reserve(2);
31
32
  }
32
33
 
33
34
  static inline void SwapTupleDataChunk(TupleDataChunk &a, TupleDataChunk &b) noexcept {
@@ -35,6 +36,7 @@ static inline void SwapTupleDataChunk(TupleDataChunk &a, TupleDataChunk &b) noex
35
36
  std::swap(a.row_block_ids, b.row_block_ids);
36
37
  std::swap(a.heap_block_ids, b.heap_block_ids);
37
38
  std::swap(a.count, b.count);
39
+ std::swap(a.lock, b.lock);
38
40
  }
39
41
 
40
42
  TupleDataChunk::TupleDataChunk(TupleDataChunk &&other) noexcept {
@@ -52,6 +54,7 @@ void TupleDataChunk::AddPart(TupleDataChunkPart &&part, const TupleDataLayout &l
52
54
  if (!layout.AllConstant() && part.total_heap_size > 0) {
53
55
  heap_block_ids.insert(part.heap_block_index);
54
56
  }
57
+ part.lock = *lock;
55
58
  parts.emplace_back(std::move(part));
56
59
  }
57
60
 
@@ -98,7 +101,7 @@ void TupleDataChunk::MergeLastChunkPart(const TupleDataLayout &layout) {
98
101
  }
99
102
 
100
103
  TupleDataSegment::TupleDataSegment(shared_ptr<TupleDataAllocator> allocator_p)
101
- : allocator(std::move(allocator_p)), count(0) {
104
+ : allocator(std::move(allocator_p)), count(0), data_size(0) {
102
105
  }
103
106
 
104
107
  TupleDataSegment::~TupleDataSegment() {
@@ -112,6 +115,7 @@ void SwapTupleDataSegment(TupleDataSegment &a, TupleDataSegment &b) {
112
115
  std::swap(a.allocator, b.allocator);
113
116
  std::swap(a.chunks, b.chunks);
114
117
  std::swap(a.count, b.count);
118
+ std::swap(a.data_size, b.data_size);
115
119
  std::swap(a.pinned_row_handles, b.pinned_row_handles);
116
120
  std::swap(a.pinned_heap_handles, b.pinned_heap_handles);
117
121
  }
@@ -130,17 +134,7 @@ idx_t TupleDataSegment::ChunkCount() const {
130
134
  }
131
135
 
132
136
  idx_t TupleDataSegment::SizeInBytes() const {
133
- const auto &layout = allocator->GetLayout();
134
- idx_t total_size = 0;
135
- for (const auto &chunk : chunks) {
136
- total_size += chunk.count * layout.GetRowWidth();
137
- if (!layout.AllConstant()) {
138
- for (const auto &part : chunk.parts) {
139
- total_size += part.total_heap_size;
140
- }
141
- }
142
- }
143
- return total_size;
137
+ return data_size;
144
138
  }
145
139
 
146
140
  void TupleDataSegment::Unpin() {
@@ -151,12 +145,23 @@ void TupleDataSegment::Unpin() {
151
145
 
152
146
  void TupleDataSegment::Verify() const {
153
147
  #ifdef DEBUG
148
+ const auto &layout = allocator->GetLayout();
149
+
154
150
  idx_t total_count = 0;
151
+ idx_t total_size = 0;
155
152
  for (const auto &chunk : chunks) {
156
153
  chunk.Verify();
157
154
  total_count += chunk.count;
155
+
156
+ total_size += chunk.count * layout.GetRowWidth();
157
+ if (!layout.AllConstant()) {
158
+ for (const auto &part : chunk.parts) {
159
+ total_size += part.total_heap_size;
160
+ }
161
+ }
158
162
  }
159
163
  D_ASSERT(total_count == this->count);
164
+ D_ASSERT(total_size == this->data_size);
160
165
  #endif
161
166
  }
162
167
 
@@ -1780,58 +1780,69 @@ void Value::FormatSerialize(FormatSerializer &serializer) const {
1780
1780
  serializer.WriteProperty(101, "is_null", is_null);
1781
1781
  if (!IsNull()) {
1782
1782
  switch (type_.InternalType()) {
1783
+ case PhysicalType::BIT:
1784
+ throw InternalException("BIT type should not be serialized");
1783
1785
  case PhysicalType::BOOL:
1784
- serializer.WriteProperty(100, "value", value_.boolean);
1786
+ serializer.WriteProperty(102, "value", value_.boolean);
1785
1787
  break;
1786
1788
  case PhysicalType::INT8:
1787
- serializer.WriteProperty(100, "value", value_.tinyint);
1789
+ serializer.WriteProperty(102, "value", value_.tinyint);
1788
1790
  break;
1789
1791
  case PhysicalType::INT16:
1790
- serializer.WriteProperty(100, "value", value_.smallint);
1792
+ serializer.WriteProperty(102, "value", value_.smallint);
1791
1793
  break;
1792
1794
  case PhysicalType::INT32:
1793
- serializer.WriteProperty(100, "value", value_.integer);
1795
+ serializer.WriteProperty(102, "value", value_.integer);
1794
1796
  break;
1795
1797
  case PhysicalType::INT64:
1796
- serializer.WriteProperty(100, "value", value_.bigint);
1798
+ serializer.WriteProperty(102, "value", value_.bigint);
1797
1799
  break;
1798
1800
  case PhysicalType::UINT8:
1799
- serializer.WriteProperty(100, "value", value_.utinyint);
1801
+ serializer.WriteProperty(102, "value", value_.utinyint);
1800
1802
  break;
1801
1803
  case PhysicalType::UINT16:
1802
- serializer.WriteProperty(100, "value", value_.usmallint);
1804
+ serializer.WriteProperty(102, "value", value_.usmallint);
1803
1805
  break;
1804
1806
  case PhysicalType::UINT32:
1805
- serializer.WriteProperty(100, "value", value_.uinteger);
1807
+ serializer.WriteProperty(102, "value", value_.uinteger);
1806
1808
  break;
1807
1809
  case PhysicalType::UINT64:
1808
- serializer.WriteProperty(100, "value", value_.ubigint);
1810
+ serializer.WriteProperty(102, "value", value_.ubigint);
1809
1811
  break;
1810
1812
  case PhysicalType::INT128:
1811
- serializer.WriteProperty(100, "value", value_.hugeint);
1813
+ serializer.WriteProperty(102, "value", value_.hugeint);
1812
1814
  break;
1813
1815
  case PhysicalType::FLOAT:
1814
- serializer.WriteProperty(100, "value", value_.float_);
1816
+ serializer.WriteProperty(102, "value", value_.float_);
1815
1817
  break;
1816
1818
  case PhysicalType::DOUBLE:
1817
- serializer.WriteProperty(100, "value", value_.double_);
1819
+ serializer.WriteProperty(102, "value", value_.double_);
1818
1820
  break;
1819
1821
  case PhysicalType::INTERVAL:
1820
- serializer.WriteProperty(100, "value", value_.interval);
1822
+ serializer.WriteProperty(102, "value", value_.interval);
1821
1823
  break;
1822
- case PhysicalType::VARCHAR:
1824
+ case PhysicalType::VARCHAR: {
1823
1825
  if (type_.id() == LogicalTypeId::BLOB) {
1824
1826
  auto blob_str = Blob::ToString(StringValue::Get(*this));
1825
- serializer.WriteProperty(100, "value", blob_str);
1827
+ serializer.WriteProperty(102, "value", blob_str);
1826
1828
  } else {
1827
- serializer.WriteProperty(100, "value", StringValue::Get(*this));
1829
+ serializer.WriteProperty(102, "value", StringValue::Get(*this));
1828
1830
  }
1829
- break;
1830
- default: {
1831
- Vector v(*this);
1832
- v.FormatSerialize(serializer, 1);
1833
- break;
1834
- }
1831
+ } break;
1832
+ case PhysicalType::LIST: {
1833
+ serializer.WriteObject(102, "value", [&](FormatSerializer &serializer) {
1834
+ auto &children = ListValue::GetChildren(*this);
1835
+ serializer.WriteProperty(100, "children", children);
1836
+ });
1837
+ } break;
1838
+ case PhysicalType::STRUCT: {
1839
+ serializer.WriteObject(102, "value", [&](FormatSerializer &serializer) {
1840
+ auto &children = StructValue::GetChildren(*this);
1841
+ serializer.WriteProperty(100, "children", children);
1842
+ });
1843
+ } break;
1844
+ default:
1845
+ throw NotImplementedException("Unimplemented type for FormatSerialize");
1835
1846
  }
1836
1847
  }
1837
1848
  }
@@ -1845,59 +1856,69 @@ Value Value::FormatDeserialize(FormatDeserializer &deserializer) {
1845
1856
  }
1846
1857
  new_value.is_null = false;
1847
1858
  switch (type.InternalType()) {
1859
+ case PhysicalType::BIT:
1860
+ throw InternalException("BIT type should not be deserialized");
1848
1861
  case PhysicalType::BOOL:
1849
- new_value.value_.boolean = deserializer.ReadProperty<bool>(100, "value");
1862
+ new_value.value_.boolean = deserializer.ReadProperty<bool>(102, "value");
1850
1863
  break;
1851
1864
  case PhysicalType::UINT8:
1852
- new_value.value_.utinyint = deserializer.ReadProperty<uint8_t>(100, "value");
1865
+ new_value.value_.utinyint = deserializer.ReadProperty<uint8_t>(102, "value");
1853
1866
  break;
1854
1867
  case PhysicalType::INT8:
1855
- new_value.value_.tinyint = deserializer.ReadProperty<int8_t>(100, "value");
1868
+ new_value.value_.tinyint = deserializer.ReadProperty<int8_t>(102, "value");
1856
1869
  break;
1857
1870
  case PhysicalType::UINT16:
1858
- new_value.value_.usmallint = deserializer.ReadProperty<uint16_t>(100, "value");
1871
+ new_value.value_.usmallint = deserializer.ReadProperty<uint16_t>(102, "value");
1859
1872
  break;
1860
1873
  case PhysicalType::INT16:
1861
- new_value.value_.smallint = deserializer.ReadProperty<int16_t>(100, "value");
1874
+ new_value.value_.smallint = deserializer.ReadProperty<int16_t>(102, "value");
1862
1875
  break;
1863
1876
  case PhysicalType::UINT32:
1864
- new_value.value_.uinteger = deserializer.ReadProperty<uint32_t>(100, "value");
1877
+ new_value.value_.uinteger = deserializer.ReadProperty<uint32_t>(102, "value");
1865
1878
  break;
1866
1879
  case PhysicalType::INT32:
1867
- new_value.value_.integer = deserializer.ReadProperty<int32_t>(100, "value");
1880
+ new_value.value_.integer = deserializer.ReadProperty<int32_t>(102, "value");
1868
1881
  break;
1869
1882
  case PhysicalType::UINT64:
1870
- new_value.value_.ubigint = deserializer.ReadProperty<uint64_t>(100, "value");
1883
+ new_value.value_.ubigint = deserializer.ReadProperty<uint64_t>(102, "value");
1871
1884
  break;
1872
1885
  case PhysicalType::INT64:
1873
- new_value.value_.bigint = deserializer.ReadProperty<int64_t>(100, "value");
1886
+ new_value.value_.bigint = deserializer.ReadProperty<int64_t>(102, "value");
1874
1887
  break;
1875
1888
  case PhysicalType::INT128:
1876
- new_value.value_.hugeint = deserializer.ReadProperty<hugeint_t>(100, "value");
1889
+ new_value.value_.hugeint = deserializer.ReadProperty<hugeint_t>(102, "value");
1877
1890
  break;
1878
1891
  case PhysicalType::FLOAT:
1879
- new_value.value_.float_ = deserializer.ReadProperty<float>(100, "value");
1892
+ new_value.value_.float_ = deserializer.ReadProperty<float>(102, "value");
1880
1893
  break;
1881
1894
  case PhysicalType::DOUBLE:
1882
- new_value.value_.double_ = deserializer.ReadProperty<double>(100, "value");
1895
+ new_value.value_.double_ = deserializer.ReadProperty<double>(102, "value");
1883
1896
  break;
1884
1897
  case PhysicalType::INTERVAL:
1885
- new_value.value_.interval = deserializer.ReadProperty<interval_t>(100, "value");
1898
+ new_value.value_.interval = deserializer.ReadProperty<interval_t>(102, "value");
1886
1899
  break;
1887
1900
  case PhysicalType::VARCHAR: {
1888
- auto str = deserializer.ReadProperty<string>(100, "value");
1901
+ auto str = deserializer.ReadProperty<string>(102, "value");
1889
1902
  if (type.id() == LogicalTypeId::BLOB) {
1890
1903
  new_value.value_info_ = make_shared<StringValueInfo>(Blob::ToBlob(str));
1891
1904
  } else {
1892
1905
  new_value.value_info_ = make_shared<StringValueInfo>(str);
1893
1906
  }
1894
1907
  } break;
1895
- default: {
1896
- Vector v(type);
1897
- v.FormatDeserialize(deserializer, 1);
1898
- new_value = v.GetValue(0);
1899
- break;
1900
- }
1908
+ case PhysicalType::LIST: {
1909
+ deserializer.ReadObject(102, "value", [&](FormatDeserializer &obj) {
1910
+ auto children = obj.ReadProperty<vector<Value>>(100, "children");
1911
+ new_value.value_info_ = make_shared<NestedValueInfo>(children);
1912
+ });
1913
+ } break;
1914
+ case PhysicalType::STRUCT: {
1915
+ deserializer.ReadObject(102, "value", [&](FormatDeserializer &obj) {
1916
+ auto children = obj.ReadProperty<vector<Value>>(100, "children");
1917
+ new_value.value_info_ = make_shared<NestedValueInfo>(children);
1918
+ });
1919
+ } break;
1920
+ default:
1921
+ throw NotImplementedException("Unimplemented type for FormatDeserialize");
1901
1922
  }
1902
1923
  return new_value;
1903
1924
  }