duckdb 0.8.2-dev4711.0 → 0.8.2-dev5002.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 (98) hide show
  1. package/binding.gyp +0 -1
  2. package/binding.gyp.in +0 -1
  3. package/package.json +1 -1
  4. package/src/connection.cpp +10 -23
  5. package/src/data_chunk.cpp +1 -3
  6. package/src/database.cpp +4 -9
  7. package/src/duckdb/extension/icu/icu-datepart.cpp +12 -8
  8. package/src/duckdb/extension/json/json_functions/json_transform.cpp +8 -6
  9. package/src/duckdb/extension/json/json_functions.cpp +4 -6
  10. package/src/duckdb/src/common/enum_util.cpp +10 -5
  11. package/src/duckdb/src/common/operator/cast_operators.cpp +18 -0
  12. package/src/duckdb/src/common/radix_partitioning.cpp +1 -1
  13. package/src/duckdb/src/common/row_operations/row_matcher.cpp +375 -0
  14. package/src/duckdb/src/common/types/data_chunk.cpp +48 -11
  15. package/src/duckdb/src/common/types/row/tuple_data_allocator.cpp +3 -3
  16. package/src/duckdb/src/common/types/row/tuple_data_collection.cpp +28 -17
  17. package/src/duckdb/src/common/types/row/tuple_data_scatter_gather.cpp +44 -43
  18. package/src/duckdb/src/common/types/vector.cpp +0 -1
  19. package/src/duckdb/src/common/types.cpp +1 -1
  20. package/src/duckdb/src/common/vector_operations/vector_hash.cpp +1 -0
  21. package/src/duckdb/src/core_functions/function_list.cpp +1 -1
  22. package/src/duckdb/src/core_functions/scalar/date/date_part.cpp +86 -50
  23. package/src/duckdb/src/core_functions/scalar/generic/hash.cpp +3 -0
  24. package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +5 -1
  25. package/src/duckdb/src/core_functions/scalar/list/list_sort.cpp +10 -1
  26. package/src/duckdb/src/core_functions/scalar/map/map_concat.cpp +0 -2
  27. package/src/duckdb/src/core_functions/scalar/string/repeat.cpp +8 -5
  28. package/src/duckdb/src/execution/aggregate_hashtable.cpp +5 -4
  29. package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +13 -0
  30. package/src/duckdb/src/execution/join_hashtable.cpp +71 -59
  31. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_inner.cpp +20 -27
  32. package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp +21 -9
  33. package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +7 -7
  34. package/src/duckdb/src/execution/operator/csv_scanner/csv_reader_options.cpp +1 -1
  35. package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +9 -4
  36. package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +0 -2
  37. package/src/duckdb/src/execution/reservoir_sample.cpp +3 -9
  38. package/src/duckdb/src/function/cast/time_casts.cpp +12 -0
  39. package/src/duckdb/src/function/cast/vector_cast_helpers.cpp +8 -2
  40. package/src/duckdb/src/function/function_binder.cpp +10 -9
  41. package/src/duckdb/src/function/pragma/pragma_queries.cpp +3 -0
  42. package/src/duckdb/src/function/scalar/string/like.cpp +0 -3
  43. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  44. package/src/duckdb/src/include/duckdb/common/enums/date_part_specifier.hpp +11 -3
  45. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +5 -0
  46. package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +27 -0
  47. package/src/duckdb/src/include/duckdb/common/operator/comparison_operators.hpp +38 -2
  48. package/src/duckdb/src/include/duckdb/common/row_operations/row_matcher.hpp +63 -0
  49. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_collection.hpp +6 -2
  50. package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_states.hpp +2 -2
  51. package/src/duckdb/src/include/duckdb/common/types/validity_mask.hpp +4 -1
  52. package/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +4 -4
  53. package/src/duckdb/src/include/duckdb/core_functions/scalar/blob_functions.hpp +4 -4
  54. package/src/duckdb/src/include/duckdb/core_functions/scalar/date_functions.hpp +5 -5
  55. package/src/duckdb/src/include/duckdb/core_functions/scalar/enum_functions.hpp +7 -7
  56. package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +12 -12
  57. package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +12 -12
  58. package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +3 -3
  59. package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +33 -33
  60. package/src/duckdb/src/include/duckdb/core_functions/scalar/operators_functions.hpp +2 -2
  61. package/src/duckdb/src/include/duckdb/core_functions/scalar/random_functions.hpp +3 -3
  62. package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +13 -13
  63. package/src/duckdb/src/include/duckdb/core_functions/scalar/struct_functions.hpp +2 -2
  64. package/src/duckdb/src/include/duckdb/core_functions/scalar/union_functions.hpp +2 -2
  65. package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +4 -0
  66. package/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +14 -8
  67. package/src/duckdb/src/include/duckdb/main/relation.hpp +4 -0
  68. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -0
  69. package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +1 -2
  70. package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +1 -1
  71. package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +1 -1
  75. package/src/duckdb/src/main/config.cpp +1 -1
  76. package/src/duckdb/src/main/relation.cpp +10 -0
  77. package/src/duckdb/src/optimizer/rule/date_part_simplification.cpp +0 -3
  78. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +28 -6
  79. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +3 -0
  80. package/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +12 -4
  81. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +14 -6
  82. package/src/duckdb/src/planner/operator/logical_create_table.cpp +3 -3
  83. package/src/duckdb/src/planner/operator/logical_delete.cpp +3 -2
  84. package/src/duckdb/src/planner/operator/logical_insert.cpp +3 -2
  85. package/src/duckdb/src/planner/operator/logical_update.cpp +3 -2
  86. package/src/duckdb/src/storage/compression/validity_uncompressed.cpp +2 -3
  87. package/src/duckdb/src/storage/data_table.cpp +18 -8
  88. package/src/duckdb/src/storage/local_storage.cpp +2 -3
  89. package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +64 -80
  90. package/src/duckdb/src/storage/storage_manager.cpp +6 -2
  91. package/src/duckdb/src/storage/table/row_group.cpp +6 -0
  92. package/src/duckdb/src/storage/table/row_group_collection.cpp +4 -3
  93. package/src/duckdb/src/storage/table/struct_column_data.cpp +2 -0
  94. package/src/duckdb/src/transaction/duck_transaction.cpp +1 -0
  95. package/src/duckdb/ub_src_common_row_operations.cpp +1 -1
  96. package/src/statement.cpp +2 -4
  97. package/test/database_fail.test.ts +6 -0
  98. package/src/duckdb/src/common/row_operations/row_match.cpp +0 -359
