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.
- package/package.json +1 -1
- package/src/database.cpp +0 -1
- package/src/duckdb/extension/json/json_functions/read_json.cpp +3 -3
- package/src/duckdb/extension/json/json_scan.cpp +16 -12
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +4 -4
- package/src/duckdb/src/common/compressed_file_system.cpp +2 -2
- package/src/duckdb/src/common/file_system.cpp +2 -2
- package/src/duckdb/src/common/row_operations/row_gather.cpp +2 -2
- package/src/duckdb/src/common/serializer/binary_deserializer.cpp +1 -1
- package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +1 -1
- package/src/duckdb/src/common/serializer/buffered_file_writer.cpp +1 -1
- package/src/duckdb/src/common/serializer/buffered_serializer.cpp +3 -3
- package/src/duckdb/src/common/serializer.cpp +1 -1
- package/src/duckdb/src/common/sort/radix_sort.cpp +5 -5
- package/src/duckdb/src/common/string_util.cpp +6 -2
- package/src/duckdb/src/common/types/bit.cpp +2 -2
- package/src/duckdb/src/common/types/blob.cpp +2 -2
- package/src/duckdb/src/common/types/data_chunk.cpp +2 -2
- package/src/duckdb/src/common/types/date.cpp +1 -1
- package/src/duckdb/src/common/types/decimal.cpp +2 -2
- package/src/duckdb/src/common/types/selection_vector.cpp +1 -1
- package/src/duckdb/src/common/types/time.cpp +1 -1
- package/src/duckdb/src/common/types/vector.cpp +7 -7
- package/src/duckdb/src/common/windows_util.cpp +2 -2
- package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +1 -1
- package/src/duckdb/src/core_functions/scalar/string/printf.cpp +1 -1
- package/src/duckdb/src/execution/aggregate_hashtable.cpp +1 -1
- package/src/duckdb/src/execution/join_hashtable.cpp +3 -3
- package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +2 -2
- package/src/duckdb/src/execution/operator/join/outer_join_marker.cpp +1 -1
- package/src/duckdb/src/execution/operator/join/perfect_hash_join_executor.cpp +1 -1
- package/src/duckdb/src/execution/operator/join/physical_range_join.cpp +1 -1
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
- package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +91 -30
- package/src/duckdb/src/execution/operator/projection/physical_pivot.cpp +1 -1
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +1 -1
- package/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +2 -2
- package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +3 -3
- package/src/duckdb/src/execution/window_segment_tree.cpp +1 -1
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +1 -1
- package/src/duckdb/src/function/scalar/strftime_format.cpp +1 -1
- package/src/duckdb/src/function/scalar/string/concat.cpp +1 -1
- package/src/duckdb/src/function/scalar/string/like.cpp +2 -2
- package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +5 -5
- package/src/duckdb/src/function/table/copy_csv.cpp +1 -1
- package/src/duckdb/src/function/table/table_scan.cpp +7 -3
- package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -6
- package/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp +2 -2
- package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -9
- package/src/duckdb/src/include/duckdb/common/http_state.hpp +2 -2
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_writer.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_serializer.hpp +2 -2
- package/src/duckdb/src/include/duckdb/common/sort/duckdb_pdqsort.hpp +10 -10
- package/src/duckdb/src/include/duckdb/common/string_util.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/types/validity_mask.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/types/vector_buffer.hpp +4 -4
- package/src/duckdb/src/include/duckdb/common/unique_ptr.hpp +8 -8
- package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/parallel_csv_reader.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +2 -3
- package/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +1 -1
- package/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +1 -1
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/join_order/join_relation.hpp +3 -3
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +4 -0
- package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/append_state.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +5 -5
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -2
- package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +1 -1
- package/src/duckdb/src/main/client_context.cpp +4 -4
- package/src/duckdb/src/main/extension/extension_install.cpp +2 -2
- package/src/duckdb/src/optimizer/join_order/join_relation_set.cpp +5 -5
- package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +7 -1
- package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -1
- package/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp +1 -1
- package/src/duckdb/src/storage/compression/string_uncompressed.cpp +2 -2
- package/src/duckdb/src/storage/data_table.cpp +75 -44
- package/src/duckdb/src/storage/local_storage.cpp +1 -1
- package/src/duckdb/src/storage/statistics/list_stats.cpp +1 -1
- package/src/duckdb/src/storage/statistics/struct_stats.cpp +1 -1
- package/src/duckdb/src/storage/table/row_group.cpp +11 -11
- package/src/duckdb/src/storage/table/scan_state.cpp +1 -1
- 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>
|
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
|
181
|
-
|
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
|
-
|
222
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
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
|
-
|
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
|
-
|
318
|
-
|
319
|
-
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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(
|
44
|
-
state_buffer1(
|
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
|
-
|
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(
|
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 =
|
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<
|
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
|
-
|
223
|
-
result->
|
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-
|
2
|
+
#define DUCKDB_VERSION "0.7.2-dev3763"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
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
|
97
|
-
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
|
-
|
22
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
21
|
+
unsafe_unique_array<data_t> data;
|
22
22
|
idx_t offset;
|
23
23
|
idx_t read_data;
|
24
24
|
unique_ptr<FileHandle> handle;
|
@@ -16,7 +16,7 @@ namespace duckdb {
|
|
16
16
|
#define SERIALIZER_DEFAULT_SIZE 1024
|
17
17
|
|
18
18
|
struct BinaryData {
|
19
|
-
|
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(
|
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::
|
43
|
-
using duckdb::
|
44
|
-
using duckdb::
|
45
|
-
using duckdb::
|
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(
|
82
|
-
iter_swap_buf_ptr(
|
83
|
-
swap_offsets_buf_ptr(
|
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
|
-
|
91
|
+
unsafe_unique_array<data_t> tmp_buf_ptr;
|
92
92
|
const data_ptr_t tmp_buf;
|
93
93
|
|
94
|
-
|
94
|
+
unsafe_unique_array<data_t> iter_swap_buf_ptr;
|
95
95
|
const data_ptr_t iter_swap_buf;
|
96
96
|
|
97
|
-
|
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
|
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
|
|
@@ -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 =
|
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 =
|
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
|
-
|
41
|
+
unsafe_unique_array<V> owned_data;
|
42
42
|
|
43
43
|
public:
|
44
44
|
static inline idx_t EntryCount(idx_t count) {
|