duckdb 0.5.2-dev325.0 → 0.5.2-dev339.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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.5.2-dev325.0",
4
+ "version": "0.5.2-dev339.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -128298,7 +128298,6 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string
128298
128298
  bool any_failed = original->Run(*this, query, [&](const string &q, unique_ptr<SQLStatement> s) {
128299
128299
  return RunStatementInternal(lock, q, move(s), false, false);
128300
128300
  });
128301
-
128302
128301
  // Execute the verifiers
128303
128302
  for (auto &verifier : statement_verifiers) {
128304
128303
  bool failed = verifier->Run(*this, query, [&](const string &q, unique_ptr<SQLStatement> s) {
@@ -128318,11 +128317,7 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string
128318
128317
  }
128319
128318
  } else {
128320
128319
  if (db->IsInvalidated()) {
128321
- for (auto &verifier : statement_verifiers) {
128322
- if (verifier->materialized_result->HasError()) {
128323
- return verifier->materialized_result->GetErrorObject();
128324
- }
128325
- }
128320
+ return original->materialized_result->GetErrorObject();
128326
128321
  }
128327
128322
  }
128328
128323
 
@@ -195078,6 +195073,8 @@ class ColumnData {
195078
195073
 
195079
195074
  public:
195080
195075
  ColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type, ColumnData *parent);
195076
+ ColumnData(ColumnData &other, idx_t start, ColumnData *parent);
195077
+
195081
195078
  virtual ~ColumnData();
195082
195079
 
195083
195080
  //! Table info for the column
@@ -195159,8 +195156,10 @@ public:
195159
195156
 
195160
195157
  static shared_ptr<ColumnData> CreateColumn(DataTableInfo &info, idx_t column_index, idx_t start_row,
195161
195158
  const LogicalType &type, ColumnData *parent = nullptr);
195159
+ static shared_ptr<ColumnData> CreateColumn(ColumnData &other, idx_t start_row, ColumnData *parent = nullptr);
195162
195160
  static unique_ptr<ColumnData> CreateColumnUnique(DataTableInfo &info, idx_t column_index, idx_t start_row,
195163
195161
  const LogicalType &type, ColumnData *parent = nullptr);
195162
+ static unique_ptr<ColumnData> CreateColumnUnique(ColumnData &other, idx_t start_row, ColumnData *parent = nullptr);
195164
195163
 
195165
195164
  protected:
195166
195165
  //! Append a transient segment
@@ -198462,6 +198461,7 @@ namespace duckdb {
198462
198461
  class ValidityColumnData : public ColumnData {
198463
198462
  public:
198464
198463
  ValidityColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, ColumnData *parent);
198464
+ ValidityColumnData(ColumnData &original, idx_t start_row, ColumnData *parent = nullptr);
198465
198465
 
198466
198466
  public:
198467
198467
  bool CheckZonemap(ColumnScanState &state, TableFilter &filter) override;
@@ -198477,6 +198477,7 @@ class StandardColumnData : public ColumnData {
198477
198477
  public:
198478
198478
  StandardColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type,
198479
198479
  ColumnData *parent = nullptr);
198480
+ StandardColumnData(ColumnData &original, idx_t start_row, ColumnData *parent = nullptr);
198480
198481
 
198481
198482
  //! The validity column data
198482
198483
  ValidityColumnData validity;
@@ -198543,7 +198544,6 @@ DataTable::DataTable(DatabaseInstance &db, const string &schema, const string &t
198543
198544
  if (stats.Empty()) {
198544
198545
  D_ASSERT(row_groups->GetTotalRows() == 0);
198545
198546
 
198546
- row_groups->InitializeEmpty();
198547
198547
  stats.InitializeEmpty(types);
198548
198548
  }
198549
198549
  row_groups->Verify();
@@ -198999,12 +198999,19 @@ void DataTable::Append(TableCatalogEntry &table, ClientContext &context, DataChu
198999
198999
  transaction.storage.Append(this, chunk);
199000
199000
  }
199001
199001
 
199002
- void DataTable::InitializeAppend(Transaction &transaction, TableAppendState &state, idx_t append_count) {
199003
- // obtain the append lock for this table
199002
+ void DataTable::AppendLock(TableAppendState &state) {
199004
199003
  state.append_lock = unique_lock<mutex>(append_lock);
199005
199004
  if (!is_root) {
199006
199005
  throw TransactionException("Transaction conflict: adding entries to a table that has been altered!");
199007
199006
  }
199007
+ state.row_start = row_groups->GetTotalRows();
199008
+ }
199009
+
199010
+ void DataTable::InitializeAppend(Transaction &transaction, TableAppendState &state, idx_t append_count) {
199011
+ // obtain the append lock for this table
199012
+ if (!state.append_lock) {
199013
+ throw InternalException("DataTable::AppendLock should be called before DataTable::InitializeAppend");
199014
+ }
199008
199015
  row_groups->InitializeAppend(transaction, state, append_count);
199009
199016
  }
199010
199017
 
@@ -199056,6 +199063,15 @@ void DataTable::ScanTableSegment(idx_t row_start, idx_t count, const std::functi
199056
199063
  }
199057
199064
  }
199058
199065
 
199066
+ void DataTable::MergeStorage(RowGroupCollection &data, TableIndexList &indexes, TableStatistics &other_stats) {
199067
+ row_groups->MergeStorage(data);
199068
+ stats.MergeStats(other_stats);
199069
+ row_groups->Verify();
199070
+ if (!indexes.Empty()) {
199071
+ throw InternalException("FIXME: merge indexes");
199072
+ }
199073
+ }
199074
+
199059
199075
  void DataTable::WriteToLog(WriteAheadLog &log, idx_t row_start, idx_t count) {
199060
199076
  if (log.skip_writing) {
199061
199077
  return;
@@ -199567,7 +199583,6 @@ LocalTableStorage::LocalTableStorage(DataTable &table)
199567
199583
  : table(table), allocator(Allocator::Get(table.db)), deleted_rows(0) {
199568
199584
  auto types = table.GetTypes();
199569
199585
  row_groups = make_shared<RowGroupCollection>(table.info, types, MAX_ROW_ID, 0);
199570
- row_groups->InitializeEmpty();
199571
199586
  stats.InitializeEmpty(types);
199572
199587
  table.info->indexes.Scan([&](Index &index) {
199573
199588
  D_ASSERT(index.type == IndexType::ART);
@@ -199758,44 +199773,51 @@ bool LocalStorage::ScanTableStorage(DataTable &table, LocalTableStorage &storage
199758
199773
  }
199759
199774
 
199760
199775
  void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage) {
199776
+ auto storage_entry = move(table_storage[&table]);
199777
+ table_storage[&table].reset();
199778
+
199761
199779
  if (storage.row_groups->GetTotalRows() <= storage.deleted_rows) {
199762
199780
  return;
199763
199781
  }
199764
199782
  idx_t append_count = storage.row_groups->GetTotalRows() - storage.deleted_rows;
199765
- TableAppendState append_state;
199766
- table.InitializeAppend(transaction, append_state, append_count);
199767
199783
 
199768
- bool constraint_violated = false;
199769
- ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
199770
- // append this chunk to the indexes of the table
199771
- if (!table.AppendToIndexes(chunk, append_state.current_row)) {
199772
- constraint_violated = true;
199773
- return false;
199774
- }
199775
- // append to base table
199776
- table.Append(transaction, chunk, append_state);
199777
- return true;
199778
- });
199779
- if (constraint_violated) {
199780
- // need to revert the append
199781
- row_t current_row = append_state.row_start;
199782
- // remove the data from the indexes, if there are any indexes
199784
+ TableAppendState append_state;
199785
+ table.AppendLock(append_state);
199786
+ if (append_state.row_start == 0 && storage.table.info->indexes.Empty() && storage.deleted_rows == 0) {
199787
+ // table is currently empty: move over the storage directly
199788
+ table.MergeStorage(*storage.row_groups, storage.indexes, storage.stats);
199789
+ } else {
199790
+ bool constraint_violated = false;
199791
+ table.InitializeAppend(transaction, append_state, append_count);
199783
199792
  ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
199784
199793
  // append this chunk to the indexes of the table
199785
- table.RemoveFromIndexes(append_state, chunk, current_row);
199786
-
199787
- current_row += chunk.size();
199788
- if (current_row >= append_state.current_row) {
199789
- // finished deleting all rows from the index: abort now
199794
+ if (!table.AppendToIndexes(chunk, append_state.current_row)) {
199795
+ constraint_violated = true;
199790
199796
  return false;
199791
199797
  }
199798
+ // append to base table
199799
+ table.Append(transaction, chunk, append_state);
199792
199800
  return true;
199793
199801
  });
199794
- table.RevertAppendInternal(append_state.row_start, append_count);
199795
- table_storage[&table].reset();
199796
- throw ConstraintException("PRIMARY KEY or UNIQUE constraint violated: duplicated key");
199802
+ if (constraint_violated) {
199803
+ // need to revert the append
199804
+ row_t current_row = append_state.row_start;
199805
+ // remove the data from the indexes, if there are any indexes
199806
+ ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
199807
+ // append this chunk to the indexes of the table
199808
+ table.RemoveFromIndexes(append_state, chunk, current_row);
199809
+
199810
+ current_row += chunk.size();
199811
+ if (current_row >= append_state.current_row) {
199812
+ // finished deleting all rows from the index: abort now
199813
+ return false;
199814
+ }
199815
+ return true;
199816
+ });
199817
+ table.RevertAppendInternal(append_state.row_start, append_count);
199818
+ throw ConstraintException("PRIMARY KEY or UNIQUE constraint violated: duplicated key");
199819
+ }
199797
199820
  }
199798
- table_storage[&table].reset();
199799
199821
  transaction.PushAppend(&table, append_state.row_start, append_count);
199800
199822
  }
199801
199823
 
@@ -202071,6 +202093,7 @@ class ListColumnData : public ColumnData {
202071
202093
  public:
202072
202094
  ListColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type,
202073
202095
  ColumnData *parent = nullptr);
202096
+ ListColumnData(ColumnData &original, idx_t start_row, ColumnData *parent = nullptr);
202074
202097
 
202075
202098
  //! The child-column of the list
202076
202099
  unique_ptr<ColumnData> child_column;
@@ -202279,6 +202302,7 @@ class StructColumnData : public ColumnData {
202279
202302
  public:
202280
202303
  StructColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type,
202281
202304
  ColumnData *parent = nullptr);
202305
+ StructColumnData(ColumnData &original, idx_t start_row, ColumnData *parent = nullptr);
202282
202306
 
202283
202307
  //! The sub-columns of the struct
202284
202308
  vector<unique_ptr<ColumnData>> sub_columns;
@@ -202441,6 +202465,17 @@ ColumnData::ColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row,
202441
202465
  : info(info), column_index(column_index), start(start_row), type(move(type)), parent(parent) {
202442
202466
  }
202443
202467
 
202468
+ ColumnData::ColumnData(ColumnData &other, idx_t start, ColumnData *parent)
202469
+ : info(other.info), column_index(other.column_index), start(start), type(move(other.type)), parent(parent),
202470
+ updates(move(other.updates)) {
202471
+ idx_t offset = 0;
202472
+ for (auto segment = other.data.GetRootSegment(); segment; segment = segment->next.get()) {
202473
+ auto &other = (ColumnSegment &)*segment;
202474
+ this->data.AppendSegment(ColumnSegment::CreateSegment(other, start + offset));
202475
+ offset += segment->count;
202476
+ }
202477
+ }
202478
+
202444
202479
  ColumnData::~ColumnData() {
202445
202480
  }
202446
202481
 
@@ -202460,8 +202495,15 @@ const LogicalType &ColumnData::RootType() const {
202460
202495
  }
202461
202496
 
202462
202497
  idx_t ColumnData::GetMaxEntry() {
202498
+ auto first_segment = data.GetRootSegment();
202463
202499
  auto last_segment = data.GetLastSegment();
202464
- return last_segment ? last_segment->start + last_segment->count : start;
202500
+ if (!first_segment) {
202501
+ D_ASSERT(!last_segment);
202502
+ return 0;
202503
+ } else {
202504
+ D_ASSERT(last_segment->start >= first_segment->start);
202505
+ return last_segment->start + last_segment->count - first_segment->start;
202506
+ }
202465
202507
  }
202466
202508
 
202467
202509
  void ColumnData::InitializeScan(ColumnScanState &state) {
@@ -202875,10 +202917,6 @@ void ColumnData::Verify(RowGroup &parent) {
202875
202917
  }
202876
202918
  root = root->next.get();
202877
202919
  }
202878
- } else {
202879
- if (type.InternalType() != PhysicalType::STRUCT) {
202880
- D_ASSERT(parent.count == 0);
202881
- }
202882
202920
  }
202883
202921
  #endif
202884
202922
  }
@@ -202896,16 +202934,36 @@ static RET CreateColumnInternal(DataTableInfo &info, idx_t column_index, idx_t s
202896
202934
  return OP::template Create<StandardColumnData>(info, column_index, start_row, type, parent);
202897
202935
  }
202898
202936
 
202937
+ template <class RET, class OP>
202938
+ static RET CreateColumnInternal(ColumnData &other, idx_t start_row, ColumnData *parent) {
202939
+ if (other.type.InternalType() == PhysicalType::STRUCT) {
202940
+ return OP::template Create<StructColumnData>(other, start_row, parent);
202941
+ } else if (other.type.InternalType() == PhysicalType::LIST) {
202942
+ return OP::template Create<ListColumnData>(other, start_row, parent);
202943
+ } else if (other.type.id() == LogicalTypeId::VALIDITY) {
202944
+ return OP::template Create<ValidityColumnData>(other, start_row, parent);
202945
+ }
202946
+ return OP::template Create<StandardColumnData>(other, start_row, parent);
202947
+ }
202948
+
202899
202949
  shared_ptr<ColumnData> ColumnData::CreateColumn(DataTableInfo &info, idx_t column_index, idx_t start_row,
202900
202950
  const LogicalType &type, ColumnData *parent) {
202901
202951
  return CreateColumnInternal<shared_ptr<ColumnData>, SharedConstructor>(info, column_index, start_row, type, parent);
202902
202952
  }
202903
202953
 
202954
+ shared_ptr<ColumnData> ColumnData::CreateColumn(ColumnData &other, idx_t start_row, ColumnData *parent) {
202955
+ return CreateColumnInternal<shared_ptr<ColumnData>, SharedConstructor>(other, start_row, parent);
202956
+ }
202957
+
202904
202958
  unique_ptr<ColumnData> ColumnData::CreateColumnUnique(DataTableInfo &info, idx_t column_index, idx_t start_row,
202905
202959
  const LogicalType &type, ColumnData *parent) {
202906
202960
  return CreateColumnInternal<unique_ptr<ColumnData>, UniqueConstructor>(info, column_index, start_row, type, parent);
202907
202961
  }
202908
202962
 
202963
+ unique_ptr<ColumnData> ColumnData::CreateColumnUnique(ColumnData &other, idx_t start_row, ColumnData *parent) {
202964
+ return CreateColumnInternal<unique_ptr<ColumnData>, UniqueConstructor>(other, start_row, parent);
202965
+ }
202966
+
202909
202967
  } // namespace duckdb
