duckdb 0.7.2-dev3710.0 → 0.7.2-dev3763.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/package.json +1 -1
  2. package/src/database.cpp +0 -1
  3. package/src/duckdb/extension/json/json_functions/read_json.cpp +3 -3
  4. package/src/duckdb/extension/json/json_scan.cpp +16 -12
  5. package/src/duckdb/src/common/arrow/arrow_converter.cpp +4 -4
  6. package/src/duckdb/src/common/compressed_file_system.cpp +2 -2
  7. package/src/duckdb/src/common/file_system.cpp +2 -2
  8. package/src/duckdb/src/common/row_operations/row_gather.cpp +2 -2
  9. package/src/duckdb/src/common/serializer/binary_deserializer.cpp +1 -1
  10. package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +1 -1
  11. package/src/duckdb/src/common/serializer/buffered_file_writer.cpp +1 -1
  12. package/src/duckdb/src/common/serializer/buffered_serializer.cpp +3 -3
  13. package/src/duckdb/src/common/serializer.cpp +1 -1
  14. package/src/duckdb/src/common/sort/radix_sort.cpp +5 -5
  15. package/src/duckdb/src/common/string_util.cpp +6 -2
  16. package/src/duckdb/src/common/types/bit.cpp +2 -2
  17. package/src/duckdb/src/common/types/blob.cpp +2 -2
  18. package/src/duckdb/src/common/types/data_chunk.cpp +2 -2
  19. package/src/duckdb/src/common/types/date.cpp +1 -1
  20. package/src/duckdb/src/common/types/decimal.cpp +2 -2
  21. package/src/duckdb/src/common/types/selection_vector.cpp +1 -1
  22. package/src/duckdb/src/common/types/time.cpp +1 -1
  23. package/src/duckdb/src/common/types/vector.cpp +7 -7
  24. package/src/duckdb/src/common/windows_util.cpp +2 -2
  25. package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +1 -1
  26. package/src/duckdb/src/core_functions/scalar/string/printf.cpp +1 -1
  27. package/src/duckdb/src/execution/aggregate_hashtable.cpp +1 -1
  28. package/src/duckdb/src/execution/join_hashtable.cpp +3 -3
  29. package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +2 -2
  30. package/src/duckdb/src/execution/operator/join/outer_join_marker.cpp +1 -1
  31. package/src/duckdb/src/execution/operator/join/perfect_hash_join_executor.cpp +1 -1
  32. package/src/duckdb/src/execution/operator/join/physical_range_join.cpp +1 -1
  33. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
  34. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +91 -30
  35. package/src/duckdb/src/execution/operator/projection/physical_pivot.cpp +1 -1
  36. package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +1 -1
  37. package/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +2 -2
  38. package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +3 -3
  39. package/src/duckdb/src/execution/window_segment_tree.cpp +1 -1
  40. package/src/duckdb/src/function/pragma/pragma_queries.cpp +1 -1
  41. package/src/duckdb/src/function/scalar/strftime_format.cpp +1 -1
  42. package/src/duckdb/src/function/scalar/string/concat.cpp +1 -1
  43. package/src/duckdb/src/function/scalar/string/like.cpp +2 -2
  44. package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +5 -5
  45. package/src/duckdb/src/function/table/copy_csv.cpp +1 -1
  46. package/src/duckdb/src/function/table/table_scan.cpp +7 -3
  47. package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -6
  48. package/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp +2 -2
  49. package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -9
  50. package/src/duckdb/src/include/duckdb/common/http_state.hpp +2 -2
  51. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +1 -1
  52. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_writer.hpp +1 -1
  53. package/src/duckdb/src/include/duckdb/common/serializer/buffered_serializer.hpp +2 -2
  54. package/src/duckdb/src/include/duckdb/common/sort/duckdb_pdqsort.hpp +10 -10
  55. package/src/duckdb/src/include/duckdb/common/string_util.hpp +2 -0
  56. package/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +1 -1
  57. package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
  58. package/src/duckdb/src/include/duckdb/common/types/validity_mask.hpp +3 -3
  59. package/src/duckdb/src/include/duckdb/common/types/vector_buffer.hpp +4 -4
  60. package/src/duckdb/src/include/duckdb/common/unique_ptr.hpp +8 -8
  61. package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +1 -1
  62. package/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +3 -3
  63. package/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp +1 -1
  64. package/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp +1 -1
  65. package/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp +1 -1
  66. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +2 -2
  67. package/src/duckdb/src/include/duckdb/execution/operator/persistent/parallel_csv_reader.hpp +2 -2
  68. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +2 -3
  69. package/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +2 -2
  70. package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +1 -1
  71. package/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/main/client_data.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/optimizer/join_order/join_relation.hpp +3 -3
  74. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +4 -0
  75. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +1 -1
  76. package/src/duckdb/src/include/duckdb/storage/table/append_state.hpp +1 -1
  77. package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +5 -5
  79. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -2
  80. package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +1 -1
  81. package/src/duckdb/src/main/client_context.cpp +4 -4
  82. package/src/duckdb/src/main/extension/extension_install.cpp +2 -2
  83. package/src/duckdb/src/optimizer/join_order/join_relation_set.cpp +5 -5
  84. package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +7 -1
  85. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -1
  86. package/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp +1 -1
  87. package/src/duckdb/src/storage/compression/string_uncompressed.cpp +2 -2
  88. package/src/duckdb/src/storage/data_table.cpp +75 -44
  89. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  90. package/src/duckdb/src/storage/statistics/list_stats.cpp +1 -1
  91. package/src/duckdb/src/storage/statistics/struct_stats.cpp +1 -1
  92. package/src/duckdb/src/storage/table/row_group.cpp +11 -11
  93. package/src/duckdb/src/storage/table/scan_state.cpp +1 -1
  94. package/src/duckdb/src/storage/table/update_segment.cpp +6 -6