@@ -748,6 +748,9 @@ void DataTable::Append(DataChunk &chunk, TableAppendState &state) {
748
748
  }
749
749
 
750
750
  void DataTable::ScanTableSegment(idx_t row_start, idx_t count, const std::function<void(DataChunk &chunk)> &function) {
751
+ if (count == 0) {
752
+ return;
753
+ }
751
754
  idx_t end = row_start + count;
752
755
 
753
756
  vector<column_t> column_ids;
@@ -817,26 +820,24 @@ void DataTable::CommitAppend(transaction_t commit_id, idx_t row_start, idx_t cou
817
820
  info->cardinality += count;
818
821
  }
819
822
 
820
- void DataTable::RevertAppendInternal(idx_t start_row, idx_t count) {
821
- if (count == 0) {
822
- // nothing to revert!
823
- return;
824
- }
823
+ void DataTable::RevertAppendInternal(idx_t start_row) {
825
824
  // adjust the cardinality
826
825
  info->cardinality = start_row;
827
826
  D_ASSERT(is_root);
828
827
  // revert appends made to row_groups
829
- row_groups->RevertAppendInternal(start_row, count);
828
+ row_groups->RevertAppendInternal(start_row);
830
829
  }
831
830
 
832
831
  void DataTable::RevertAppend(idx_t start_row, idx_t count) {
833
832
  lock_guard<mutex> lock(append_lock);
834
833
 
834
+ // revert any appends to indexes
835
835
  if (!info->indexes.Empty()) {
836
836
  idx_t current_row_base = start_row;
837
837
  row_t row_data[STANDARD_VECTOR_SIZE];
838
838
  Vector row_identifiers(LogicalType::ROW_TYPE, data_ptr_cast(row_data));
839
- ScanTableSegment(start_row, count, [&](DataChunk &chunk) {
839
+ idx_t scan_count = MinValue<idx_t>(count, row_groups->GetTotalRows() - start_row);
840
+ ScanTableSegment(start_row, scan_count, [&](DataChunk &chunk) {
840
841
  for (idx_t i = 0; i < chunk.size(); i++) {
841
842
  row_data[i] = current_row_base + i;
842
843
  }
@@ -847,7 +848,16 @@ void DataTable::RevertAppend(idx_t start_row, idx_t count) {
847
848
  current_row_base += chunk.size();
848
849
  });
849
850
  }
850
- RevertAppendInternal(start_row, count);
851
+
852
+ // we need to vacuum the indexes to remove any buffers that are now empty
853
+ // due to reverting the appends
854
+ info->indexes.Scan([&](Index &index) {
855
+ index.Vacuum();
856
+ return false;
857
+ });
858
+
859
+ // revert the data table append
860
+ RevertAppendInternal(start_row);
851
861
  }
852
862
 
853
863
  //===--------------------------------------------------------------------===//
@@ -178,7 +178,7 @@ void LocalTableStorage::AppendToIndexes(DuckTransaction &transaction, TableAppen
178
178
  return true;
179
179
  });
180
180
  if (append_to_table) {
181
- table.RevertAppendInternal(append_state.row_start, append_count);
181
+ table.RevertAppendInternal(append_state.row_start);
182
182
  }
183
183
 
184
184
  // we need to vacuum the indexes to remove any buffers that are now empty
@@ -353,7 +353,6 @@ void LocalStorage::Append(LocalAppendState &state, DataChunk &chunk) {
353
353
 
354
354
  //! Append the chunk to the local storage
355
355
  auto new_row_group = storage->row_groups->Append(chunk, state.append_state);
356
-
357
356
  //! Check if we should pre-emptively flush blocks to disk
358
357
  if (new_row_group) {
359
358
  storage->WriteNewRowGroup();
@@ -432,6 +431,7 @@ void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage) {
432
431
 
433
432
  TableAppendState append_state;
434
433
  table.AppendLock(append_state);
434
+ transaction.PushAppend(table, append_state.row_start, append_count);
435
435
  if ((append_state.row_start == 0 || storage.row_groups->GetTotalRows() >= MERGE_THRESHOLD) &&
436
436
  storage.deleted_rows == 0) {
437
437
  // table is currently empty OR we are bulk appending: move over the storage directly
@@ -453,7 +453,6 @@ void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage) {
453
453
  // append to the indexes and append to the base table
454
454
  storage.AppendToIndexes(transaction, append_state, append_count, true);
455
455
  }
456
- transaction.PushAppend(table, append_state.row_start, append_count);
457
456
 
458
457
  // possibly vacuum any excess index data
459
458
  table.info->indexes.Scan([&](Index &index) {
@@ -314,16 +314,12 @@ unique_ptr<LogicalOperator> LogicalCreateIndex::Deserialize(Deserializer &deseri
314
314
 
315
315
  void LogicalCreateTable::Serialize(Serializer &serializer) const {
316
316
  LogicalOperator::Serialize(serializer);
317
- serializer.WriteProperty(200, "catalog", schema.ParentCatalog().GetName());
318
- serializer.WriteProperty(201, "schema", schema.name);
319
- serializer.WriteProperty(202, "info", info->base);
317
+ serializer.WriteProperty(200, "info", info->base);
320
318
  }
321
319
 
322
320
  unique_ptr<LogicalOperator> LogicalCreateTable::Deserialize(Deserializer &deserializer) {
323
- auto catalog = deserializer.ReadProperty<string>(200, "catalog");
324
- auto schema = deserializer.ReadProperty<string>(201, "schema");
325
- auto info = deserializer.ReadProperty<unique_ptr<CreateInfo>>(202, "info");
326
- auto result = duckdb::unique_ptr<LogicalCreateTable>(new LogicalCreateTable(deserializer.Get<ClientContext &>(), catalog, schema, std::move(info)));
321
+ auto info = deserializer.ReadProperty<unique_ptr<CreateInfo>>(200, "info");
322
+ auto result = duckdb::unique_ptr<LogicalCreateTable>(new LogicalCreateTable(deserializer.Get<ClientContext &>(), std::move(info)));
327
323
  return std::move(result);
328
324
  }
329
325
 
@@ -338,22 +334,18 @@ unique_ptr<LogicalOperator> LogicalCrossProduct::Deserialize(Deserializer &deser
338
334
 
339
335
  void LogicalDelete::Serialize(Serializer &serializer) const {
340
336
  LogicalOperator::Serialize(serializer);
341
- serializer.WriteProperty(200, "catalog", table.ParentCatalog().GetName());
342
- serializer.WriteProperty(201, "schema", table.ParentSchema().name);
343
- serializer.WriteProperty(202, "table", table.name);
344
- serializer.WriteProperty(203, "table_index", table_index);
345
- serializer.WriteProperty(204, "return_chunk", return_chunk);
346
- serializer.WriteProperty(205, "expressions", expressions);
337
+ serializer.WriteProperty(200, "table_info", table.GetInfo());
338
+ serializer.WriteProperty(201, "table_index", table_index);
339
+ serializer.WriteProperty(202, "return_chunk", return_chunk);
340
+ serializer.WriteProperty(203, "expressions", expressions);
347
341
  }
348
342
 
349
343
  unique_ptr<LogicalOperator> LogicalDelete::Deserialize(Deserializer &deserializer) {
350
- auto catalog = deserializer.ReadProperty<string>(200, "catalog");
351
- auto schema = deserializer.ReadProperty<string>(201, "schema");
352
- auto table = deserializer.ReadProperty<string>(202, "table");
353
- auto result = duckdb::unique_ptr<LogicalDelete>(new LogicalDelete(deserializer.Get<ClientContext &>(), catalog, schema, table));
354
- deserializer.ReadProperty(203, "table_index", result->table_index);
355
- deserializer.ReadProperty(204, "return_chunk", result->return_chunk);
356
- deserializer.ReadProperty(205, "expressions", result->expressions);
344
+ auto table_info = deserializer.ReadProperty<unique_ptr<CreateInfo>>(200, "table_info");
345
+ auto result = duckdb::unique_ptr<LogicalDelete>(new LogicalDelete(deserializer.Get<ClientContext &>(), table_info));
346
+ deserializer.ReadProperty(201, "table_index", result->table_index);
347
+ deserializer.ReadProperty(202, "return_chunk", result->return_chunk);
348
+ deserializer.ReadProperty(203, "expressions", result->expressions);
357
349
  return std::move(result);
358
350
  }
359
351
 
@@ -456,50 +448,46 @@ unique_ptr<LogicalOperator> LogicalFilter::Deserialize(Deserializer &deserialize
456
448
 
457
449
  void LogicalInsert::Serialize(Serializer &serializer) const {
458
450
  LogicalOperator::Serialize(serializer);
459
- serializer.WriteProperty(200, "catalog", table.ParentCatalog().GetName());
460
- serializer.WriteProperty(201, "schema", table.ParentSchema().name);
461
- serializer.WriteProperty(202, "table", table.name);
462
- serializer.WriteProperty(203, "insert_values", insert_values);
463
- serializer.WriteProperty(204, "column_index_map", column_index_map);
464
- serializer.WriteProperty(205, "expected_types", expected_types);
465
- serializer.WriteProperty(206, "table_index", table_index);
466
- serializer.WriteProperty(207, "return_chunk", return_chunk);
467
- serializer.WriteProperty(208, "bound_defaults", bound_defaults);
468
- serializer.WriteProperty(209, "action_type", action_type);
469
- serializer.WriteProperty(210, "expected_set_types", expected_set_types);
470
- serializer.WriteProperty(211, "on_conflict_filter", on_conflict_filter);
471
- serializer.WritePropertyWithDefault(212, "on_conflict_condition", on_conflict_condition, unique_ptr<Expression>());
472
- serializer.WritePropertyWithDefault(213, "do_update_condition", do_update_condition, unique_ptr<Expression>());
473
- serializer.WriteProperty(214, "set_columns", set_columns);
474
- serializer.WriteProperty(215, "set_types", set_types);
475
- serializer.WriteProperty(216, "excluded_table_index", excluded_table_index);
476
- serializer.WriteProperty(217, "columns_to_fetch", columns_to_fetch);
477
- serializer.WriteProperty(218, "source_columns", source_columns);
478
- serializer.WriteProperty(219, "expressions", expressions);
451
+ serializer.WriteProperty(200, "table_info", table.GetInfo());
452
+ serializer.WriteProperty(201, "insert_values", insert_values);
453
+ serializer.WriteProperty(202, "column_index_map", column_index_map);
454
+ serializer.WriteProperty(203, "expected_types", expected_types);
455
+ serializer.WriteProperty(204, "table_index", table_index);
456
+ serializer.WriteProperty(205, "return_chunk", return_chunk);
457
+ serializer.WriteProperty(206, "bound_defaults", bound_defaults);
458
+ serializer.WriteProperty(207, "action_type", action_type);
459
+ serializer.WriteProperty(208, "expected_set_types", expected_set_types);
460
+ serializer.WriteProperty(209, "on_conflict_filter", on_conflict_filter);
461
+ serializer.WritePropertyWithDefault(210, "on_conflict_condition", on_conflict_condition, unique_ptr<Expression>());
462
+ serializer.WritePropertyWithDefault(211, "do_update_condition", do_update_condition, unique_ptr<Expression>());
463
+ serializer.WriteProperty(212, "set_columns", set_columns);
464
+ serializer.WriteProperty(213, "set_types", set_types);
465
+ serializer.WriteProperty(214, "excluded_table_index", excluded_table_index);
466
+ serializer.WriteProperty(215, "columns_to_fetch", columns_to_fetch);
467
+ serializer.WriteProperty(216, "source_columns", source_columns);
468
+ serializer.WriteProperty(217, "expressions", expressions);
479
469
  }
480
470
 
481
471
  unique_ptr<LogicalOperator> LogicalInsert::Deserialize(Deserializer &deserializer) {
482
- auto catalog = deserializer.ReadProperty<string>(200, "catalog");
483
- auto schema = deserializer.ReadProperty<string>(201, "schema");
484
- auto table = deserializer.ReadProperty<string>(202, "table");
485
- auto result = duckdb::unique_ptr<LogicalInsert>(new LogicalInsert(deserializer.Get<ClientContext &>(), catalog, schema, table));
486
- deserializer.ReadProperty(203, "insert_values", result->insert_values);
487
- deserializer.ReadProperty(204, "column_index_map", result->column_index_map);
488
- deserializer.ReadProperty(205, "expected_types", result->expected_types);
489
- deserializer.ReadProperty(206, "table_index", result->table_index);
490
- deserializer.ReadProperty(207, "return_chunk", result->return_chunk);
491
- deserializer.ReadProperty(208, "bound_defaults", result->bound_defaults);
492
- deserializer.ReadProperty(209, "action_type", result->action_type);
493
- deserializer.ReadProperty(210, "expected_set_types", result->expected_set_types);
494
- deserializer.ReadProperty(211, "on_conflict_filter", result->on_conflict_filter);
495
- deserializer.ReadPropertyWithDefault(212, "on_conflict_condition", result->on_conflict_condition, unique_ptr<Expression>());
496
- deserializer.ReadPropertyWithDefault(213, "do_update_condition", result->do_update_condition, unique_ptr<Expression>());
497
- deserializer.ReadProperty(214, "set_columns", result->set_columns);
498
- deserializer.ReadProperty(215, "set_types", result->set_types);
499
- deserializer.ReadProperty(216, "excluded_table_index", result->excluded_table_index);
500
- deserializer.ReadProperty(217, "columns_to_fetch", result->columns_to_fetch);
501
- deserializer.ReadProperty(218, "source_columns", result->source_columns);
502
- deserializer.ReadProperty(219, "expressions", result->expressions);
472
+ auto table_info = deserializer.ReadProperty<unique_ptr<CreateInfo>>(200, "table_info");
473
+ auto result = duckdb::unique_ptr<LogicalInsert>(new LogicalInsert(deserializer.Get<ClientContext &>(), std::move(table_info)));
474
+ deserializer.ReadProperty(201, "insert_values", result->insert_values);
475
+ deserializer.ReadProperty(202, "column_index_map", result->column_index_map);
476
+ deserializer.ReadProperty(203, "expected_types", result->expected_types);
477
+ deserializer.ReadProperty(204, "table_index", result->table_index);
478
+ deserializer.ReadProperty(205, "return_chunk", result->return_chunk);
479
+ deserializer.ReadProperty(206, "bound_defaults", result->bound_defaults);
480
+ deserializer.ReadProperty(207, "action_type", result->action_type);
481
+ deserializer.ReadProperty(208, "expected_set_types", result->expected_set_types);
482
+ deserializer.ReadProperty(209, "on_conflict_filter", result->on_conflict_filter);
483
+ deserializer.ReadPropertyWithDefault(210, "on_conflict_condition", result->on_conflict_condition, unique_ptr<Expression>());
484
+ deserializer.ReadPropertyWithDefault(211, "do_update_condition", result->do_update_condition, unique_ptr<Expression>());
485
+ deserializer.ReadProperty(212, "set_columns", result->set_columns);
486
+ deserializer.ReadProperty(213, "set_types", result->set_types);
487
+ deserializer.ReadProperty(214, "excluded_table_index", result->excluded_table_index);
488
+ deserializer.ReadProperty(215, "columns_to_fetch", result->columns_to_fetch);
489
+ deserializer.ReadProperty(216, "source_columns", result->source_columns);
490
+ deserializer.ReadProperty(217, "expressions", result->expressions);
503
491
  return std::move(result);
504
492
  }
505
493
 
@@ -723,28 +711,24 @@ unique_ptr<LogicalOperator> LogicalUnnest::Deserialize(Deserializer &deserialize
723
711
 
724
712
  void LogicalUpdate::Serialize(Serializer &serializer) const {
725
713
  LogicalOperator::Serialize(serializer);
726
- serializer.WriteProperty(200, "catalog", table.ParentCatalog().GetName());
727
- serializer.WriteProperty(201, "schema", table.ParentSchema().name);
728
- serializer.WriteProperty(202, "table", table.name);
729
- serializer.WriteProperty(203, "table_index", table_index);
730
- serializer.WriteProperty(204, "return_chunk", return_chunk);
731
- serializer.WriteProperty(205, "expressions", expressions);
732
- serializer.WriteProperty(206, "columns", columns);
733
- serializer.WriteProperty(207, "bound_defaults", bound_defaults);
734
- serializer.WriteProperty(208, "update_is_del_and_insert", update_is_del_and_insert);
714
+ serializer.WriteProperty(200, "table_info", table.GetInfo());
715
+ serializer.WriteProperty(201, "table_index", table_index);
716
+ serializer.WriteProperty(202, "return_chunk", return_chunk);
717
+ serializer.WriteProperty(203, "expressions", expressions);
718
+ serializer.WriteProperty(204, "columns", columns);
719
+ serializer.WriteProperty(205, "bound_defaults", bound_defaults);
720
+ serializer.WriteProperty(206, "update_is_del_and_insert", update_is_del_and_insert);
735
721
  }
736
722
 
737
723
  unique_ptr<LogicalOperator> LogicalUpdate::Deserialize(Deserializer &deserializer) {
738
- auto catalog = deserializer.ReadProperty<string>(200, "catalog");
739
- auto schema = deserializer.ReadProperty<string>(201, "schema");
740
- auto table = deserializer.ReadProperty<string>(202, "table");
741
- auto result = duckdb::unique_ptr<LogicalUpdate>(new LogicalUpdate(deserializer.Get<ClientContext &>(), catalog, schema, table));
742
- deserializer.ReadProperty(203, "table_index", result->table_index);
743
- deserializer.ReadProperty(204, "return_chunk", result->return_chunk);
744
- deserializer.ReadProperty(205, "expressions", result->expressions);
745
- deserializer.ReadProperty(206, "columns", result->columns);
746
- deserializer.ReadProperty(207, "bound_defaults", result->bound_defaults);
747
- deserializer.ReadProperty(208, "update_is_del_and_insert", result->update_is_del_and_insert);
724
+ auto table_info = deserializer.ReadProperty<unique_ptr<CreateInfo>>(200, "table_info");
725
+ auto result = duckdb::unique_ptr<LogicalUpdate>(new LogicalUpdate(deserializer.Get<ClientContext &>(), table_info));
726
+ deserializer.ReadProperty(201, "table_index", result->table_index);
727
+ deserializer.ReadProperty(202, "return_chunk", result->return_chunk);
728
+ deserializer.ReadProperty(203, "expressions", result->expressions);
729
+ deserializer.ReadProperty(204, "columns", result->columns);
730
+ deserializer.ReadProperty(205, "bound_defaults", result->bound_defaults);
731
+ deserializer.ReadProperty(206, "update_is_del_and_insert", result->update_is_del_and_insert);
748
732
  return std::move(result);
749
733
  }
750
734
 
@@ -235,8 +235,12 @@ void SingleFileStorageManager::CreateCheckpoint(bool delete_wal, bool force_chec
235
235
  auto &config = DBConfig::Get(db);
236
236
  if (wal->GetWALSize() > 0 || config.options.force_checkpoint || force_checkpoint) {
237
237
  // we only need to checkpoint if there is anything in the WAL
238
- SingleFileCheckpointWriter checkpointer(db, *block_manager);
239
- checkpointer.CreateCheckpoint();
238
+ try {
239
+ SingleFileCheckpointWriter checkpointer(db, *block_manager);
240
+ checkpointer.CreateCheckpoint();
241
+ } catch (std::exception &ex) {
242
+ throw FatalException("Failed to create checkpoint because of error: %s", ex.what());
243
+ }
240
244
  }
241
245
  if (delete_wal) {
242
246
  wal->Delete();
@@ -782,6 +782,12 @@ RowGroupPointer RowGroup::Checkpoint(RowGroupWriter &writer, TableStatistics &gl
782
782
  vector<CompressionType> compression_types;
783
783
  compression_types.reserve(columns.size());
784
784
  for (idx_t column_idx = 0; column_idx < GetColumnCount(); column_idx++) {
785
+ auto &column = GetColumn(column_idx);
786
+ if (column.count != this->count) {
787
+ throw InternalException("Corrupted in-memory column - column with index %llu has misaligned count (row "
788
+ "group has %llu rows, column has %llu)",
789
+ column_idx, this->count.load(), column.count);
790
+ }
785
791
  compression_types.push_back(writer.GetColumnCompressionType(column_idx));
786
792
  }
787
793
  auto result = WriteToDisk(writer.GetPartialBlockManager(), compression_types);
@@ -33,6 +33,7 @@ void RowGroupSegmentTree::Initialize(PersistentTableData &data) {
33
33
 
34
34
  unique_ptr<RowGroup> RowGroupSegmentTree::LoadSegment() {
35
35
  if (current_row_group >= max_row_group) {
36
+ reader.reset();
36
37
  finished_loading = true;
37
38
  return nullptr;
38
39
  }
@@ -426,9 +427,9 @@ void RowGroupCollection::CommitAppend(transaction_t commit_id, idx_t row_start,
426
427
  }
427
428
  }
428
429
 
429
- void RowGroupCollection::RevertAppendInternal(idx_t start_row, idx_t count) {
430
- if (total_rows != start_row + count) {
431
- throw InternalException("Interleaved appends: this should no longer happen");
430
+ void RowGroupCollection::RevertAppendInternal(idx_t start_row) {
431
+ if (total_rows <= start_row) {
432
+ return;
432
433
  }
433
434
  total_rows = start_row;
434
435
 
@@ -128,6 +128,7 @@ void StructColumnData::Append(BaseStatistics &stats, ColumnAppendState &state, V
128
128
  sub_columns[i]->Append(StructStats::GetChildStats(stats, i), state.child_appends[i + 1], *child_entries[i],
129
129
  count);
130
130
  }
131
+ this->count += count;
131
132
  }
132
133
 
133
134
  void StructColumnData::RevertAppend(row_t start_row) {
@@ -135,6 +136,7 @@ void StructColumnData::RevertAppend(row_t start_row) {
135
136
  for (auto &sub_column : sub_columns) {
136
137
  sub_column->RevertAppend(start_row);
137
138
  }
139
+ this->count = start_row - this->start;
138
140
  }
139
141
 
140
142
  idx_t StructColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &result) {
@@ -142,6 +142,7 @@ string DuckTransaction::Commit(AttachedDatabase &db, transaction_t commit_id, bo
142
142
  }
143
143
  return string();
144
144
  } catch (std::exception &ex) {
145
+ undo_buffer.RevertCommit(iterator_state, this->transaction_id);
145
146
  return ex.what();
146
147
  }
147
148
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  #include "src/common/row_operations/row_gather.cpp"
6
6
 
7
- #include "src/common/row_operations/row_match.cpp"
7
+ #include "src/common/row_operations/row_matcher.cpp"
8
8
 
9
9
  #include "src/common/row_operations/row_external.cpp"
10
10
 
package/src/statement.cpp CHANGED
@@ -93,11 +93,9 @@ Statement::Statement(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Statemen
93
93
  int length = info.Length();
94
94
 
95
95
  if (length <= 0 || !Connection::HasInstance(info[0])) {
96
- Napi::TypeError::New(env, "Connection object expected").ThrowAsJavaScriptException();
97
- return;
96
+ throw Napi::TypeError::New(env, "Connection object expected");
98
97
  } else if (length <= 1 || !info[1].IsString()) {
99
- Napi::TypeError::New(env, "SQL query expected").ThrowAsJavaScriptException();
100
- return;
98
+ throw Napi::TypeError::New(env, "SQL query expected");
101
99
  }
102
100
 
103
101
  connection_ref = Napi::ObjectWrap<Connection>::Unwrap(info[0].As<Napi::Object>());
@@ -2,6 +2,7 @@ import * as sqlite3 from '..';
2
2
  import * as assert from 'assert';
3
3
  import {DuckDbError, RowData} from "..";
4
4
  import {Worker} from 'worker_threads';
5
+ import {expect} from 'chai';
5
6
 
6
7
  describe('error handling', function() {
7
8
  var db: sqlite3.Database;
@@ -163,4 +164,9 @@ describe('error handling', function() {
163
164
  await run_worker(); // first should always succeed
164
165
  await run_worker(); // second fails without thread safety
165
166
  })
167
+
168
+ it("shouldn't crash on an exception", () => {
169
+ expect(() => new sqlite3.Database(':memory:', {file_search_path: '/'})).to.throw('Could not set option "file_search_path" as a global option');
170
+ });
166
171
  });
172
+