202910
202968
 
202911
202969
 
@@ -203196,6 +203254,10 @@ unique_ptr<ColumnSegment> ColumnSegment::CreateTransientSegment(DatabaseInstance
203196
203254
  INVALID_BLOCK, 0);
203197
203255
  }
203198
203256
 
203257
+ unique_ptr<ColumnSegment> ColumnSegment::CreateSegment(ColumnSegment &other, idx_t start) {
203258
+ return make_unique<ColumnSegment>(other, start);
203259
+ }
203260
+
203199
203261
  ColumnSegment::ColumnSegment(DatabaseInstance &db, LogicalType type_p, ColumnSegmentType segment_type, idx_t start,
203200
203262
  idx_t count, CompressionFunction *function_p, unique_ptr<BaseStatistics> statistics,
203201
203263
  block_id_t block_id_p, idx_t offset_p)
@@ -203222,6 +203284,12 @@ ColumnSegment::ColumnSegment(DatabaseInstance &db, LogicalType type_p, ColumnSeg
203222
203284
  }
203223
203285
  }
203224
203286
 
203287
+ ColumnSegment::ColumnSegment(ColumnSegment &other, idx_t start)
203288
+ : SegmentBase(start, other.count), db(other.db), type(move(other.type)), type_size(other.type_size),
203289
+ segment_type(other.segment_type), function(other.function), stats(move(other.stats)), block(move(other.block)),
203290
+ block_id(other.block_id), offset(other.offset), segment_state(move(other.segment_state)) {
203291
+ }
203292
+
203225
203293
  ColumnSegment::~ColumnSegment() {
203226
203294
  }