@@ -71,10 +71,10 @@ public:
71
71
  }
72
72
  explicit VectorBuffer(idx_t data_size) : buffer_type(VectorBufferType::STANDARD_BUFFER) {
73
73
  if (data_size > 0) {
74
- data = make_unsafe_array<data_t>(data_size);
74
+ data = make_unsafe_uniq_array<data_t>(data_size);
75
75
  }
76
76
  }
77
- explicit VectorBuffer(unsafe_array_ptr<data_t> data_p)
77
+ explicit VectorBuffer(unsafe_unique_array<data_t> data_p)
78
78
  : buffer_type(VectorBufferType::STANDARD_BUFFER), data(std::move(data_p)) {
79
79
  }
80
80
  virtual ~VectorBuffer() {
@@ -87,7 +87,7 @@ public:
87
87
  return data.get();
88
88
  }
89
89
 
90
- void SetData(unsafe_array_ptr<data_t> new_data) {
90
+ void SetData(unsafe_unique_array<data_t> new_data) {
91
91
  data = std::move(new_data);
92
92
  }
93
93
 
@@ -120,7 +120,7 @@ public:
120
120
  protected:
121
121
  VectorBufferType buffer_type;
122
122
  unique_ptr<VectorAuxiliaryData> aux_data;
123
- unsafe_array_ptr<data_t> data;
123
+ unsafe_unique_array<data_t> data;
124
124
  };
125
125
 
126
126
  //! The DictionaryBuffer holds a selection vector
@@ -9,10 +9,10 @@
9
9
 
