duckdb 0.7.2-dev3710.0 → 0.7.2-dev3763.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 (94) hide show
  1. package/package.json +1 -1
  2. package/src/database.cpp +0 -1
  3. package/src/duckdb/extension/json/json_functions/read_json.cpp +3 -3
  4. package/src/duckdb/extension/json/json_scan.cpp +16 -12
  5. package/src/duckdb/src/common/arrow/arrow_converter.cpp +4 -4
  6. package/src/duckdb/src/common/compressed_file_system.cpp +2 -2
  7. package/src/duckdb/src/common/file_system.cpp +2 -2
  8. package/src/duckdb/src/common/row_operations/row_gather.cpp +2 -2
  9. package/src/duckdb/src/common/serializer/binary_deserializer.cpp +1 -1
  10. package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +1 -1
  11. package/src/duckdb/src/common/serializer/buffered_file_writer.cpp +1 -1
  12. package/src/duckdb/src/common/serializer/buffered_serializer.cpp +3 -3
  13. package/src/duckdb/src/common/serializer.cpp +1 -1
  14. package/src/duckdb/src/common/sort/radix_sort.cpp +5 -5
  15. package/src/duckdb/src/common/string_util.cpp +6 -2
  16. package/src/duckdb/src/common/types/bit.cpp +2 -2
  17. package/src/duckdb/src/common/types/blob.cpp +2 -2
  18. package/src/duckdb/src/common/types/data_chunk.cpp +2 -2
  19. package/src/duckdb/src/common/types/date.cpp +1 -1
  20. package/src/duckdb/src/common/types/decimal.cpp +2 -2
  21. package/src/duckdb/src/common/types/selection_vector.cpp +1 -1
  22. package/src/duckdb/src/common/types/time.cpp +1 -1
  23. package/src/duckdb/src/common/types/vector.cpp +7 -7
  24. package/src/duckdb/src/common/windows_util.cpp +2 -2
  25. package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +1 -1
  26. package/src/duckdb/src/core_functions/scalar/string/printf.cpp +1 -1
  27. package/src/duckdb/src/execution/aggregate_hashtable.cpp +1 -1
  28. package/src/duckdb/src/execution/join_hashtable.cpp +3 -3
  29. package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +2 -2
  30. package/src/duckdb/src/execution/operator/join/outer_join_marker.cpp +1 -1
  31. package/src/duckdb/src/execution/operator/join/perfect_hash_join_executor.cpp +1 -1
  32. package/src/duckdb/src/execution/operator/join/physical_range_join.cpp +1 -1
  33. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
  34. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +91 -30
  35. package/src/duckdb/src/execution/operator/projection/physical_pivot.cpp +1 -1
  36. package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +1 -1
  37. package/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +2 -2
  38. package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +3 -3
  39. package/src/duckdb/src/execution/window_segment_tree.cpp +1 -1
  40. package/src/duckdb/src/function/pragma/pragma_queries.cpp +1 -1
  41. package/src/duckdb/src/function/scalar/strftime_format.cpp +1 -1
  42. package/src/duckdb/src/function/scalar/string/concat.cpp +1 -1
  43. package/src/duckdb/src/function/scalar/string/like.cpp +2 -2
  44. package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +5 -5
  45. package/src/duckdb/src/function/table/copy_csv.cpp +1 -1
  46. package/src/duckdb/src/function/table/table_scan.cpp +7 -3
  47. package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -6
  48. package/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp +2 -2
  49. package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -9
  50. package/src/duckdb/src/include/duckdb/common/http_state.hpp +2 -2
  51. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +1 -1
  52. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_writer.hpp +1 -1
  53. package/src/duckdb/src/include/duckdb/common/serializer/buffered_serializer.hpp +2 -2
  54. package/src/duckdb/src/include/duckdb/common/sort/duckdb_pdqsort.hpp +10 -10
  55. package/src/duckdb/src/include/duckdb/common/string_util.hpp +2 -0
  56. package/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +1 -1
  57. package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
  58. package/src/duckdb/src/include/duckdb/common/types/validity_mask.hpp +3 -3
  59. package/src/duckdb/src/include/duckdb/common/types/vector_buffer.hpp +4 -4
  60. package/src/duckdb/src/include/duckdb/common/unique_ptr.hpp +8 -8
  61. package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +1 -1
  62. package/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +3 -3
  63. package/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp +1 -1
  64. package/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp +1 -1
  65. package/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp +1 -1
  66. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +2 -2
  67. package/src/duckdb/src/include/duckdb/execution/operator/persistent/parallel_csv_reader.hpp +2 -2
  68. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +2 -3
  69. package/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +2 -2
  70. package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +1 -1
  71. package/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/main/client_data.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/optimizer/join_order/join_relation.hpp +3 -3
  74. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +4 -0
  75. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +1 -1
  76. package/src/duckdb/src/include/duckdb/storage/table/append_state.hpp +1 -1
  77. package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +5 -5
  79. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -2
  80. package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +1 -1
  81. package/src/duckdb/src/main/client_context.cpp +4 -4
  82. package/src/duckdb/src/main/extension/extension_install.cpp +2 -2
  83. package/src/duckdb/src/optimizer/join_order/join_relation_set.cpp +5 -5
  84. package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +7 -1
  85. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -1
  86. package/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp +1 -1
  87. package/src/duckdb/src/storage/compression/string_uncompressed.cpp +2 -2
  88. package/src/duckdb/src/storage/data_table.cpp +75 -44
  89. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  90. package/src/duckdb/src/storage/statistics/list_stats.cpp +1 -1
  91. package/src/duckdb/src/storage/statistics/struct_stats.cpp +1 -1
  92. package/src/duckdb/src/storage/table/row_group.cpp +11 -11
  93. package/src/duckdb/src/storage/table/scan_state.cpp +1 -1
  94. package/src/duckdb/src/storage/table/update_segment.cpp +6 -6