203227
203295
 
@@ -203625,6 +203693,12 @@ ListColumnData::ListColumnData(DataTableInfo &info, idx_t column_index, idx_t st
203625
203693
  child_column = ColumnData::CreateColumnUnique(info, 1, start_row, child_type, this);
203626
203694
  }
203627
203695
 
203696
+ ListColumnData::ListColumnData(ColumnData &original, idx_t start_row, ColumnData *parent)
203697
+ : ColumnData(original, start_row, parent), validity(((ListColumnData &)original).validity, start_row, this) {
203698
+ auto &list_data = (ListColumnData &)original;
203699
+ child_column = ColumnData::CreateColumnUnique(*list_data.child_column, start_row, this);
203700
+ }
203701
+
203628
203702
  bool ListColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filter) {
203629
203703
  // table filters are not supported yet for list columns
203630
203704
  return false;
@@ -203674,7 +203748,7 @@ void ListColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_
203674
203748
  D_ASSERT(child_offset <= child_column->GetMaxEntry());
203675
203749
  ColumnScanState child_state;
203676
203750
  if (child_offset < child_column->GetMaxEntry()) {
203677
- child_column->InitializeScanWithOffset(child_state, child_offset);
203751
+ child_column->InitializeScanWithOffset(child_state, start + child_offset);
203678
203752
  }
203679
203753
  state.child_states.push_back(move(child_state));
203680
203754
  }
