duckdb 0.6.2-dev2301.0 → 0.6.2-dev2303.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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.6.2-dev2301.0",
5
+ "version": "0.6.2-dev2303.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.6.2-dev2301"
2
+ #define DUCKDB_VERSION "0.6.2-dev2303"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "979e2a710f"
5
+ #define DUCKDB_SOURCE_ID "f75b768239"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -171,7 +171,8 @@ public:
171
171
  const vector<column_t> &bound_columns, Expression &cast_expr);
172
172
 
173
173
  void MoveStorage(DataTable *old_dt, DataTable *new_dt);
174
- void FetchChunk(DataTable *table, Vector &row_ids, idx_t count, DataChunk &chunk);
174
+ void FetchChunk(DataTable *table, Vector &row_ids, idx_t count, const vector<column_t> &col_ids, DataChunk &chunk,
175
+ ColumnFetchState &fetch_state);
175
176
  TableIndexList &GetIndexes(DataTable *table);
176
177
 
177
178
  void VerifyNewConstraint(DataTable &parent, const BoundConstraint &constraint);
@@ -886,6 +886,32 @@ void DataTable::RemoveFromIndexes(Vector &row_identifiers, idx_t count) {
886
886
  row_groups->RemoveFromIndexes(info->indexes, row_identifiers, count);
887
887
  }
888
888
 