10
10
  namespace duckdb {
11
11
 
12
- template <class _Tp, bool SAFE = true>
13
- class unique_ptr : public std::unique_ptr<_Tp, std::default_delete<_Tp>> {
12
+ template <class _Tp, class _Dp = std::default_delete<_Tp>, bool SAFE = true>
13
+ class unique_ptr : public std::unique_ptr<_Tp, _Dp> {
14
14
  public:
15
- using original = std::unique_ptr<_Tp, std::default_delete<_Tp>>;
15
+ using original = std::unique_ptr<_Tp, _Dp>;
16
16
  using original::original;
17
17
 
18
18
  private:
@@ -53,8 +53,8 @@ public:
53
53
  }
54
54
  };
55
55
 
56
- template <class _Tp, bool SAFE>
57
- class unique_ptr<_Tp[], SAFE> : public std::unique_ptr<_Tp[], std::default_delete<_Tp[]>> {
56
+ template <class _Tp, class _Dp, bool SAFE>
57
+ class unique_ptr<_Tp[], _Dp, SAFE> : public std::unique_ptr<_Tp[], std::default_delete<_Tp[]>> {
58
58
  public:
59
59
  using original = std::unique_ptr<_Tp[], std::default_delete<_Tp[]>>;
60
60
  using original::original;
@@ -81,12 +81,12 @@ public:
81
81
  };
82
82
 
83
83
  template <typename T>
84
- using array_ptr = unique_ptr<T[], true>;
84
+ using unique_array = unique_ptr<T[], std::default_delete<T>, true>;
85
85
 
86
86
  template <typename T>
87
- using unsafe_array_ptr = unique_ptr<T[], false>;
87
+ using unsafe_unique_array = unique_ptr<T[], std::default_delete<T>, false>;
88
88
 
89
89
  template <typename T>
90
- using unsafe_unique_ptr = unique_ptr<T, false>;
90
+ using unsafe_unique_ptr = unique_ptr<T, std::default_delete<T>, false>;
91
91
 
92
92
  } // namespace duckdb
@@ -73,7 +73,7 @@ struct AggregateHTAppendState {
73
73
  SelectionVector empty_vector;
74
74
  SelectionVector new_groups;
75
75
  Vector addresses;
76
- unsafe_array_ptr<UnifiedVectorFormat> group_data;
76
+ unsafe_unique_array<UnifiedVectorFormat> group_data;
77
77
  DataChunk group_chunk;
78
78
 
79
79
  TupleDataChunkState chunk_state;
@@ -65,12 +65,12 @@ public:
65
65
  //! returned by the JoinHashTable::Scan function and can be used to resume a
66
66
  //! probe.
67
67
  struct ScanStructure {
68
- unsafe_array_ptr<UnifiedVectorFormat> key_data;
68
+ unsafe_unique_array<UnifiedVectorFormat> key_data;
69
69
  Vector pointers;
70
70
  idx_t count;
71
71
  SelectionVector sel_vector;
72
72
  // whether or not the given tuple has found a match
73
- unsafe_array_ptr<bool> found_match;
73
+ unsafe_unique_array<bool> found_match;
74
74
  JoinHashTable &ht;
75
75
  bool finished;
76
76
 
@@ -212,7 +212,7 @@ private:
212
212
  //! Insert the given set of locations into the HT with the given set of hashes
213
213
  void InsertHashes(Vector &hashes, idx_t count, data_ptr_t key_locations[], bool parallel);
214
214
 
215
- idx_t PrepareKeys(DataChunk &keys, unsafe_array_ptr<UnifiedVectorFormat> &key_data,
215
+ idx_t PrepareKeys(DataChunk &keys, unsafe_unique_array<UnifiedVectorFormat> &key_data,
216
216
  const SelectionVector *&current_sel, SelectionVector &sel, bool build_side);
217
217
 
218
218
  //! Lock for combining data_collection when merging HTs
@@ -67,7 +67,7 @@ public:
67
67
 
68
68
  private:
69
69
  bool enabled;
70
- unsafe_array_ptr<bool> found_match;
70
+ unsafe_unique_array<bool> found_match;
71
71
  idx_t count;
72
72
  };
73
73
 
@@ -68,7 +68,7 @@ private:
68
68
  //! Build and probe statistics
69
69
  PerfectHashJoinStats perfect_join_statistics;
70
70
  //! Stores the occurences of each value in the build side
71
- unsafe_array_ptr<bool> bitmap_build_idx;
71
+ unsafe_unique_array<bool> bitmap_build_idx;
72
72
  //! Stores the number of unique keys in the build side
73
73
  idx_t unique_keys = 0;
74
74
  };
@@ -83,7 +83,7 @@ public:
83
83
  //! The total number of rows in the RHS
84
84
  atomic<idx_t> count;
85
85
  //! A bool indicating for each tuple in the RHS if they found a match (only used in FULL OUTER JOIN)
86
- unsafe_array_ptr<bool> found_match;
86
+ unsafe_unique_array<bool> found_match;
87
87
  //! Memory usage per thread
88
88
  idx_t memory_per_thread;
89
89
  };
@@ -60,12 +60,12 @@ public:
60
60
  virtual ~BufferedCSVReader() {
61
61
  }
62
62
 
63
- unsafe_array_ptr<char> buffer;
63
+ unsafe_unique_array<char> buffer;
64
64
  idx_t buffer_size;
65
65
  idx_t position;
66
66
  idx_t start = 0;
67
67
 
68
- vector<unsafe_array_ptr<char>> cached_buffers;
68
+ vector<unsafe_unique_array<char>> cached_buffers;
69
69
 
70
70
  unique_ptr<CSVFileHandle> file_handle;
71
71
 
@@ -67,7 +67,7 @@ struct CSVBufferRead {
67
67
  } else {
68
68
  // 3) It starts in the current buffer and ends in the next buffer
69
69
  D_ASSERT(next_buffer);
70
- auto intersection = make_unsafe_array<char>(length);
70
+ auto intersection = make_unsafe_uniq_array<char>(length);
71
71
  idx_t cur_pos = 0;
72
72
  auto buffer_ptr = buffer->Ptr();
73
73
  for (idx_t i = start_buffer; i < buffer->GetBufferSize(); i++) {
@@ -85,7 +85,7 @@ struct CSVBufferRead {
85
85
 
86
86
  shared_ptr<CSVBuffer> buffer;
87
87
  shared_ptr<CSVBuffer> next_buffer;
88
- vector<unsafe_array_ptr<char>> intersections;
88
+ vector<unsafe_unique_array<char>> intersections;
89
89
  optional_ptr<LineInfo> line_info;
90
90
 
91
91
  idx_t buffer_start;
@@ -115,10 +115,9 @@ protected:
115
115
  void CombineExistingAndInsertTuples(DataChunk &result, DataChunk &scan_chunk, DataChunk &input_chunk,
116
116
  ClientContext &client) const;
117
117
  //! Returns the amount of updated tuples
118
+ void CreateUpdateChunk(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry &table, Vector &row_ids,
119
+ DataChunk &result) const;
118
120
  idx_t OnConflictHandling(TableCatalogEntry &table, ExecutionContext &context, InsertLocalState &lstate) const;
119
- idx_t PerformOnConflictAction(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry &table,
120
- Vector &row_ids) const;
121
- void RegisterUpdatedRows(InsertLocalState &lstate, const Vector &row_ids, idx_t count) const;
122
121
  };
123
122
 
124
123
  } // namespace duckdb
@@ -46,9 +46,9 @@ protected:
46
46
  // The actual pointer to the data
47
47
  data_ptr_t data;
48
48
  //! The owned data of the HT
49
- unsafe_array_ptr<data_t> owned_data;
49
+ unsafe_unique_array<data_t> owned_data;
50
50
  //! Information on whether or not a specific group has any entries
51
- unsafe_array_ptr<bool> group_is_set;
51
+ unsafe_unique_array<bool> group_is_set;
52
52
 
53
53
  //! The minimum values for each of the group columns
54
54
  vector<Value> group_minima;
@@ -113,7 +113,7 @@ private:
113
113
  Vector statev;
114
114
 
115
115
  //! The actual window segment tree: an array of aggregate states that represent all the intermediate nodes
116
- unsafe_array_ptr<data_t> levels_flat_native;
116
+ unsafe_unique_array<data_t> levels_flat_native;
117
117
  //! For each level, the starting location in the levels_flat_native array
118
118
  vector<idx_t> levels_flat_start;
119
119
 
@@ -55,7 +55,7 @@ struct WriteCSVData : public BaseCSVData {
55
55
  //! The size of the CSV file (in bytes) that we buffer before we flush it to disk
56
56
  idx_t flush_size = 4096 * 8;
57
57
  //! For each byte whether or not the CSV file requires quotes when containing the byte
58
- unsafe_array_ptr<bool> requires_quotes;
58
+ unsafe_unique_array<bool> requires_quotes;
59
59
  };
60
60
 
61
61
  struct ColumnInfo {
@@ -54,7 +54,7 @@ struct ClientData {
54
54
  unique_ptr<FileOpener> file_opener;
55
55
 
56
56
  //! HTTP State in this query
57
- unique_ptr<HTTPState> http_state;
57
+ shared_ptr<HTTPState> http_state;
58
58
 
59
59
  //! The clients' file system wrapper
60
60
  unique_ptr<FileSystem> client_file_system;
@@ -27,12 +27,12 @@ struct SingleJoinRelation {
27
27
 
28
28
  //! Set of relations, used in the join graph.
29
29
  struct JoinRelationSet {
30
- JoinRelationSet(unsafe_array_ptr<idx_t> relations, idx_t count) : relations(std::move(relations)), count(count) {
30
+ JoinRelationSet(unsafe_unique_array<idx_t> relations, idx_t count) : relations(std::move(relations)), count(count) {
31
31
  }
32
32
 
33
33
  string ToString() const;
34
34
 
35
- unsafe_array_ptr<idx_t> relations;
35
+ unsafe_unique_array<idx_t> relations;
36
36
  idx_t count;
37
37
 
38
38
  static bool IsSubset(JoinRelationSet &super, JoinRelationSet &sub);
@@ -55,7 +55,7 @@ public:
55
55
  //! Create or get a JoinRelationSet from a set of relation bindings
56
56
  JoinRelationSet &GetJoinRelation(unordered_set<idx_t> &bindings);
57
57
  //! Create or get a JoinRelationSet from a (sorted, duplicate-free!) list of relations
58
- JoinRelationSet &GetJoinRelation(unsafe_array_ptr<idx_t> relations, idx_t count);
58
+ JoinRelationSet &GetJoinRelation(unsafe_unique_array<idx_t> relations, idx_t count);
59
59
  //! Union two sets of relations together and create a new relation set
60
60
  JoinRelationSet &Union(JoinRelationSet &left, JoinRelationSet &right);
61
61
  // //! Create the set difference of left \ right (i.e. all elements in left that are not in right)
@@ -193,6 +193,10 @@ public:
193
193
  void VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk,
194
194
  ConflictManager *conflict_manager = nullptr);
195
195
 
196
+ public:
197
+ static void VerifyUniqueIndexes(TableIndexList &indexes, ClientContext &context, DataChunk &chunk,
198
+ ConflictManager *conflict_manager);
199
+
196
200
  private:
197
201
  //! Verify the new added constraints against current persistent&local data
198
202
  void VerifyNewConstraint(ClientContext &context, DataTable &parent, const BoundConstraint *constraint);
@@ -138,7 +138,7 @@ private:
138
138
  StringStatsData string_data;
139
139
  } stats_union;
140
140
  //! Child stats (for LIST and STRUCT)
141
- unsafe_array_ptr<BaseStatistics> child_stats;
141
+ unsafe_unique_array<BaseStatistics> child_stats;
142
142
  };
143
143
 
144
144
  } // namespace duckdb
@@ -44,7 +44,7 @@ struct RowGroupAppendState {
44
44
  //! The current row_group we are appending to
45
45
  RowGroup *row_group;
46
46
  //! The column append states
47
- unsafe_array_ptr<ColumnAppendState> states;
47
+ unsafe_unique_array<ColumnAppendState> states;
48
48
  //! Offset within the row_group
49
49
  idx_t offset_in_row_group;
50
50
  };
@@ -149,7 +149,7 @@ public:
149
149
 
150
150
  private:
151
151
  ChunkInfo *GetChunkInfo(idx_t vector_idx);
152
- ColumnData &GetColumn(idx_t c);
152
+ ColumnData &GetColumn(storage_t c);
153
153
  idx_t GetColumnCount() const;
154
154
  vector<shared_ptr<ColumnData>> &GetColumns();
155
155
 
@@ -99,7 +99,7 @@ public:
99
99
  //! The maximum row within the row group
100
100
  idx_t max_row_group_row;
101
101
  //! Child column scans
102
- unsafe_array_ptr<ColumnScanState> column_scans;
102
+ unsafe_unique_array<ColumnScanState> column_scans;
103
103
  //! Row group segment tree
104
104
  RowGroupSegmentTree *row_groups;
105
105
  //! The total maximum row index
@@ -109,7 +109,7 @@ public:
109
109
 
110
110
  public:
111
111
  void Initialize(const vector<LogicalType> &types);
112
- const vector<column_t> &GetColumnIds();
112
+ const vector<storage_t> &GetColumnIds();
113
113
  TableFilterSet *GetFilters();
114
114
  AdaptiveFilter *GetAdaptiveFilter();
115
115
  bool Scan(DuckTransaction &transaction, DataChunk &result);
@@ -130,15 +130,15 @@ public:
130
130
  CollectionScanState local_state;
131
131
 
132
132
  public:
133
- void Initialize(vector<column_t> column_ids, TableFilterSet *table_filters = nullptr);
133
+ void Initialize(vector<storage_t> column_ids, TableFilterSet *table_filters = nullptr);
134
134
 
135
- const vector<column_t> &GetColumnIds();
135
+ const vector<storage_t> &GetColumnIds();
136
136
  TableFilterSet *GetFilters();
137
137
  AdaptiveFilter *GetAdaptiveFilter();
138
138
 
139
139
  private:
140
140
  //! The column identifiers of the scan
141
- vector<column_t> column_ids;
141
+ vector<storage_t> column_ids;
142
142
  //! The table filters (if any)
143
143
  TableFilterSet *table_filters;
144
144
  //! Adaptive filter info (if any)
@@ -96,8 +96,8 @@ private:
96
96
 
97
97
  struct UpdateNodeData {
98
98
  unique_ptr<UpdateInfo> info;
99
- unsafe_array_ptr<sel_t> tuples;
100
- unsafe_array_ptr<data_t> tuple_data;
99
+ unsafe_unique_array<sel_t> tuples;
100
+ unsafe_unique_array<data_t> tuple_data;
101
101
  };
102
102
 
103
103
  struct UpdateNode {
@@ -108,7 +108,7 @@ public:
108
108
  //! Initialize a scan of the local storage
109
109
  void InitializeScan(DataTable &table, CollectionScanState &state, optional_ptr<TableFilterSet> table_filters);
110
110
  //! Scan
111
- void Scan(CollectionScanState &state, const vector<column_t> &column_ids, DataChunk &result);
111
+ void Scan(CollectionScanState &state, const vector<storage_t> &column_ids, DataChunk &result);
112
112
 
113
113
  void InitializeParallelScan(DataTable &table, ParallelCollectionScanState &state);
114
114
  bool NextParallelScan(ClientContext &context, DataTable &table, ParallelCollectionScanState &state,
@@ -209,7 +209,7 @@ PreservedError ClientContext::EndQueryInternal(ClientContextLock &lock, bool suc
209
209
  }
210
210
 
211
211
  void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *result, bool invalidate_transaction) {
212
- client_data->http_state = make_uniq<HTTPState>();
212
+ client_data->http_state = make_shared<HTTPState>();
213
213
  if (!active_query) {
214
214
  // no query currently active
215
215
  return;
@@ -491,7 +491,7 @@ unique_ptr<LogicalOperator> ClientContext::ExtractPlan(const string &query) {
491
491
  }
492
492
 
493
493
  unique_ptr<LogicalOperator> plan;
494
- client_data->http_state = make_uniq<HTTPState>();
494
+ client_data->http_state = make_shared<HTTPState>();
495
495
  RunFunctionInTransactionInternal(*lock, [&]() {
496
496
  Planner planner(*this);
497
497
  planner.CreatePlan(std::move(statements[0]));
@@ -934,7 +934,7 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co
934
934
  bool requires_valid_transaction) {
935
935
  if (requires_valid_transaction && transaction.HasActiveTransaction() &&
936
936
  ValidChecker::IsInvalidated(ActiveTransaction())) {
937
- throw Exception(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION));
937
+ throw TransactionException(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION));
938
938
  }
939
939
  // check if we are on AutoCommit. In this case we should start a transaction
940
940
  bool require_new_transaction = transaction.IsAutoCommit() && !transaction.HasActiveTransaction();
@@ -1013,7 +1013,7 @@ void ClientContext::TryBindRelation(Relation &relation, vector<ColumnDefinition>
1013
1013
  D_ASSERT(!relation.GetAlias().empty());
1014
1014
  D_ASSERT(!relation.ToString().empty());
1015
1015
  #endif
1016
- client_data->http_state = make_uniq<HTTPState>();
1016
+ client_data->http_state = make_shared<HTTPState>();
1017
1017
  RunFunctionInTransaction([&]() {
1018
1018
  // bind the expressions
1019
1019
  auto binder = Binder::CreateBinder(*this);
@@ -133,10 +133,10 @@ void ExtensionHelper::InstallExtension(ClientContext &context, const string &ext
133
133
  InstallExtensionInternal(config, &client_config, fs, local_path, extension, force_install);
134
134
  }
135
135
 
136
- unsafe_array_ptr<data_t> ReadExtensionFileFromDisk(FileSystem &fs, const string &path, idx_t &file_size) {
136
+ unsafe_unique_array<data_t> ReadExtensionFileFromDisk(FileSystem &fs, const string &path, idx_t &file_size) {
137
137
  auto source_file = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ);
138
138
  file_size = source_file->GetFileSize();
139
- auto in_buffer = make_unsafe_array<data_t>(file_size);
139
+ auto in_buffer = make_unsafe_uniq_array<data_t>(file_size);
140
140
  source_file->Read(in_buffer.get(), file_size);
141
141
  source_file->Close();
142
142
  return in_buffer;
@@ -35,7 +35,7 @@ bool JoinRelationSet::IsSubset(JoinRelationSet &super, JoinRelationSet &sub) {
35
35
  return false;
36
36
  }
37
37
 
38
- JoinRelationSet &JoinRelationSetManager::GetJoinRelation(unsafe_array_ptr<idx_t> relations, idx_t count) {
38
+ JoinRelationSet &JoinRelationSetManager::GetJoinRelation(unsafe_unique_array<idx_t> relations, idx_t count) {
39
39
  // now look it up in the tree
40
40
  reference<JoinRelationTreeNode> info(root);
41
41
  for (idx_t i = 0; i < count; i++) {
@@ -59,7 +59,7 @@ JoinRelationSet &JoinRelationSetManager::GetJoinRelation(unsafe_array_ptr<idx_t>
59
59
  //! Create or get a JoinRelationSet from a single node with the given index
60
60
  JoinRelationSet &JoinRelationSetManager::GetJoinRelation(idx_t index) {
61
61
  // create a sorted vector of the relations
62
- auto relations = make_unsafe_array<idx_t>(1);
62
+ auto relations = make_unsafe_uniq_array<idx_t>(1);
63
63
  relations[0] = index;
64
64
  idx_t count = 1;
65
65
  return GetJoinRelation(std::move(relations), count);
@@ -67,7 +67,7 @@ JoinRelationSet &JoinRelationSetManager::GetJoinRelation(idx_t index) {
67
67
 
68
68
  JoinRelationSet &JoinRelationSetManager::GetJoinRelation(unordered_set<idx_t> &bindings) {
69
69
  // create a sorted vector of the relations
70
- unsafe_array_ptr<idx_t> relations = bindings.empty() ? nullptr : make_unsafe_array<idx_t>(bindings.size());
70
+ unsafe_unique_array<idx_t> relations = bindings.empty() ? nullptr : make_unsafe_uniq_array<idx_t>(bindings.size());
71
71
  idx_t count = 0;
72
72
  for (auto &entry : bindings) {
73
73
  relations[count++] = entry;
@@ -77,7 +77,7 @@ JoinRelationSet &JoinRelationSetManager::GetJoinRelation(unordered_set<idx_t> &b
77
77
  }
78
78
 
79
79
  JoinRelationSet &JoinRelationSetManager::Union(JoinRelationSet &left, JoinRelationSet &right) {
80
- auto relations = make_unsafe_array<idx_t>(left.count + right.count);
80
+ auto relations = make_unsafe_uniq_array<idx_t>(left.count + right.count);
81
81
  idx_t count = 0;
82
82
  // move through the left and right relations, eliminating duplicates
83
83
  idx_t i = 0, j = 0;
@@ -113,7 +113,7 @@ JoinRelationSet &JoinRelationSetManager::Union(JoinRelationSet &left, JoinRelati
113
113
  }
114
114
 
115
115
  // JoinRelationSet *JoinRelationSetManager::Difference(JoinRelationSet *left, JoinRelationSet *right) {
116
- // auto relations = unsafe_array_ptr<idx_t>(new idx_t[left->count]);
116
+ // auto relations = unsafe_unique_array<idx_t>(new idx_t[left->count]);
117
117
  // idx_t count = 0;
118
118
  // // move through the left and right relations
119
119
  // idx_t i = 0, j = 0;
@@ -94,7 +94,13 @@ unique_ptr<BoundTableRef> Binder::Bind(BaseTableRef &ref) {
94
94
  for (auto &scan : config.replacement_scans) {
95
95
  auto replacement_function = scan.function(context, table_name, scan.data.get());
96
96
  if (replacement_function) {
97
- replacement_function->alias = ref.alias.empty() ? replacement_function->alias : ref.alias;
97
+ if (!ref.alias.empty()) {
98
+ // user-provided alias overrides the default alias
99
+ replacement_function->alias = ref.alias;
100
+ } else if (replacement_function->alias.empty()) {
101
+ // if the replacement scan itself did not provide an alias we use the table name
102
+ replacement_function->alias = ref.table_name;
103
+ }
98
104
  if (replacement_function->type == TableReferenceType::TABLE_FUNCTION) {
99
105
  auto &table_function = replacement_function->Cast<TableFunctionRef>();
100
106
  table_function.column_name_alias = ref.column_name_alias;
@@ -40,7 +40,7 @@ BindResult IndexBinder::BindExpression(unique_ptr<ParsedExpression> &expr_ptr, i
40
40
  throw InternalException("failed to replay CREATE INDEX statement - column id not found");
41
41
  }
42
42
  return BindResult(
43
- make_uniq<BoundColumnRefExpression>(col_ref.alias, col_type, ColumnBinding(0, col_id_idx)));
43
+ make_uniq<BoundColumnRefExpression>(col_ref.GetColumnName(), col_type, ColumnBinding(0, col_id_idx)));
44
44
  }
45
45
  return ExpressionBinder::BindExpression(expr_ptr, depth);
46
46
  }
@@ -32,7 +32,7 @@ void WriteOverflowStringsToDisk::WriteString(string_t string, block_id_t &result
32
32
  MiniZStream s;
33
33
  size_t compressed_size = 0;
34
34
  compressed_size = s.MaxCompressedLength(uncompressed_size);
35
- auto compressed_buf = make_unsafe_array<data_t>(compressed_size);
35
+ auto compressed_buf = make_unsafe_uniq_array<data_t>(compressed_size);
36
36
  s.Compress((const char *)string.GetData(), uncompressed_size, (char *)compressed_buf.get(), &compressed_size);
37
37
  string_t compressed_string((const char *)compressed_buf.get(), compressed_size);
38
38
 
@@ -292,13 +292,13 @@ string_t UncompressedStringStorage::ReadOverflowString(ColumnSegment &segment, V
292
292
  offset += 2 * sizeof(uint32_t);
293
293
 
294
294
  data_ptr_t decompression_ptr;
295
- unsafe_array_ptr<data_t> decompression_buffer;
295
+ unsafe_unique_array<data_t> decompression_buffer;
296
296
 
297
297
  // If string is in single block we decompress straight from it, else we copy first
298
298
  if (remaining <= Storage::BLOCK_SIZE - sizeof(block_id_t) - offset) {
299
299
  decompression_ptr = handle.Ptr() + offset;
300
300
  } else {
301
- decompression_buffer = make_unsafe_array<data_t>(compressed_size);
301
+ decompression_buffer = make_unsafe_uniq_array<data_t>(compressed_size);
302
302
  auto target_ptr = decompression_buffer.get();
303
303
 
304
304
  // now append the string to the single buffer
@@ -530,6 +530,75 @@ void DataTable::VerifyNewConstraint(ClientContext &context, DataTable &parent, c
530
530
  local_storage.VerifyNewConstraint(parent, *constraint);
531
531
  }
532
532
 
533
+ bool HasUniqueIndexes(TableIndexList &list) {
534
+ bool has_unique_index = false;
535
+ list.Scan([&](Index &index) {
536
+ if (index.IsUnique()) {
537
+ return has_unique_index = true;
538
+ return true;
539
+ }
540
+ return false;
541
+ });
542
+ return has_unique_index;
543
+ }
544
+
545
+ void DataTable::VerifyUniqueIndexes(TableIndexList &indexes, ClientContext &context, DataChunk &chunk,
546
+ ConflictManager *conflict_manager) {
547
+ //! check whether or not the chunk can be inserted into the indexes
548
+ if (!conflict_manager) {
549
+ // Only need to verify that no unique constraints are violated
550
+ indexes.Scan([&](Index &index) {
551
+ if (!index.IsUnique()) {
552
+ return false;
553
+ }
554
+ index.VerifyAppend(chunk);
555
+ return false;
556
+ });
557
+ return;
558
+ }
559
+
560
+ D_ASSERT(conflict_manager);
561
+ // The conflict manager is only provided when a ON CONFLICT clause was provided to the INSERT statement
562
+
563
+ idx_t matching_indexes = 0;
564
+ auto &conflict_info = conflict_manager->GetConflictInfo();
565
+ // First we figure out how many indexes match our conflict target
566
+ // So we can optimize accordingly
567
+ indexes.Scan([&](Index &index) {
568
+ matching_indexes += conflict_info.ConflictTargetMatches(index);
569
+ return false;
570
+ });
571
+ conflict_manager->SetMode(ConflictManagerMode::SCAN);
572
+ conflict_manager->SetIndexCount(matching_indexes);
573
+ // First we verify only the indexes that match our conflict target
574
+ unordered_set<Index *> checked_indexes;
575
+ indexes.Scan([&](Index &index) {
576
+ if (!index.IsUnique()) {
577
+ return false;
578
+ }
579
+ if (conflict_info.ConflictTargetMatches(index)) {
580
+ index.VerifyAppend(chunk, *conflict_manager);
581
+ checked_indexes.insert(&index);
582
+ }
583
+ return false;
584
+ });
585
+
586
+ conflict_manager->SetMode(ConflictManagerMode::THROW);
587
+ // Then we scan the other indexes, throwing if they cause conflicts on tuples that were not found during
588
+ // the scan
589
+ indexes.Scan([&](Index &index) {
590
+ if (!index.IsUnique()) {
591
+ return false;
592
+ }
593
+ if (checked_indexes.count(&index)) {
594
+ // Already checked this constraint
595
+ return false;
596
+ }
597
+ index.VerifyAppend(chunk, *conflict_manager);
598
+ return false;
599
+ });
600
+ }
601
+
533
602
  void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk,
534
603
  ConflictManager *conflict_manager) {
535
604
  if (table.HasGeneratedColumns()) {
@@ -548,6 +617,11 @@ void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext
548
617
  VerifyGeneratedExpressionSuccess(context, table, chunk, *bound_expression, col.Oid());
549
618
  }
550
619
  }
620
+
621
+ if (HasUniqueIndexes(info->indexes)) {
622
+ VerifyUniqueIndexes(info->indexes, context, chunk, conflict_manager);
623
+ }
624
+
551
625
  auto &constraints = table.GetConstraints();
552
626
  auto &bound_constraints = table.GetBoundConstraints();
553
627
  for (idx_t i = 0; i < bound_constraints.size(); i++) {
@@ -567,50 +641,7 @@ void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext
567
641
  break;
568
642
  }
569
643
  case ConstraintType::UNIQUE: {
570
- //! check whether or not the chunk can be inserted into the indexes
571
- if (conflict_manager) {
572
- // This is only provided when a ON CONFLICT clause was provided
573
- idx_t matching_indexes = 0;
574
- auto &conflict_info = conflict_manager->GetConflictInfo();
575
- // First we figure out how many indexes match our conflict target
576
- // So we can optimize accordingly
577
- info->indexes.Scan([&](Index &index) {
578
- matching_indexes += conflict_info.ConflictTargetMatches(index);
579
- return false;
580
- });
581
- conflict_manager->SetMode(ConflictManagerMode::SCAN);
582
- conflict_manager->SetIndexCount(matching_indexes);
583
- // First we verify only the indexes that match our conflict target
584
- info->indexes.Scan([&](Index &index) {
585
- if (!index.IsUnique()) {
586
- return false;
587
- }
588
- if (conflict_info.ConflictTargetMatches(index)) {
589
- index.VerifyAppend(chunk, *conflict_manager);
590
- }
591
- return false;
592
- });
593
-
594
- conflict_manager->SetMode(ConflictManagerMode::THROW);
595
- // Then we scan the other indexes, throwing if they cause conflicts on tuples that were not found during
596
- // the scan
597
- info->indexes.Scan([&](Index &index) {
598
- if (!index.IsUnique()) {
599
- return false;
600
- }
601
- index.VerifyAppend(chunk, *conflict_manager);
602
- return false;
603
- });
604
- } else {
605
- // Only need to verify that no unique constraints are violated
606
- info->indexes.Scan([&](Index &index) {
607
- if (!index.IsUnique()) {
608
- return false;
609
- }
610
- index.VerifyAppend(chunk);
611
- return false;
612
- });
613
- }
644
+ // These were handled earlier on
614
645
  break;
615
646
  }
616
647
  case ConstraintType::FOREIGN_KEY: {