@@ -203719,7 +203793,8 @@ idx_t ListColumnData::ScanCount(ColumnScanState &state, Vector &result, idx_t co
203719
203793
  if (child_scan_count > 0) {
203720
203794
  auto &child_entry = ListVector::GetEntry(result);
203721
203795
  D_ASSERT(child_entry.GetType().InternalType() == PhysicalType::STRUCT ||
203722
- state.child_states[1].row_index + child_scan_count <= child_column->GetMaxEntry());
203796
+ state.child_states[1].row_index + child_scan_count <=
203797
+ child_column->start + child_column->GetMaxEntry());
203723
203798
  child_column->ScanCount(state.child_states[1], child_entry, child_scan_count);
203724
203799
  }
203725
203800
 
@@ -203908,9 +203983,9 @@ void ListColumnData::FetchRow(TransactionData transaction, ColumnFetchState &sta
203908
203983
  auto &child_type = ListType::GetChildType(result.GetType());
203909
203984
  Vector child_scan(child_type, child_scan_count);
203910
203985
  // seek the scan towards the specified position and read [length] entries
203911
- child_column->InitializeScanWithOffset(*child_state, original_offset);
203986
+ child_column->InitializeScanWithOffset(*child_state, start + original_offset);
203912
203987
  D_ASSERT(child_type.InternalType() == PhysicalType::STRUCT ||
203913
- child_state->row_index + child_scan_count <= child_column->GetMaxEntry());
203988
+ child_state->row_index + child_scan_count - this->start <= child_column->GetMaxEntry());
203914
203989
  child_column->ScanCount(*child_state, child_scan, child_scan_count);