@@ -101,7 +101,9 @@ public:
101
101
  unique_ptr<RowGroupCollection> local_collection;
102
102
  optional_ptr<OptimisticDataWriter> writer;
103
103
  // Rows that have been updated by a DO UPDATE conflict
104
- unordered_set<row_t> updated_rows;
104
+ unordered_set<row_t> updated_global_rows;
105
+ // Rows in the transaction-local storage that have been updated by a DO UPDATE conflict
106
+ unordered_set<row_t> updated_local_rows;
105
107
  idx_t update_count = 0;
106
108
  };
107
109
 
@@ -177,8 +179,11 @@ void CheckOnConflictCondition(ExecutionContext &context, DataChunk &conflicts, c
177
179
  result.SetCardinality(conflicts.size());
178
180
  }
179
181
 
180
- void PhysicalInsert::CombineExistingAndInsertTuples(DataChunk &result, DataChunk &scan_chunk, DataChunk &input_chunk,
181
- ClientContext &client) const {
182
+ static void CombineExistingAndInsertTuples(DataChunk &result, DataChunk &scan_chunk, DataChunk &input_chunk,
183
+ ClientContext &client, const PhysicalInsert &op) {
184
+ auto &types_to_fetch = op.types_to_fetch;
185
+ auto &insert_types = op.insert_types;
186
+
182
187
  if (types_to_fetch.empty()) {
183
188
  // We have not scanned the initial table, so we can just duplicate the initial chunk
184
189
  result.Initialize(client, input_chunk.GetTypes());
@@ -218,14 +223,12 @@ void PhysicalInsert::CombineExistingAndInsertTuples(DataChunk &result, DataChunk
218
223
  result.SetCardinality(input_chunk.size());
219
224
  }
220
225
 
221
- idx_t PhysicalInsert::PerformOnConflictAction(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry &table,
222
- Vector &row_ids) const {
223
- if (action_type == OnConflictAction::NOTHING) {
224
- return 0;
225
- }
226
-
227
- DataChunk update_chunk; // contains only the to-update columns
226
+ static void CreateUpdateChunk(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry &table, Vector &row_ids,
227
+ DataChunk &update_chunk, const PhysicalInsert &op) {
228
228
 
229
+ auto &do_update_condition = op.do_update_condition;
230
+ auto &set_types = op.set_types;
231
+ auto &set_expressions = op.set_expressions;
229
232
  // Check the optional condition for the DO UPDATE clause, to filter which rows will be updated
230
233
  if (do_update_condition) {
231
234
  DataChunk do_update_filter_result;
@@ -256,19 +259,43 @@ idx_t PhysicalInsert::PerformOnConflictAction(ExecutionContext &context, DataChu
256
259
  ExpressionExecutor executor(context.client, set_expressions);
257
260
  executor.Execute(chunk, update_chunk);
258
261
  update_chunk.SetCardinality(chunk);
262
+ }
263
+
264
+ template <bool GLOBAL>
265
+ static idx_t PerformOnConflictAction(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry &table,
266
+ Vector &row_ids, const PhysicalInsert &op) {
267
+
268
+ if (op.action_type == OnConflictAction::NOTHING) {
269
+ return 0;
270
+ }
271
+ auto &set_columns = op.set_columns;
272
+
273
+ DataChunk update_chunk;
274
+ CreateUpdateChunk(context, chunk, table, row_ids, update_chunk, op);
259
275
 
260
276
  auto &data_table = table.GetStorage();
261
277
  // Perform the update, using the results of the SET expressions
262
- data_table.Update(table, context.client, row_ids, set_columns, update_chunk);
278
+ if (GLOBAL) {
279
+ data_table.Update(table, context.client, row_ids, set_columns, update_chunk);
280
+ } else {
281
+ auto &local_storage = LocalStorage::Get(context.client, data_table.db);
282
+ // Perform the update, using the results of the SET expressions
283
+ local_storage.Update(data_table, row_ids, set_columns, update_chunk);
284
+ }
263
285
  return update_chunk.size();
264
286
  }
265
287
 
266
288
  // TODO: should we use a hash table to keep track of this instead?
267
- void PhysicalInsert::RegisterUpdatedRows(InsertLocalState &lstate, const Vector &row_ids, idx_t count) const {
289
+ template <bool GLOBAL>
290
+ static void RegisterUpdatedRows(InsertLocalState &lstate, const Vector &row_ids, idx_t count) {
268
291
  // Insert all rows, if any of the rows has already been updated before, we throw an error
269
292
  auto data = FlatVector::GetData<row_t>(row_ids);
293
+
294
+ // The rowids in the transaction-local ART aren't final yet so we have to separately keep track of the two sets of
295
+ // rowids
296
+ unordered_set<row_t> &updated_rows = GLOBAL ? lstate.updated_global_rows : lstate.updated_local_rows;
270
297
  for (idx_t i = 0; i < count; i++) {
271
- auto result = lstate.updated_rows.insert(data[i]);
298
+ auto result = updated_rows.insert(data[i]);
272
299
  if (result.second == false) {
273
300
  throw InvalidInputException(
274
301
  "ON CONFLICT DO UPDATE can not update the same row twice in the same command, Ensure that no rows "
@@ -277,20 +304,25 @@ void PhysicalInsert::RegisterUpdatedRows(InsertLocalState &lstate, const Vector
277
304
  }
278
305
  }
279
306
 
280
- idx_t PhysicalInsert::OnConflictHandling(TableCatalogEntry &table, ExecutionContext &context,
281
- InsertLocalState &lstate) const {
282
- auto &data_table = table.GetStorage();
283
- if (action_type == OnConflictAction::THROW) {
284
- data_table.VerifyAppendConstraints(table, context.client, lstate.insert_chunk, nullptr);
285
- return 0;
286
- }
287
- // Check whether any conflicts arise, and if they all meet the conflict_target + condition
288
- // If that's not the case - We throw the first error
307
+ template <bool GLOBAL>
308
+ static idx_t HandleInsertConflicts(TableCatalogEntry &table, ExecutionContext &context, InsertLocalState &lstate,
309
+ DataTable &data_table, const PhysicalInsert &op) {
310
+ auto &types_to_fetch = op.types_to_fetch;
311
+ auto &on_conflict_condition = op.on_conflict_condition;
312
+ auto &conflict_target = op.conflict_target;
313
+ auto &columns_to_fetch = op.columns_to_fetch;
314
+
315
+ auto &local_storage = LocalStorage::Get(context.client, data_table.db);
289
316
 
290
317
  // We either want to do nothing, or perform an update when conflicts arise
291
318
  ConflictInfo conflict_info(conflict_target);
292
319
  ConflictManager conflict_manager(VerifyExistenceType::APPEND, lstate.insert_chunk.size(), &conflict_info);
293
- data_table.VerifyAppendConstraints(table, context.client, lstate.insert_chunk, &conflict_manager);
320
+ if (GLOBAL) {
321
+ data_table.VerifyAppendConstraints(table, context.client, lstate.insert_chunk, &conflict_manager);
322
+ } else {
323
+ DataTable::VerifyUniqueIndexes(local_storage.GetIndexes(data_table), context.client, lstate.insert_chunk,
324
+ &conflict_manager);
325
+ }
294
326
  conflict_manager.Finalize();
295
327
  if (conflict_manager.ConflictCount() == 0) {
296
328
  // No conflicts found, 0 updates performed
@@ -309,18 +341,25 @@ idx_t PhysicalInsert::OnConflictHandling(TableCatalogEntry &table, ExecutionCont
309
341
  conflict_chunk.Slice(conflicts.Selection(), conflicts.Count());
310
342
  conflict_chunk.SetCardinality(conflicts.Count());
311
343
 
344
+ // Holds the pins for the fetched rows
345
+ unique_ptr<ColumnFetchState> fetch_state;
312
346
  if (!types_to_fetch.empty()) {
313
347
  D_ASSERT(scan_chunk.size() == 0);
314
348
  // When these values are required for the conditions or the SET expressions,
315
349
  // then we scan the existing table for the conflicting tuples, using the rowids
316
350
  scan_chunk.Initialize(context.client, types_to_fetch);
317
- auto fetch_state = make_uniq<ColumnFetchState>();
318
- auto &transaction = DuckTransaction::Get(context.client, table.catalog);
319
- data_table.Fetch(transaction, scan_chunk, columns_to_fetch, row_ids, conflicts.Count(), *fetch_state);
351
+ fetch_state = make_uniq<ColumnFetchState>();
352
+ if (GLOBAL) {
353
+ auto &transaction = DuckTransaction::Get(context.client, table.catalog);
354
+ data_table.Fetch(transaction, scan_chunk, columns_to_fetch, row_ids, conflicts.Count(), *fetch_state);
355
+ } else {
356
+ local_storage.FetchChunk(data_table, row_ids, conflicts.Count(), columns_to_fetch, scan_chunk,
357
+ *fetch_state);
358
+ }
320
359
  }
321
360
 
322
361
  // Splice the Input chunk and the fetched chunk together
323
- CombineExistingAndInsertTuples(combined_chunk, scan_chunk, conflict_chunk, context.client);
362
+ CombineExistingAndInsertTuples(combined_chunk, scan_chunk, conflict_chunk, context.client, op);
324
363
 
325
364
  if (on_conflict_condition) {
326
365
  DataChunk conflict_condition_result;
@@ -338,14 +377,19 @@ idx_t PhysicalInsert::OnConflictHandling(TableCatalogEntry &table, ExecutionCont
338
377
  }
339
378
  combined_chunk.Slice(sel.Selection(), sel.Count());
340
379
  row_ids.Slice(sel.Selection(), sel.Count());
341
- data_table.VerifyAppendConstraints(table, context.client, combined_chunk, nullptr);
380
+ if (GLOBAL) {
381
+ data_table.VerifyAppendConstraints(table, context.client, combined_chunk, nullptr);
382
+ } else {
383
+ DataTable::VerifyUniqueIndexes(local_storage.GetIndexes(data_table), context.client,
384
+ lstate.insert_chunk, nullptr);
385
+ }
342
386
  throw InternalException("The previous operation was expected to throw but didn't");
343
387
  }
344
388
  }
345
389
 
346
- RegisterUpdatedRows(lstate, row_ids, combined_chunk.size());
390
+ RegisterUpdatedRows<GLOBAL>(lstate, row_ids, combined_chunk.size());
347
391
 
348
- idx_t updated_tuples = PerformOnConflictAction(context, combined_chunk, table, row_ids);
392
+ idx_t updated_tuples = PerformOnConflictAction<GLOBAL>(context, combined_chunk, table, row_ids, op);
349
393
 
350
394
  // Remove the conflicting tuples from the insert chunk
351
395
  SelectionVector sel_vec(lstate.insert_chunk.size());
@@ -356,6 +400,23 @@ idx_t PhysicalInsert::OnConflictHandling(TableCatalogEntry &table, ExecutionCont
356
400
  return updated_tuples;
357
401
  }
358
402
 
403
+ idx_t PhysicalInsert::OnConflictHandling(TableCatalogEntry &table, ExecutionContext &context,
404
+ InsertLocalState &lstate) const {
405
+ auto &data_table = table.GetStorage();
406
+ if (action_type == OnConflictAction::THROW) {
407
+ data_table.VerifyAppendConstraints(table, context.client, lstate.insert_chunk, nullptr);
408
+ return 0;
409
+ }
410
+ // Check whether any conflicts arise, and if they all meet the conflict_target + condition
411
+ // If that's not the case - We throw the first error
412
+ idx_t updated_tuples = 0;
413
+ updated_tuples += HandleInsertConflicts<true>(table, context, lstate, data_table, *this);
414
+ // Also check the transaction-local storage+ART so we can detect conflicts within this transaction
415
+ updated_tuples += HandleInsertConflicts<false>(table, context, lstate, data_table, *this);
416
+
417
+ return updated_tuples;
418
+ }
419
+
359
420
  SinkResultType PhysicalInsert::Sink(ExecutionContext &context, DataChunk &chunk, OperatorSinkInput &input) const {
360
421
  auto &gstate = input.global_state.Cast<InsertGlobalState>();
361
422
  auto &lstate = input.local_state.Cast<InsertLocalState>();
@@ -19,7 +19,7 @@ PhysicalPivot::PhysicalPivot(vector<LogicalType> types_p, unique_ptr<PhysicalOpe
19
19
  for (auto &aggr_expr : bound_pivot.aggregates) {
20
20
  auto &aggr = (BoundAggregateExpression &)*aggr_expr;
21
21
  // for each aggregate, initialize an empty aggregate state and finalize it immediately
22
- auto state = make_unsafe_array<data_t>(aggr.function.state_size());
22
+ auto state = make_unsafe_uniq_array<data_t>(aggr.function.state_size());
23
23
  aggr.function.initialize(state.get());
24
24
  Vector state_vector(Value::POINTER((uintptr_t)state.get()));
25
25
  Vector result_vector(aggr_expr->return_type);
@@ -17,7 +17,6 @@ PhysicalCreateIndex::PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry
17
17
  : PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types, estimated_cardinality),
18
18
  table(table_p.Cast<DuckTableEntry>()), info(std::move(info)),
19
19
  unbound_expressions(std::move(unbound_expressions)) {
20
- D_ASSERT(table_p.IsDuckTable());
21
20
  // convert virtual column ids to storage column ids
22
21
  for (auto &column_id : column_ids) {
23
22
  storage_ids.push_back(table.GetColumns().LogicalToPhysical(LogicalIndex(column_id)).index);
@@ -136,6 +135,7 @@ SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event,
136
135
  auto &schema = table.schema;
137
136
  auto index_entry = schema.CreateIndex(context, *info, table).get();
138
137
  if (!index_entry) {
138
+ D_ASSERT(info->on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT);
139
139
  // index already exists, but error ignored because of IF NOT EXISTS
140
140
  return SinkFinalizeType::READY;
141
141
  }
@@ -23,11 +23,11 @@ PerfectAggregateHashTable::PerfectAggregateHashTable(ClientContext &context, All
23
23
  tuple_size = layout.GetRowWidth();
24
24
 
25
25
  // allocate and null initialize the data
26
- owned_data = make_unsafe_array<data_t>(tuple_size * total_groups);
26
+ owned_data = make_unsafe_uniq_array<data_t>(tuple_size * total_groups);
27
27
  data = owned_data.get();
28
28
 
29
29
  // set up the empty payloads for every tuple, and initialize the "occupied" flag to false
30
- group_is_set = make_unsafe_array<bool>(total_groups);
30
+ group_is_set = make_unsafe_uniq_array<bool>(total_groups);
31
31
  memset(group_is_set.get(), 0, total_groups * sizeof(bool));
32
32
 
33
33
  // initialize the hash table for each entry
@@ -334,7 +334,7 @@ public:
334
334
  //! The current position to scan the HT for output tuples
335
335
  idx_t ht_index;
336
336
  //! The set of aggregate scan states
337
- unsafe_array_ptr<TupleDataParallelScanState> ht_scan_states;
337
+ unsafe_unique_array<TupleDataParallelScanState> ht_scan_states;
338
338
  atomic<bool> initialized;
339
339
  atomic<bool> finished;
340
340
  };
@@ -404,7 +404,7 @@ SourceResultType RadixPartitionedHashTable::GetData(ExecutionContext &context, D
404
404
  for (idx_t i = 0; i < op.aggregates.size(); i++) {
405
405
  D_ASSERT(op.aggregates[i]->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
406
406
  auto &aggr = op.aggregates[i]->Cast<BoundAggregateExpression>();
407
- auto aggr_state = make_unsafe_array<data_t>(aggr.function.state_size());
407
+ auto aggr_state = make_unsafe_uniq_array<data_t>(aggr.function.state_size());
408
408
  aggr.function.initialize(aggr_state.get());
409
409
 
410
410
  AggregateInputData aggr_input_data(aggr.bind_info.get(), Allocator::DefaultAllocator());
@@ -433,7 +433,7 @@ SourceResultType RadixPartitionedHashTable::GetData(ExecutionContext &context, D
433
433
  lock_guard<mutex> l(state.lock);
434
434
  if (!state.initialized) {
435
435
  auto &finalized_hts = gstate.finalized_hts;
436
- state.ht_scan_states = make_unsafe_array<TupleDataParallelScanState>(finalized_hts.size());
436
+ state.ht_scan_states = make_unsafe_uniq_array<TupleDataParallelScanState>(finalized_hts.size());
437
437
 
438
438
  const auto &layout = gstate.finalized_hts[0]->GetDataCollection().GetLayout();
439
439
  vector<column_t> column_ids;
@@ -309,7 +309,7 @@ void WindowSegmentTree::ConstructTree() {
309
309
  level_nodes = (level_nodes + (TREE_FANOUT - 1)) / TREE_FANOUT;
310
310
  internal_nodes += level_nodes;
311
311
  } while (level_nodes > 1);
312
- levels_flat_native = make_unsafe_array<data_t>(internal_nodes * state.size());
312
+ levels_flat_native = make_unsafe_uniq_array<data_t>(internal_nodes * state.size());
313
313
  levels_flat_start.push_back(0);
314
314
 
315
315
  idx_t levels_flat_offset = 0;
@@ -141,7 +141,7 @@ string PragmaImportDatabase(ClientContext &context, const FunctionParameters &pa
141
141
  auto handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_READ, FileSystem::DEFAULT_LOCK,
142
142
  FileSystem::DEFAULT_COMPRESSION);
143
143
  auto fsize = fs.GetFileSize(*handle);
144
- auto buffer = make_unsafe_array<char>(fsize);
144
+ auto buffer = make_unsafe_uniq_array<char>(fsize);
145
145
  fs.Read(*handle, buffer.get(), fsize);
146
146
  auto query = string(buffer.get(), fsize);
147
147
  // Replace the placeholder with the path provided to IMPORT
@@ -408,7 +408,7 @@ string StrfTimeFormat::Format(timestamp_t timestamp, const string &format_str) {
408
408
  auto time = Timestamp::GetTime(timestamp);
409
409
 
410
410
  auto len = format.GetLength(date, time, 0, nullptr);
411
- auto result = make_unsafe_array<char>(len);
411
+ auto result = make_unsafe_uniq_array<char>(len);
412
412
  format.FormatString(date, time, result.get());
413
413
  return string(result.get(), len);
414
414
  }
@@ -118,7 +118,7 @@ static void TemplatedConcatWS(DataChunk &args, string_t *sep_data, const Selecti
118
118
  const SelectionVector &rsel, idx_t count, Vector &result) {
119
119
  vector<idx_t> result_lengths(args.size(), 0);
120
120
  vector<bool> has_results(args.size(), false);
121
- auto orrified_data = make_unsafe_array<UnifiedVectorFormat>(args.ColumnCount() - 1);
121
+ auto orrified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(args.ColumnCount() - 1);
122
122
  for (idx_t col_idx = 1; col_idx < args.ColumnCount(); col_idx++) {
123
123
  args.data[col_idx].ToUnifiedFormat(args.size(), orrified_data[col_idx - 1]);
124
124
  }
@@ -395,11 +395,11 @@ bool ILikeOperatorFunction(string_t &str, string_t &pattern, char escape = '\0')
395
395
 
396
396
  // lowercase both the str and the pattern
397
397
  idx_t str_llength = LowerFun::LowerLength(str_data, str_size);
398
- auto str_ldata = make_unsafe_array<char>(str_llength);
398
+ auto str_ldata = make_unsafe_uniq_array<char>(str_llength);
399
399
  LowerFun::LowerCase(str_data, str_size, str_ldata.get());
400
400
 
401
401
  idx_t pat_llength = LowerFun::LowerLength(pat_data, pat_size);
402
- auto pat_ldata = make_unsafe_array<char>(pat_llength);
402
+ auto pat_ldata = make_unsafe_uniq_array<char>(pat_llength);
403
403
  LowerFun::LowerCase(pat_data, pat_size, pat_ldata.get());
404
404
  string_t str_lcase(str_ldata.get(), str_llength);
405
405
  string_t pat_lcase(pat_ldata.get(), pat_llength);
@@ -36,12 +36,12 @@ struct ExportAggregateBindData : public FunctionData {
36
36
  struct CombineState : public FunctionLocalState {
37
37
  idx_t state_size;
38
38
 
39
- unsafe_array_ptr<data_t> state_buffer0, state_buffer1;
39
+ unsafe_unique_array<data_t> state_buffer0, state_buffer1;
40
40
  Vector state_vector0, state_vector1;
41
41
 
42
42
  explicit CombineState(idx_t state_size_p)
43
- : state_size(state_size_p), state_buffer0(make_unsafe_array<data_t>(state_size_p)),
44
- state_buffer1(make_unsafe_array<data_t>(state_size_p)),
43
+ : state_size(state_size_p), state_buffer0(make_unsafe_uniq_array<data_t>(state_size_p)),
44
+ state_buffer1(make_unsafe_uniq_array<data_t>(state_size_p)),
45
45
  state_vector0(Value::POINTER((uintptr_t)state_buffer0.get())),
46
46
  state_vector1(Value::POINTER((uintptr_t)state_buffer1.get())) {
47
47
  }
@@ -55,12 +55,12 @@ static unique_ptr<FunctionLocalState> InitCombineState(ExpressionState &state, c
55
55
 
56
56
  struct FinalizeState : public FunctionLocalState {
57
57
  idx_t state_size;
58
- unsafe_array_ptr<data_t> state_buffer;
58
+ unsafe_unique_array<data_t> state_buffer;
59
59
  Vector addresses;
60
60
 
61
61
  explicit FinalizeState(idx_t state_size_p)
62
62
  : state_size(state_size_p),
63
- state_buffer(make_unsafe_array<data_t>(STANDARD_VECTOR_SIZE * AlignValue(state_size_p))),
63
+ state_buffer(make_unsafe_uniq_array<data_t>(STANDARD_VECTOR_SIZE * AlignValue(state_size_p))),
64
64
  addresses(LogicalType::POINTER) {
65
65
  }
66
66
  };
@@ -88,7 +88,7 @@ static unique_ptr<FunctionData> WriteCSVBind(ClientContext &context, CopyInfo &i
88
88
  bind_data->is_simple = bind_data->options.delimiter.size() == 1 && bind_data->options.escape.size() == 1 &&
89
89
  bind_data->options.quote.size() == 1;
90
90
  if (bind_data->is_simple) {
91
- bind_data->requires_quotes = make_unsafe_array<bool>(256);
91
+ bind_data->requires_quotes = make_unsafe_uniq_array<bool>(256);
92
92
  memset(bind_data->requires_quotes.get(), 0, sizeof(bool) * 256);
93
93
  bind_data->requires_quotes['\n'] = true;
94
94
  bind_data->requires_quotes['\r'] = true;
@@ -207,7 +207,7 @@ struct IndexScanGlobalState : public GlobalTableFunctionState {
207
207
  Vector row_ids;
208
208
  ColumnFetchState fetch_state;
209
209
  TableScanState local_storage_state;
210
- vector<column_t> column_ids;
210
+ vector<storage_t> column_ids;
211
211
  bool finished;
212
212
  };
213
213
 
@@ -219,8 +219,12 @@ static unique_ptr<GlobalTableFunctionState> IndexScanInitGlobal(ClientContext &c
219
219
  }
220
220
  auto result = make_uniq<IndexScanGlobalState>(row_id_data);
221
221
  auto &local_storage = LocalStorage::Get(context, bind_data.table.catalog);
222
- result->column_ids = input.column_ids;
223
- result->local_storage_state.Initialize(input.column_ids, input.filters.get());
222
+
223
+ result->column_ids.reserve(input.column_ids.size());
224
+ for (auto &id : input.column_ids) {
225
+ result->column_ids.push_back(GetStorageIndex(bind_data.table, id));
226
+ }
227
+ result->local_storage_state.Initialize(result->column_ids, input.filters.get());
224
228
  local_storage.InitializeScan(bind_data.table.GetStorage(), result->local_storage_state.local_state, input.filters);
225
229
 
226
230
  result->finished = false;
@@ -1,16 +1,14 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.7.2-dev3710"
2
+ #define DUCKDB_VERSION "0.7.2-dev3763"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "59a4ec3adc"
5
+ #define DUCKDB_SOURCE_ID "d3562b54ee"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
9
9
 
10
10
  #include <cstdint>
11
11
 
12
- #define DUCKDB_STRINGIFY(x) #x
13
-
14
12
  namespace duckdb {
15
13
 
16
14
  struct PragmaVersionData : public GlobalTableFunctionState {
@@ -93,8 +91,8 @@ string DuckDB::Platform() {
93
91
  postfix = "_mingw";
94
92
  #endif
95
93
  // this is used for the windows R builds which use a separate build environment
96
- #ifdef DUCKDB_OVERRIDE_PLATFORM_POSTFIX
97
- postfix = DUCKDB_STRINGIFY(DUCKDB_OVERRIDE_PLATFORM_POSTFIX);
94
+ #ifdef DUCKDB_PLATFORM_RTOOLS
95
+ postfix = "_rtools";
98
96
  #endif
99
97
  return os + "_" + arch + postfix;
100
98
  }
@@ -18,8 +18,8 @@ struct StreamData {
18
18
  // various buffers & pointers
19
19
  bool write = false;
20
20
  bool refresh = false;
21
- unsafe_array_ptr<data_t> in_buff;
22
- unsafe_array_ptr<data_t> out_buff;
21
+ unsafe_unique_array<data_t> in_buff;
22
+ unsafe_unique_array<data_t> out_buff;
23
23
  data_ptr_t out_buff_start = nullptr;
24
24
  data_ptr_t out_buff_end = nullptr;
25
25
  data_ptr_t in_buff_start = nullptr;
@@ -40,7 +40,7 @@ namespace duckdb {
40
40
  template<class _Tp, bool SAFE = true>
41
41
  struct __unique_if
42
42
  {
43
- typedef unique_ptr<_Tp, SAFE> __unique_single;
43
+ typedef unique_ptr<_Tp, std::default_delete<_Tp>, SAFE> __unique_single;
44
44
  };
45
45
 
46
46
  template<class _Tp>
@@ -60,7 +60,7 @@ inline
60
60
  typename __unique_if<_Tp, true>::__unique_single
61
61
  make_uniq(_Args&&... __args)
62
62
  {
63
- return unique_ptr<_Tp, true>(new _Tp(std::forward<_Args>(__args)...));
63
+ return unique_ptr<_Tp, std::default_delete<_Tp>, true>(new _Tp(std::forward<_Args>(__args)...));
64
64
  }
65
65
 
66
66
  template<class _Tp, class... _Args>
@@ -68,21 +68,21 @@ inline
68
68
  typename __unique_if<_Tp, false>::__unique_single
69
69
  make_unsafe_uniq(_Args&&... __args)
70
70
  {
71
- return unique_ptr<_Tp, false>(new _Tp(std::forward<_Args>(__args)...));
71
+ return unique_ptr<_Tp, std::default_delete<_Tp>, false>(new _Tp(std::forward<_Args>(__args)...));
72
72
  }
73
73
 
74
74
  template<class _Tp>
75
- inline unique_ptr<_Tp[], true>
76
- make_array(size_t __n)
75
+ inline unique_ptr<_Tp[], std::default_delete<_Tp>, true>
76
+ make_uniq_array(size_t __n)
77
77
  {
78
- return unique_ptr<_Tp[], true>(new _Tp[__n]());
78
+ return unique_ptr<_Tp[], std::default_delete<_Tp>, true>(new _Tp[__n]());
79
79
  }
80
80
 
81
81
  template<class _Tp>
82
- inline unique_ptr<_Tp[], false>
83
- make_unsafe_array(size_t __n)
82
+ inline unique_ptr<_Tp[], std::default_delete<_Tp>, false>
83
+ make_unsafe_uniq_array(size_t __n)
84
84
  {
85
- return unique_ptr<_Tp[], false>(new _Tp[__n]());
85
+ return unique_ptr<_Tp[], std::default_delete<_Tp>, false>(new _Tp[__n]());
86
86
  }
87
87
 
88
88
  template<class _Tp, class... _Args>
@@ -49,10 +49,10 @@ public:
49
49
  }
50
50
 
51
51
  //! helper function to get the HTTP
52
- static optional_ptr<HTTPState> TryGetState(FileOpener *opener) {
52
+ static shared_ptr<HTTPState> TryGetState(FileOpener *opener) {
53
53
  auto client_context = FileOpener::TryGetClientContext(opener);
54
54
  if (client_context) {
55
- return client_context->client_data->http_state.get();
55
+ return client_context->client_data->http_state;
56
56
  }
57
57
  return nullptr;
58
58
  }
@@ -18,7 +18,7 @@ public:
18
18
  FileLockType lock_type = FileLockType::READ_LOCK, optional_ptr<FileOpener> opener = nullptr);
19
19
 
20
20
  FileSystem &fs;
21
- unsafe_array_ptr<data_t> data;
21
+ unsafe_unique_array<data_t> data;
22
22
  idx_t offset;
23
23
  idx_t read_data;
24
24
  unique_ptr<FileHandle> handle;
@@ -25,7 +25,7 @@ public:
25
25
 
26
26
  FileSystem &fs;
27
27
  string path;
28
- unsafe_array_ptr<data_t> data;
28
+ unsafe_unique_array<data_t> data;
29
29
  idx_t offset;
30
30
  idx_t total_written;
31
31
  unique_ptr<FileHandle> handle;
@@ -16,7 +16,7 @@ namespace duckdb {
16
16
  #define SERIALIZER_DEFAULT_SIZE 1024
17
17
 
18
18
  struct BinaryData {
19
- unsafe_array_ptr<data_t> data;
19
+ unsafe_unique_array<data_t> data;
20
20
  idx_t size;
21
21
  };
22
22
 
@@ -26,7 +26,7 @@ public:
26
26
  //! writing past the initial threshold
27
27
  DUCKDB_API explicit BufferedSerializer(idx_t maximum_size = SERIALIZER_DEFAULT_SIZE);
28
28
  //! Serializes to a provided (owned) data pointer
29
- BufferedSerializer(unsafe_array_ptr<data_t> data, idx_t size);
29
+ BufferedSerializer(unsafe_unique_array<data_t> data, idx_t size);
30
30
  BufferedSerializer(data_ptr_t data, idx_t size);
31
31
 
32
32
  idx_t maximum_size;
@@ -39,10 +39,10 @@ using duckdb::idx_t;
39
39
  using duckdb::data_t;
40
40
  using duckdb::data_ptr_t;
41
41
  using duckdb::unique_ptr;
42
- using duckdb::array_ptr;
43
- using duckdb::unsafe_array_ptr;
44
- using duckdb::make_array;
45
- using duckdb::make_unsafe_array;
42
+ using duckdb::unique_array;
43
+ using duckdb::unsafe_unique_array;
44
+ using duckdb::make_uniq_array;
45
+ using duckdb::make_unsafe_uniq_array;
46
46
  using duckdb::FastMemcpy;
47
47
  using duckdb::FastMemcmp;
48
48
 
@@ -78,9 +78,9 @@ inline int log2(T n) {
78
78
  struct PDQConstants {
79
79
  PDQConstants(idx_t entry_size, idx_t comp_offset, idx_t comp_size, data_ptr_t end)
80
80
  : entry_size(entry_size), comp_offset(comp_offset), comp_size(comp_size),
81
- tmp_buf_ptr(make_unsafe_array<data_t>(entry_size)), tmp_buf(tmp_buf_ptr.get()),
82
- iter_swap_buf_ptr(make_unsafe_array<data_t>(entry_size)), iter_swap_buf(iter_swap_buf_ptr.get()),
83
- swap_offsets_buf_ptr(make_unsafe_array<data_t>(entry_size)),
81
+ tmp_buf_ptr(make_unsafe_uniq_array<data_t>(entry_size)), tmp_buf(tmp_buf_ptr.get()),
82
+ iter_swap_buf_ptr(make_unsafe_uniq_array<data_t>(entry_size)), iter_swap_buf(iter_swap_buf_ptr.get()),
83
+ swap_offsets_buf_ptr(make_unsafe_uniq_array<data_t>(entry_size)),
84
84
  swap_offsets_buf(swap_offsets_buf_ptr.get()), end(end) {
85
85
  }
86
86
 
@@ -88,13 +88,13 @@ struct PDQConstants {
88
88
  const idx_t comp_offset;
89
89
  const idx_t comp_size;
90
90
 
91
- unsafe_array_ptr<data_t> tmp_buf_ptr;
91
+ unsafe_unique_array<data_t> tmp_buf_ptr;
92
92
  const data_ptr_t tmp_buf;
93
93
 
94
- unsafe_array_ptr<data_t> iter_swap_buf_ptr;
94
+ unsafe_unique_array<data_t> iter_swap_buf_ptr;
95
95
  const data_ptr_t iter_swap_buf;
96
96
 
97
- unsafe_array_ptr<data_t> swap_offsets_buf_ptr;
97
+ unsafe_unique_array<data_t> swap_offsets_buf_ptr;
98
98
  const data_ptr_t swap_offsets_buf;
99
99
 
100
100
  const data_ptr_t end;
@@ -163,6 +163,8 @@ public:
163
163
  //! Convert a string to lowercase
164
164
  DUCKDB_API static string Lower(const string &str);
165
165
 
166
+ DUCKDB_API static bool IsLower(const string &str);
167
+
166
168
  //! Case insensitive hash
167
169
  DUCKDB_API static uint64_t CIHash(const string &str);
168
170
 
@@ -125,7 +125,7 @@ public:
125
125
  DUCKDB_API void Flatten();
126
126
 
127
127
  // FIXME: this is DUCKDB_API, might need conversion back to regular unique ptr?
128
- DUCKDB_API unsafe_array_ptr<UnifiedVectorFormat> ToUnifiedFormat();
128
+ DUCKDB_API unsafe_unique_array<UnifiedVectorFormat> ToUnifiedFormat();
129
129
 
130
130
  DUCKDB_API void Slice(const SelectionVector &sel_vector, idx_t count);
131
131
 
@@ -18,7 +18,7 @@ class VectorBuffer;
18
18
  struct SelectionData {
19
19
  DUCKDB_API explicit SelectionData(idx_t count);
20
20
 
21
- unsafe_array_ptr<sel_t> owned_data;
21
+ unsafe_unique_array<sel_t> owned_data;
22
22
  };
23
23
 
24
24
  struct SelectionVector {
@@ -24,7 +24,7 @@ struct TemplatedValidityData {
24
24
  public:
25
25
  inline explicit TemplatedValidityData(idx_t count) {
26
26
  auto entry_count = EntryCount(count);
27
- owned_data = make_unsafe_array<V>(entry_count);
27
+ owned_data = make_unsafe_uniq_array<V>(entry_count);
28
28
  for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
29
29
  owned_data[entry_idx] = MAX_ENTRY;
30
30
  }
@@ -32,13 +32,13 @@ public:
32
32
  inline TemplatedValidityData(const V *validity_mask, idx_t count) {
33
33
  D_ASSERT(validity_mask);
34
34
  auto entry_count = EntryCount(count);
35
- owned_data = make_unsafe_array<V>(entry_count);
35
+ owned_data = make_unsafe_uniq_array<V>(entry_count);
36
36
  for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
37
37
  owned_data[entry_idx] = validity_mask[entry_idx];
38
38
  }
39
39
  }
40
40
 
41
- unsafe_array_ptr<V> owned_data;
41
+ unsafe_unique_array<V> owned_data;
42
42
 
43
43
  public:
44
44
  static inline idx_t EntryCount(idx_t count) {