889
+ //===--------------------------------------------------------------------===//
890
+ // Delete
891
+ //===--------------------------------------------------------------------===//
892
+ static bool TableHasDeleteConstraints(TableCatalogEntry &table) {
893
+ auto &bound_constraints = table.GetBoundConstraints();
894
+ for (auto &constraint : bound_constraints) {
895
+ switch (constraint->type) {
896
+ case ConstraintType::NOT_NULL:
897
+ case ConstraintType::CHECK:
898
+ case ConstraintType::UNIQUE:
899
+ break;
900
+ case ConstraintType::FOREIGN_KEY: {
901
+ auto &bfk = *reinterpret_cast<BoundForeignKeyConstraint *>(constraint.get());
902
+ if (bfk.info.type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE ||
903
+ bfk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) {
904
+ return true;
905
+ }
906
+ break;
907
+ }
908
+ default:
909
+ throw NotImplementedException("Constraint type not implemented!");
910
+ }
911
+ }
912
+ return false;
913
+ }
914
+
889
915
  void DataTable::VerifyDeleteConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk) {
890
916
  auto &bound_constraints = table.GetBoundConstraints();
891
917
  for (auto &constraint : bound_constraints) {
@@ -908,9 +934,6 @@ void DataTable::VerifyDeleteConstraints(TableCatalogEntry &table, ClientContext
908
934
  }
909
935
  }
910
936
 
911
- //===--------------------------------------------------------------------===//
912
- // Delete
913
- //===--------------------------------------------------------------------===//
914
937
  idx_t DataTable::Delete(TableCatalogEntry &table, ClientContext &context, Vector &row_identifiers, idx_t count) {
915
938
  D_ASSERT(row_identifiers.GetType().InternalType() == ROW_TYPE);
916
939
  if (count == 0) {
@@ -919,36 +942,58 @@ idx_t DataTable::Delete(TableCatalogEntry &table, ClientContext &context, Vector
919
942
 
920
943
  auto &transaction = DuckTransaction::Get(context, db);
921
944
  auto &local_storage = LocalStorage::Get(transaction);
945
+ bool has_delete_constraints = TableHasDeleteConstraints(table);
922
946
 
923
947
  row_identifiers.Flatten(count);
924
948
  auto ids = FlatVector::GetData<row_t>(row_identifiers);
925
- auto first_id = ids[0];
926
949
 
927
- // verify any constraints on the delete rows
928
- // FIXME: we only need to fetch in case we have a foreign key constraint
929
- // and we only need to fetch columns that are part of this constraint
930
950
  DataChunk verify_chunk;
931
- if (first_id >= MAX_ROW_ID) {
932
- local_storage.FetchChunk(this, row_identifiers, count, verify_chunk);
933
- } else {
934
- ColumnFetchState fetch_state;
935
- vector<column_t> col_ids;
936
- vector<LogicalType> types;
951
+ vector<column_t> col_ids;
952
+ vector<LogicalType> types;
953
+ ColumnFetchState fetch_state;
954
+ if (has_delete_constraints) {
955
+ // initialize the chunk if there are any constraints to verify
937
956
  for (idx_t i = 0; i < column_definitions.size(); i++) {
938
957
  col_ids.push_back(column_definitions[i].StorageOid());
939
958
  types.emplace_back(column_definitions[i].Type());
940
959
  }
941
960
  verify_chunk.Initialize(Allocator::Get(context), types);
942
- Fetch(transaction, verify_chunk, col_ids, row_identifiers, count, fetch_state);
943
961
  }
944
- VerifyDeleteConstraints(table, context, verify_chunk);
945
-
946
- if (first_id >= MAX_ROW_ID) {
947
- // deletion is in transaction-local storage: push delete into local chunk collection
948
- return local_storage.Delete(this, row_identifiers, count);
949
- } else {
950
- return row_groups->Delete(transaction, this, ids, count);
962
+ idx_t pos = 0;
963
+ idx_t delete_count = 0;
964
+ while (pos < count) {
965
+ idx_t start = pos;
966
+ bool is_transaction_delete = ids[pos] >= MAX_ROW_ID;
967
+ // figure out which batch of rows to delete now
968
+ for (pos++; pos < count; pos++) {
969
+ bool row_is_transaction_delete = ids[pos] >= MAX_ROW_ID;
970
+ if (row_is_transaction_delete != is_transaction_delete) {
971
+ break;
972
+ }
973
+ }
974
+ idx_t current_offset = start;
975
+ idx_t current_count = pos - start;
976
+
977
+ Vector offset_ids(row_identifiers, current_offset, pos);
978
+ if (is_transaction_delete) {
979
+ // transaction-local delete
980
+ if (has_delete_constraints) {
981
+ // perform the constraint verification
982
+ local_storage.FetchChunk(this, offset_ids, current_count, col_ids, verify_chunk, fetch_state);
983
+ VerifyDeleteConstraints(table, context, verify_chunk);
984
+ }
985
+ delete_count += local_storage.Delete(this, offset_ids, current_count);
986
+ } else {
987
+ // regular table delete
988
+ if (has_delete_constraints) {
989
+ // perform the constraint verification
990
+ Fetch(transaction, verify_chunk, col_ids, offset_ids, current_count, fetch_state);
991
+ VerifyDeleteConstraints(table, context, verify_chunk);
992
+ }
993
+ delete_count += row_groups->Delete(transaction, this, ids + current_offset, current_count);
994
+ }
951
995
  }
996
+ return delete_count;
952
997
  }
953
998
 
954
999
  //===--------------------------------------------------------------------===//
@@ -596,20 +596,14 @@ void LocalStorage::ChangeType(DataTable *old_dt, DataTable *new_dt, idx_t change
596
596
  table_manager.InsertEntry(new_dt, std::move(new_storage));
597
597
  }
598
598
 
599
- void LocalStorage::FetchChunk(DataTable *table, Vector &row_ids, idx_t count, DataChunk &verify_chunk) {
599
+ void LocalStorage::FetchChunk(DataTable *table, Vector &row_ids, idx_t count, const vector<column_t> &col_ids,
600
+ DataChunk &chunk, ColumnFetchState &fetch_state) {
600
601
  auto storage = table_manager.GetStorage(table);
601
602
  if (!storage) {
602
603
  throw InternalException("LocalStorage::FetchChunk - local storage not found");
603
604
  }
604
605
 
605
- ColumnFetchState fetch_state;
606
- vector<column_t> col_ids;
607
- vector<LogicalType> types = storage->table->GetTypes();
608
- for (idx_t i = 0; i < types.size(); i++) {
609
- col_ids.push_back(i);
610
- }
611
- verify_chunk.Initialize(storage->allocator, types);
612
- storage->row_groups->Fetch(transaction, verify_chunk, col_ids, row_ids, count, fetch_state);
606
+ storage->row_groups->Fetch(transaction, chunk, col_ids, row_ids, count, fetch_state);
613
607
  }
614
608
 
615
609
  TableIndexList &LocalStorage::GetIndexes(DataTable *table) {
@@ -409,7 +409,7 @@ idx_t RowGroupCollection::Delete(TransactionData transaction, DataTable *table,
409
409
  idx_t pos = 0;
410
410
  do {
411
411
  idx_t start = pos;
412
- auto row_group = (RowGroup *)row_groups->GetSegment(ids[pos]);
412
+ auto row_group = (RowGroup *)row_groups->GetSegment(ids[start]);
413
413
  for (pos++; pos < count; pos++) {
414
414
  D_ASSERT(ids[pos] >= 0);
415
415
  // check if this id still belongs to this row group