203915
203990
 
203916
203991
  ListVector::Append(result, child_scan, child_scan_count);
@@ -204040,6 +204115,28 @@ RowGroup::RowGroup(DatabaseInstance &db, DataTableInfo &table_info, const vector
204040
204115
  Verify();
204041
204116
  }
204042
204117
 
204118
+ RowGroup::RowGroup(RowGroup &row_group, idx_t start)
204119
+ : SegmentBase(start, row_group.count), db(row_group.db), table_info(row_group.table_info),
204120
+ version_info(move(row_group.version_info)), stats(move(row_group.stats)) {
204121
+ for (auto &column : row_group.columns) {
204122
+ this->columns.push_back(ColumnData::CreateColumn(*column, start));
204123
+ }
204124
+ if (version_info) {
204125
+ version_info->SetStart(start);
204126
+ }
204127
+ Verify();
204128
+ }
204129
+
204130
+ void VersionNode::SetStart(idx_t start) {
204131
+ idx_t current_start = start;
204132
+ for (idx_t i = 0; i < RowGroup::ROW_GROUP_VECTOR_COUNT; i++) {
204133
+ if (info[i]) {
204134
+ info[i]->start = current_start;
204135
+ }
204136
+ current_start += STANDARD_VECTOR_SIZE;
204137
+ }
204138
+ }
204139
+
204043
204140
  RowGroup::~RowGroup() {
204044
204141
  }
204045
204142
 
@@ -204933,10 +205030,6 @@ void RowGroupCollection::Initialize(PersistentTableData &data) {
204933
205030
  }
204934
205031
  }
204935
205032
 
204936
- void RowGroupCollection::InitializeEmpty() {
204937
- AppendRowGroup(row_start);
204938
- }
204939
-
204940
205033
  void RowGroupCollection::AppendRowGroup(idx_t start_row) {
204941
205034
  D_ASSERT(start_row >= row_start);
204942
205035
  auto new_row_group = make_unique<RowGroup>(info->db, *info, start_row, 0);
@@ -204946,7 +205039,10 @@ void RowGroupCollection::AppendRowGroup(idx_t start_row) {
204946
205039
 
204947
205040
  void RowGroupCollection::Verify() {
204948
205041
  #ifdef DEBUG
204949
- D_ASSERT(row_groups->GetRootSegment() != nullptr);
205042
+ for (auto segment = row_groups->GetRootSegment(); segment; segment = segment->next.get()) {
205043
+ auto &row_group = (RowGroup &)*segment;
205044
+ row_group.Verify();
205045
+ }
204950
205046
  #endif
204951
205047
  }
204952
205048
 
@@ -204956,6 +205052,7 @@ void RowGroupCollection::Verify() {
204956
205052
  void RowGroupCollection::InitializeScan(CollectionScanState &state, const vector<column_t> &column_ids,
204957
205053
  TableFilterSet *table_filters) {
204958
205054
  auto row_group = (RowGroup *)row_groups->GetRootSegment();
205055
+ D_ASSERT(row_group);
204959
205056
  state.max_row = row_start + total_rows;
204960
205057
  while (row_group && !row_group->InitializeScan(state.row_group_state)) {
204961
205058
  row_group = (RowGroup *)row_group->next.get();
@@ -204969,6 +205066,7 @@ void RowGroupCollection::InitializeCreateIndexScan(CreateIndexScanState &state)
204969
205066
  void RowGroupCollection::InitializeScanWithOffset(CollectionScanState &state, const vector<column_t> &column_ids,
204970
205067
  idx_t start_row, idx_t end_row) {
204971
205068
  auto row_group = (RowGroup *)row_groups->GetSegment(start_row);
205069
+ D_ASSERT(row_group);
204972
205070
  state.max_row = end_row;
204973
205071
  idx_t start_vector = (start_row - row_group->start) / STANDARD_VECTOR_SIZE;
204974
205072
  if (!row_group->InitializeScanWithOffset(state.row_group_state, start_vector)) {
@@ -205046,6 +205144,10 @@ void RowGroupCollection::Fetch(TransactionData transaction, DataChunk &result, c
205046
205144
  //===--------------------------------------------------------------------===//
205047
205145
  // Append
205048
205146
  //===--------------------------------------------------------------------===//
205147
+ bool RowGroupCollection::IsEmpty() const {
205148
+ return row_groups->GetRootSegment() == nullptr;
205149
+ }
205150
+
205049
205151
  void RowGroupCollection::InitializeAppend(TransactionData transaction, TableAppendState &state, idx_t append_count) {
205050
205152
  state.remaining_append_count = append_count;
205051
205153
  state.row_start = total_rows;
@@ -205053,6 +205155,10 @@ void RowGroupCollection::InitializeAppend(TransactionData transaction, TableAppe
205053
205155
 
205054
205156
  // start writing to the row_groups
205055
205157
  lock_guard<mutex> row_group_lock(row_groups->node_lock);
205158
+ if (IsEmpty()) {
205159
+ // empty row group collection: empty first row group
205160
+ AppendRowGroup(row_start);
205161
+ }
205056
205162
  auto last_row_group = (RowGroup *)row_groups->GetLastSegment();
205057
205163
  D_ASSERT(this->row_start + total_rows == last_row_group->start + last_row_group->count);
205058
205164
  last_row_group->InitializeAppend(transaction, state.row_group_append_state, state.remaining_append_count);
@@ -205117,6 +205223,7 @@ void RowGroupCollection::Append(TransactionData transaction, DataChunk &chunk, T
205117
205223
 
205118
205224
  void RowGroupCollection::CommitAppend(transaction_t commit_id, idx_t row_start, idx_t count) {
205119
205225
  auto row_group = (RowGroup *)row_groups->GetSegment(row_start);
205226
+ D_ASSERT(row_group);
205120
205227
  idx_t current_row = row_start;
205121
205228
  idx_t remaining = count;
205122
205229
  while (true) {
@@ -205159,6 +205266,18 @@ void RowGroupCollection::RevertAppendInternal(idx_t start_row, idx_t count) {
205159
205266
  info.RevertAppend(start_row);
205160
205267
  }
205161
205268
 
205269
+ void RowGroupCollection::MergeStorage(RowGroupCollection &data) {
205270
+ D_ASSERT(data.types == types);
205271
+ auto index = row_start;
205272
+ for (auto segment = data.row_groups->GetRootSegment(); segment; segment = segment->next.get()) {
205273
+ auto &row_group = (RowGroup &)*segment;
205274
+ auto new_group = make_unique<RowGroup>(row_group, index);
205275
+ index += new_group->count;
205276
+ row_groups->AppendSegment(move(new_group));
205277
+ }
205278
+ total_rows += data.total_rows.load();
205279
+ }
205280
+
205162
205281
  //===--------------------------------------------------------------------===//
205163
205282
  // Delete
205164
205283
  //===--------------------------------------------------------------------===//
@@ -205417,6 +205536,9 @@ shared_ptr<RowGroupCollection> RowGroupCollection::AlterType(idx_t changed_idx,
205417
205536
  }
205418
205537
 
205419
205538
  void RowGroupCollection::VerifyNewConstraint(DataTable &parent, const BoundConstraint &constraint) {
205539
+ if (total_rows == 0) {
205540
+ return;
205541
+ }
205420
205542
  // scan the original table, check if there's any null value
205421
205543
  auto &not_null_constraint = (BoundNotNullConstraint &)constraint;
205422
205544
  vector<LogicalType> scan_types;
@@ -205651,6 +205773,10 @@ StandardColumnData::StandardColumnData(DataTableInfo &info, idx_t column_index,
205651
205773
  : ColumnData(info, column_index, start_row, move(type), parent), validity(info, 0, start_row, this) {
205652
205774
  }
205653
205775
 
205776
+ StandardColumnData::StandardColumnData(ColumnData &original, idx_t start_row, ColumnData *parent)
205777
+ : ColumnData(original, start_row, parent), validity(((StandardColumnData &)original).validity, start_row, this) {
205778
+ }
205779
+
205654
205780
  bool StandardColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filter) {
205655
205781
  if (!state.segment_checked) {
205656
205782
  if (!state.current) {
@@ -205873,6 +205999,14 @@ StructColumnData::StructColumnData(DataTableInfo &info, idx_t column_index, idx_
205873
205999
  }
205874
206000
  }
205875
206001
 
206002
+ StructColumnData::StructColumnData(ColumnData &original, idx_t start_row, ColumnData *parent)
206003
+ : ColumnData(original, start_row, parent), validity(((StructColumnData &)original).validity, start_row, this) {
206004
+ auto &struct_data = (StructColumnData &)original;
206005
+ for (auto &child_col : struct_data.sub_columns) {
206006
+ sub_columns.push_back(ColumnData::CreateColumnUnique(*child_col, start_row, this));
206007
+ }
206008
+ }
206009
+
205876
206010
  bool StructColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filter) {
205877
206011
  // table filters are not supported yet for struct columns
205878
206012
  return false;
@@ -206220,6 +206354,14 @@ void TableStatistics::InitializeAddConstraint(TableStatistics &parent) {
206220
206354
  }
206221
206355
  }
206222
206356
 
206357
+ void TableStatistics::MergeStats(TableStatistics &other) {
206358
+ auto l = GetLock();
206359
+ D_ASSERT(column_stats.size() == other.column_stats.size());
206360
+ for (idx_t i = 0; i < column_stats.size(); i++) {
206361
+ column_stats[i]->stats->Merge(*other.column_stats[i]->stats);
206362
+ }
206363
+ }
206364
+
206223
206365
  void TableStatistics::MergeStats(idx_t i, BaseStatistics &stats) {
206224
206366
  auto l = GetLock();
206225
206367
  MergeStats(*l, i, stats);
@@ -207543,6 +207685,10 @@ ValidityColumnData::ValidityColumnData(DataTableInfo &info, idx_t column_index,
207543
207685
  : ColumnData(info, column_index, start_row, LogicalType(LogicalTypeId::VALIDITY), parent) {
207544
207686
  }
207545
207687
 
207688
+ ValidityColumnData::ValidityColumnData(ColumnData &original, idx_t start_row, ColumnData *parent)
207689
+ : ColumnData(original, start_row, parent) {
207690
+ }
207691
+
207546
207692
  bool ValidityColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filter) {
207547
207693
  return true;
207548
207694
  }
package/src/duckdb.hpp CHANGED
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
13
  #define DUCKDB_AMALGAMATION_EXTENDED 1
14
- #define DUCKDB_SOURCE_ID "689b242d2"
15
- #define DUCKDB_VERSION "v0.5.2-dev325"
14
+ #define DUCKDB_SOURCE_ID "23ca324e8"
15
+ #define DUCKDB_VERSION "v0.5.2-dev339"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -17759,6 +17759,7 @@ public:
17759
17759
  RowGroup(DatabaseInstance &db, DataTableInfo &table_info, idx_t start, idx_t count);
17760
17760
  RowGroup(DatabaseInstance &db, DataTableInfo &table_info, const vector<LogicalType> &types,
17761
17761
  RowGroupPointer &pointer);
17762
+ RowGroup(RowGroup &row_group, idx_t start);
17762
17763
  ~RowGroup();
17763
17764
 
17764
17765
  private:
@@ -17872,6 +17873,8 @@ private:
17872
17873
 
17873
17874
  struct VersionNode {
17874
17875
  unique_ptr<ChunkInfo> info[RowGroup::ROW_GROUP_VECTOR_COUNT];
17876
+
17877
+ void SetStart(idx_t start);
17875
17878
  };
17876
17879
 
17877
17880
  } // namespace duckdb
@@ -17973,7 +17976,8 @@ public:
17973
17976
  Allocator &GetAllocator() const;
17974
17977
 
17975
17978
  void Initialize(PersistentTableData &data);
17976
- void InitializeEmpty();
17979
+
17980
+ bool IsEmpty() const;
17977
17981
 
17978
17982
  void AppendRowGroup(idx_t start_row);
17979
17983
  void Verify();
@@ -17995,6 +17999,8 @@ public:
17995
17999
  void CommitAppend(transaction_t commit_id, idx_t row_start, idx_t count);
17996
18000
  void RevertAppendInternal(idx_t start_row, idx_t count);
17997
18001
 
18002
+ void MergeStorage(RowGroupCollection &data);
18003
+
17998
18004
  void RemoveFromIndexes(TableIndexList &indexes, Vector &row_identifiers, idx_t count);
17999
18005
 
18000
18006
  idx_t Delete(TransactionData transaction, DataTable *table, row_t *ids, idx_t count);
@@ -20288,6 +20294,7 @@ public:
20288
20294
  void InitializeAlterType(TableStatistics &parent, idx_t changed_idx, const LogicalType &new_type);
20289
20295
  void InitializeAddConstraint(TableStatistics &parent);
20290
20296
 
20297
+ void MergeStats(TableStatistics &other);
20291
20298
  void MergeStats(idx_t i, BaseStatistics &stats);
20292
20299
  void MergeStats(TableStatisticsLock &lock, idx_t i, BaseStatistics &stats);
20293
20300
 
@@ -25872,6 +25879,7 @@ public:
25872
25879
  CompressionType compression_type,
25873
25880
  unique_ptr<BaseStatistics> statistics);
25874
25881
  static unique_ptr<ColumnSegment> CreateTransientSegment(DatabaseInstance &db, const LogicalType &type, idx_t start);
25882
+ static unique_ptr<ColumnSegment> CreateSegment(ColumnSegment &other, idx_t start);
25875
25883
 
25876
25884
  public:
25877
25885
  void InitializeScan(ColumnScanState &state);
@@ -25927,6 +25935,7 @@ public:
25927
25935
  ColumnSegment(DatabaseInstance &db, LogicalType type, ColumnSegmentType segment_type, idx_t start, idx_t count,
25928
25936
  CompressionFunction *function, unique_ptr<BaseStatistics> statistics, block_id_t block_id,
25929
25937
  idx_t offset);
25938
+ ColumnSegment(ColumnSegment &other, idx_t start);
25930
25939
 
25931
25940
  private:
25932
25941
  void Scan(ColumnScanState &state, idx_t scan_count, Vector &result);
@@ -26048,6 +26057,8 @@ public:
26048
26057
  void UpdateColumn(TableCatalogEntry &table, ClientContext &context, Vector &row_ids,
26049
26058
  const vector<column_t> &column_path, DataChunk &updates);
26050
26059
 
26060
+ //! Fetches an append lock
26061
+ void AppendLock(TableAppendState &state);
26051
26062
  //! Begin appending structs to this table, obtaining necessary locks, etc
26052
26063
  void InitializeAppend(Transaction &transaction, TableAppendState &state, idx_t append_count);
26053
26064
  //! Append a chunk to the table using the AppendState obtained from BeginAppend
@@ -26063,6 +26074,9 @@ public:
26063
26074
 
26064
26075
  void ScanTableSegment(idx_t start_row, idx_t count, const std::function<void(DataChunk &chunk)> &function);
26065
26076
 
26077
+ //! Merge a row group collection directly into this table - appending it to the end of the table without copying
26078
+ void MergeStorage(RowGroupCollection &data, TableIndexList &indexes, TableStatistics &stats);
26079
+
26066
26080
  //! Append a chunk with the row ids [row_start, ..., row_start + chunk.size()] to all indexes of the table, returns
26067
26081
  //! whether or not the append succeeded
26068
26082
  bool AppendToIndexes(DataChunk &chunk, row_t row_start);