duckdb 0.3.5-dev26.0 → 0.3.5-dev54.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.3.5-dev26.0",
4
+ "version": "0.3.5-dev54.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -41290,7 +41290,7 @@ void Vector::Normalify(idx_t count) {
41290
41290
  break;
41291
41291
  case VectorType::DICTIONARY_VECTOR: {
41292
41292
  // create a new flat vector of this type
41293
- Vector other(GetType());
41293
+ Vector other(GetType(), count);
41294
41294
  // now copy the data of this vector to the other vector, removing the selection vector in the process
41295
41295
  VectorOperations::Copy(*this, other, count, 0, 0);
41296
41296
  // create a reference to the data in the other vector
@@ -47105,7 +47105,20 @@ void VectorOperations::Copy(const Vector &source, Vector &target, const Selectio
47105
47105
  if (smask.IsMaskSet()) {
47106
47106
  for (idx_t i = 0; i < copy_count; i++) {
47107
47107
  auto idx = sel->get_index(source_offset + i);
47108
- tmask.Set(target_offset + i, smask.RowIsValid(idx));
47108
+
47109
+ if (smask.RowIsValid(idx)) {
47110
+ // set valid
47111
+ if (!tmask.AllValid()) {
47112
+ tmask.SetValidUnsafe(target_offset + i);
47113
+ }
47114
+ } else {
47115
+ // set invalid
47116
+ if (tmask.AllValid()) {
47117
+ auto init_size = MaxValue<idx_t>(STANDARD_VECTOR_SIZE, target_offset + copy_count);
47118
+ tmask.Initialize(init_size);
47119
+ }
47120
+ tmask.SetInvalidUnsafe(target_offset + i);
47121
+ }
47109
47122
  }
47110
47123
  }
47111
47124
  }
@@ -79724,6 +79737,11 @@ struct ListAggregateFun {
79724
79737
  static void RegisterFunction(BuiltinFunctions &set);
79725
79738
  };
79726
79739
 
79740
+ struct ListSortFun {
79741
+ static ScalarFunction GetFunction();
79742
+ static void RegisterFunction(BuiltinFunctions &set);
79743
+ };
79744
+
79727
79745
  struct CardinalityFun {
79728
79746
  static void RegisterFunction(BuiltinFunctions &set);
79729
79747
  };
@@ -88868,6 +88886,371 @@ void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
88868
88886
 
88869
88887
 
88870
88888
 
88889
+ namespace duckdb {
88890
+
88891
+ struct ListSortBindData : public FunctionData {
88892
+ ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, LogicalType &return_type_p,
88893
+ LogicalType &child_type_p, ClientContext &context_p);
88894
+ ~ListSortBindData() override;
88895
+
88896
+ OrderType order_type;
88897
+ OrderByNullType null_order;
88898
+ LogicalType return_type;
88899
+ LogicalType child_type;
88900
+
88901
+ vector<LogicalType> types;
88902
+ vector<LogicalType> payload_types;
88903
+
88904
+ ClientContext &context;
88905
+ unique_ptr<GlobalSortState> global_sort_state;
88906
+ RowLayout payload_layout;
88907
+ vector<BoundOrderByNode> orders;
88908
+
88909
+ unique_ptr<FunctionData> Copy() override;
88910
+ };
88911
+
88912
+ ListSortBindData::ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, LogicalType &return_type_p,
88913
+ LogicalType &child_type_p, ClientContext &context_p)
88914
+ : order_type(order_type_p), null_order(null_order_p), return_type(return_type_p), child_type(child_type_p),
88915
+ context(context_p) {
88916
+
88917
+ // get the vector types
88918
+ types.emplace_back(LogicalType::USMALLINT);
88919
+ types.emplace_back(child_type);
88920
+ D_ASSERT(types.size() == 2);
88921
+
88922
+ // get the payload types
88923
+ payload_types.emplace_back(LogicalType::UINTEGER);
88924
+ D_ASSERT(payload_types.size() == 1);
88925
+
88926
+ // initialize the payload layout
88927
+ payload_layout.Initialize(payload_types);
88928
+
88929
+ // get the BoundOrderByNode
88930
+ auto idx_col_expr = make_unique_base<Expression, BoundReferenceExpression>(LogicalType::USMALLINT, 0);
88931
+ auto lists_col_expr = make_unique_base<Expression, BoundReferenceExpression>(child_type, 1);
88932
+ orders.emplace_back(OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, move(idx_col_expr));
88933
+ orders.emplace_back(order_type, null_order, move(lists_col_expr));
88934
+ }
88935
+
88936
+ unique_ptr<FunctionData> ListSortBindData::Copy() {
88937
+ return make_unique<ListSortBindData>(order_type, null_order, return_type, child_type, context);
88938
+ }
88939
+
88940
+ ListSortBindData::~ListSortBindData() {
88941
+ }
88942
+
88943
+ // create the key_chunk and the payload_chunk and sink them into the local_sort_state
88944
+ void SinkDataChunk(Vector *child_vector, SelectionVector &sel, idx_t offset_lists_indices, vector<LogicalType> &types,
88945
+ vector<LogicalType> &payload_types, Vector &payload_vector, LocalSortState &local_sort_state,
88946
+ bool &data_to_sort, Vector &lists_indices) {
88947
+
88948
+ // slice the child vector
88949
+ Vector slice(*child_vector, sel, offset_lists_indices);
88950
+
88951
+ // initialize and fill key_chunk
88952
+ DataChunk key_chunk;
88953
+ key_chunk.InitializeEmpty(types);
88954
+ key_chunk.data[0].Reference(lists_indices);
88955
+ key_chunk.data[1].Reference(slice);
88956
+ key_chunk.SetCardinality(offset_lists_indices);
88957
+
88958
+ // initialize and fill key_chunk and payload_chunk
88959
+ DataChunk payload_chunk;
88960
+ payload_chunk.InitializeEmpty(payload_types);
88961
+ payload_chunk.data[0].Reference(payload_vector);
88962
+ payload_chunk.SetCardinality(offset_lists_indices);
88963
+
88964
+ // sink
88965
+ local_sort_state.SinkChunk(key_chunk, payload_chunk);
88966
+ data_to_sort = true;
88967
+ }
88968
+
88969
+ static void ListSortFunction(DataChunk &args, ExpressionState &state, Vector &result) {
88970
+
88971
+ D_ASSERT(args.ColumnCount() >= 1 && args.ColumnCount() <= 3);
88972
+ auto count = args.size();
88973
+ Vector &lists = args.data[0];
88974
+
88975
+ result.SetVectorType(VectorType::FLAT_VECTOR);
88976
+ auto &result_validity = FlatVector::Validity(result);
88977
+
88978
+ if (lists.GetType().id() == LogicalTypeId::SQLNULL) {
88979
+ result_validity.SetInvalid(0);
88980
+ return;
88981
+ }
88982
+
88983
+ auto &func_expr = (BoundFunctionExpression &)state.expr;
88984
+ auto &info = (ListSortBindData &)*func_expr.bind_info;
88985
+
88986
+ // initialize the global and local sorting state
88987
+ auto &buffer_manager = BufferManager::GetBufferManager(info.context);
88988
+ info.global_sort_state = make_unique<GlobalSortState>(buffer_manager, info.orders, info.payload_layout);
88989
+ auto &global_sort_state = *info.global_sort_state;
88990
+ LocalSortState local_sort_state;
88991
+ local_sort_state.Initialize(global_sort_state, buffer_manager);
88992
+
88993
+ // get the child vector
88994
+ auto lists_size = ListVector::GetListSize(lists);
88995
+ auto &child_vector = ListVector::GetEntry(lists);
88996
+ VectorData child_data;
88997
+ child_vector.Orrify(lists_size, child_data);
88998
+
88999
+ // get the lists data
89000
+ VectorData lists_data;
89001
+ lists.Orrify(count, lists_data);
89002
+ auto list_entries = (list_entry_t *)lists_data.data;
89003
+
89004
+ // create the lists_indices vector, this contains an element for each list's entry,
89005
+ // the element corresponds to the list's index, e.g. for [1, 2, 4], [5, 4]
89006
+ // lists_indices contains [0, 0, 0, 1, 1]
89007
+ Vector lists_indices(LogicalType::USMALLINT);
89008
+ auto lists_indices_data = FlatVector::GetData<uint16_t>(lists_indices);
89009
+
89010
+ // create the payload_vector, this is just a vector containing incrementing integers
89011
+ // this will later be used as the 'new' selection vector of the child_vector, after
89012
+ // rearranging the payload according to the sorting order
89013
+ Vector payload_vector(LogicalType::UINTEGER);
89014
+ auto payload_vector_data = FlatVector::GetData<uint32_t>(payload_vector);
89015
+
89016
+ // selection vector pointing to the data of the child vector,
89017
+ // used for slicing the child_vector correctly
89018
+ SelectionVector sel(STANDARD_VECTOR_SIZE);
89019
+
89020
+ idx_t offset_lists_indices = 0;
89021
+ uint32_t incr_payload_count = 0;
89022
+ bool data_to_sort = false;
89023
+
89024
+ for (idx_t i = 0; i < count; i++) {
89025
+
89026
+ auto lists_index = lists_data.sel->get_index(i);
89027
+ const auto &list_entry = list_entries[lists_index];
89028
+
89029
+ // nothing to do for this list
89030
+ if (!lists_data.validity.RowIsValid(lists_index)) {
89031
+ result_validity.SetInvalid(i);
89032
+ continue;
89033
+ }
89034
+
89035
+ // empty list, no sorting required
89036
+ if (list_entry.length == 0) {
89037
+ continue;
89038
+ }
89039
+
89040
+ for (idx_t child_idx = 0; child_idx < list_entry.length; child_idx++) {
89041
+
89042
+ // lists_indices vector is full, sink
89043
+ if (offset_lists_indices == STANDARD_VECTOR_SIZE) {
89044
+ SinkDataChunk(&child_vector, sel, offset_lists_indices, info.types, info.payload_types, payload_vector,
89045
+ local_sort_state, data_to_sort, lists_indices);
89046
+ offset_lists_indices = 0;
89047
+ }
89048
+
89049
+ auto source_idx = child_data.sel->get_index(list_entry.offset + child_idx);
89050
+ sel.set_index(offset_lists_indices, source_idx);
89051
+ lists_indices_data[offset_lists_indices] = (uint32_t)i;
89052
+ payload_vector_data[offset_lists_indices] = incr_payload_count;
89053
+ offset_lists_indices++;
89054
+ incr_payload_count++;
89055
+ }
89056
+ }
89057
+
89058
+ if (offset_lists_indices != 0) {
89059
+ SinkDataChunk(&child_vector, sel, offset_lists_indices, info.types, info.payload_types, payload_vector,
89060
+ local_sort_state, data_to_sort, lists_indices);
89061
+ }
89062
+
89063
+ if (data_to_sort) {
89064
+
89065
+ // add local state to global state, which sorts the data
89066
+ global_sort_state.AddLocalState(local_sort_state);
89067
+ global_sort_state.PrepareMergePhase();
89068
+
89069
+ // selection vector that is to be filled with the 'sorted' payload
89070
+ SelectionVector sel_sorted(incr_payload_count);
89071
+ idx_t sel_sorted_idx = 0;
89072
+
89073
+ // scan the sorted row data
89074
+ PayloadScanner scanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state);
89075
+ for (;;) {
89076
+ DataChunk result_chunk;
89077
+ result_chunk.Initialize(info.payload_types);
89078
+ result_chunk.SetCardinality(0);
89079
+ scanner.Scan(result_chunk);
89080
+ if (result_chunk.size() == 0) {
89081
+ break;
89082
+ }
89083
+
89084
+ // construct the selection vector with the new order from the result vectors
89085
+ Vector result_vector(result_chunk.data[0]);
89086
+ auto result_data = FlatVector::GetData<uint32_t>(result_vector);
89087
+ auto row_count = result_chunk.size();
89088
+
89089
+ for (idx_t i = 0; i < row_count; i++) {
89090
+ sel_sorted.set_index(sel_sorted_idx, result_data[i]);
89091
+ sel_sorted_idx++;
89092
+ }
89093
+ }
89094
+
89095
+ D_ASSERT(sel_sorted_idx == incr_payload_count);
89096
+ child_vector.Slice(sel_sorted, sel_sorted_idx);
89097
+ child_vector.Normalify(sel_sorted_idx);
89098
+ }
89099
+
89100
+ result.Reference(lists);
89101
+ }
89102
+
89103
+ static unique_ptr<FunctionData> ListSortBind(ClientContext &context, ScalarFunction &bound_function,
89104
+ vector<unique_ptr<Expression>> &arguments, OrderType &order,
89105
+ OrderByNullType &null_order) {
89106
+
89107
+ if (arguments[0]->return_type.id() == LogicalTypeId::SQLNULL) {
89108
+ bound_function.arguments[0] = LogicalType::SQLNULL;
89109
+ bound_function.return_type = LogicalType::SQLNULL;
89110
+ return make_unique<VariableReturnBindData>(bound_function.return_type);
89111
+ }
89112
+
89113
+ bound_function.arguments[0] = arguments[0]->return_type;
89114
+ bound_function.return_type = arguments[0]->return_type;
89115
+ auto child_type = ListType::GetChildType(arguments[0]->return_type);
89116
+
89117
+ return make_unique<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
89118
+ }
89119
+
89120
+ OrderByNullType GetNullOrder(vector<unique_ptr<Expression>> &arguments, idx_t idx) {
89121
+
89122
+ if (!arguments[idx]->IsFoldable()) {
89123
+ throw InvalidInputException("Null sorting order must be a constant");
89124
+ }
89125
+ Value null_order_value = ExpressionExecutor::EvaluateScalar(*arguments[idx]);
89126
+ auto null_order_name = null_order_value.ToString();
89127
+ std::transform(null_order_name.begin(), null_order_name.end(), null_order_name.begin(), ::toupper);
89128
+ if (null_order_name != "NULLS FIRST" && null_order_name != "NULLS LAST") {
89129
+ throw InvalidInputException("Null sorting order must be either NULLS FIRST or NULLS LAST");
89130
+ }
89131
+
89132
+ if (null_order_name == "NULLS LAST") {
89133
+ return OrderByNullType::NULLS_LAST;
89134
+ }
89135
+ return OrderByNullType::NULLS_FIRST;
89136
+ }
89137
+
89138
+ static unique_ptr<FunctionData> ListNormalSortBind(ClientContext &context, ScalarFunction &bound_function,
89139
+ vector<unique_ptr<Expression>> &arguments) {
89140
+
89141
+ D_ASSERT(bound_function.arguments.size() >= 1 && bound_function.arguments.size() <= 3);
89142
+ D_ASSERT(arguments.size() >= 1 && arguments.size() <= 3);
89143
+
89144
+ // set default values
89145
+ auto &config = DBConfig::GetConfig(context);
89146
+ auto order = config.default_order_type;
89147
+ auto null_order = config.default_null_order;
89148
+
89149
+ // get the sorting order
89150
+ if (arguments.size() >= 2) {
89151
+
89152
+ if (!arguments[1]->IsFoldable()) {
89153
+ throw InvalidInputException("Sorting order must be a constant");
89154
+ }
89155
+ Value order_value = ExpressionExecutor::EvaluateScalar(*arguments[1]);
89156
+ auto order_name = order_value.ToString();
89157
+ std::transform(order_name.begin(), order_name.end(), order_name.begin(), ::toupper);
89158
+ if (order_name != "DESC" && order_name != "ASC") {
89159
+ throw InvalidInputException("Sorting order must be either ASC or DESC");
89160
+ }
89161
+ if (order_name == "DESC") {
89162
+ order = OrderType::DESCENDING;
89163
+ } else {
89164
+ order = OrderType::ASCENDING;
89165
+ }
89166
+ }
89167
+
89168
+ // get the null sorting order
89169
+ if (arguments.size() == 3) {
89170
+ null_order = GetNullOrder(arguments, 2);
89171
+ }
89172
+
89173
+ return ListSortBind(context, bound_function, arguments, order, null_order);
89174
+ }
89175
+
89176
+ static unique_ptr<FunctionData> ListReverseSortBind(ClientContext &context, ScalarFunction &bound_function,
89177
+ vector<unique_ptr<Expression>> &arguments) {
89178
+
89179
+ D_ASSERT(bound_function.arguments.size() == 1 || bound_function.arguments.size() == 2);
89180
+ D_ASSERT(arguments.size() == 1 || arguments.size() == 2);
89181
+
89182
+ // set (reverse) default values
89183
+ auto &config = DBConfig::GetConfig(context);
89184
+ auto order = (config.default_order_type == OrderType::ASCENDING) ? OrderType::DESCENDING : OrderType::ASCENDING;
89185
+ auto null_order = config.default_null_order;
89186
+
89187
+ // get the null sorting order
89188
+ if (arguments.size() == 2) {
89189
+ null_order = GetNullOrder(arguments, 1);
89190
+ }
89191
+
89192
+ return ListSortBind(context, bound_function, arguments, order, null_order);
89193
+ }
89194
+
89195
+ void ListSortFun::RegisterFunction(BuiltinFunctions &set) {
89196
+
89197
+ // normal sort
89198
+
89199
+ // one parameter: list
89200
+ ScalarFunction sort({LogicalType::LIST(LogicalType::ANY)}, LogicalType::LIST(LogicalType::ANY), ListSortFunction,
89201
+ false, false, ListNormalSortBind);
89202
+
89203
+ // two parameters: list, order
89204
+ ScalarFunction sort_order({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR},
89205
+ LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false, ListNormalSortBind);
89206
+
89207
+ // three parameters: list, order, null order
89208
+ ScalarFunction sort_orders({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR, LogicalType::VARCHAR},
89209
+ LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false, ListNormalSortBind);
89210
+
89211
+ ScalarFunctionSet list_sort("list_sort");
89212
+ list_sort.AddFunction(sort);
89213
+ list_sort.AddFunction(sort_order);
89214
+ list_sort.AddFunction(sort_orders);
89215
+ set.AddFunction(list_sort);
89216
+
89217
+ ScalarFunctionSet array_sort("array_sort");
89218
+ array_sort.AddFunction(sort);
89219
+ array_sort.AddFunction(sort_order);
89220
+ array_sort.AddFunction(sort_orders);
89221
+ set.AddFunction(array_sort);
89222
+
89223
+ // reverse sort
89224
+
89225
+ // one parameter: list
89226
+ ScalarFunction sort_reverse({LogicalType::LIST(LogicalType::ANY)}, LogicalType::LIST(LogicalType::ANY),
89227
+ ListSortFunction, false, false, ListReverseSortBind);
89228
+
89229
+ // two parameters: list, null order
89230
+ ScalarFunction sort_reverse_null_order({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR},
89231
+ LogicalType::LIST(LogicalType::ANY), ListSortFunction, false, false,
89232
+ ListReverseSortBind);
89233
+
89234
+ ScalarFunctionSet list_reverse_sort("list_reverse_sort");
89235
+ list_reverse_sort.AddFunction(sort_reverse);
89236
+ list_reverse_sort.AddFunction(sort_reverse_null_order);
89237
+ set.AddFunction(list_reverse_sort);
89238
+
89239
+ ScalarFunctionSet array_reverse_sort("array_reverse_sort");
89240
+ array_reverse_sort.AddFunction(sort_reverse);
89241
+ array_reverse_sort.AddFunction(sort_reverse_null_order);
89242
+ set.AddFunction(array_reverse_sort);
89243
+ }
89244
+
89245
+ } // namespace duckdb
89246
+
89247
+
89248
+
89249
+
89250
+
89251
+
89252
+
89253
+
88871
89254
  namespace duckdb {
88872
89255
 
88873
89256
  static void ListValueFunction(DataChunk &args, ExpressionState &state, Vector &result) {
@@ -90762,6 +91145,7 @@ void BuiltinFunctions::RegisterNestedFunctions() {
90762
91145
  Register<ListAggregateFun>();
90763
91146
  Register<ListValueFun>();
90764
91147
  Register<ListExtractFun>();
91148
+ Register<ListSortFun>();
90765
91149
  Register<ListRangeFun>();
90766
91150
  Register<ListFlattenFun>();
90767
91151
  Register<MapFun>();
@@ -121858,6 +122242,18 @@ string Relation::RenderWhitespace(idx_t depth) {
121858
122242
  return string(depth * 2, ' ');
121859
122243
  }
121860
122244
 
122245
+ vector<shared_ptr<ExternalDependency>> Relation::GetAllDependencies() {
122246
+ vector<shared_ptr<ExternalDependency>> all_dependencies;
122247
+ Relation *cur = this;
122248
+ while (cur) {
122249
+ if (cur->extra_dependencies) {
122250
+ all_dependencies.push_back(cur->extra_dependencies);
122251
+ }
122252
+ cur = ChildRelation();
122253
+ }
122254
+ return all_dependencies;
122255
+ }
122256
+
121861
122257
  } // namespace duckdb
121862
122258
 
121863
122259
 
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 "b6daef25a"
15
- #define DUCKDB_VERSION "v0.3.5-dev26"
14
+ #define DUCKDB_SOURCE_ID "c8e258878"
15
+ #define DUCKDB_VERSION "v0.3.5-dev54"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -17214,6 +17214,27 @@ public:
17214
17214
 
17215
17215
  } // namespace duckdb
17216
17216
 
17217
+ //===----------------------------------------------------------------------===//
17218
+ // DuckDB
17219
+ //
17220
+ // duckdb/main/external_dependencies.hpp
17221
+ //
17222
+ //
17223
+ //===----------------------------------------------------------------------===//
17224
+
17225
+
17226
+
17227
+ namespace duckdb {
17228
+
17229
+ enum ExternalDependenciesType { PYTHON_DEPENDENCY };
17230
+ class ExternalDependency {
17231
+ public:
17232
+ explicit ExternalDependency(ExternalDependenciesType type_p) : type(type_p) {};
17233
+ virtual ~ExternalDependency() {};
17234
+ ExternalDependenciesType type;
17235
+ };
17236
+
17237
+ } // namespace duckdb
17217
17238
 
17218
17239
  namespace duckdb {
17219
17240
  class Appender;
@@ -17255,6 +17276,8 @@ public:
17255
17276
  TransactionContext transaction;
17256
17277
  //! Whether or not the query is interrupted
17257
17278
  atomic<bool> interrupted;
17279
+ //! External Objects (e.g., Python objects) that views depend of
17280
+ unordered_map<string, vector<shared_ptr<ExternalDependency>>> external_dependencies;
17258
17281
 
17259
17282
  unique_ptr<SchemaCatalogEntry> temporary_objects;
17260
17283
  unordered_map<string, shared_ptr<PreparedStatementData>> prepared_statements;
@@ -17472,6 +17495,7 @@ private:
17472
17495
  } // namespace duckdb
17473
17496
 
17474
17497
 
17498
+
17475
17499
  #include <memory>
17476
17500
 
17477
17501
  namespace duckdb {
@@ -17483,8 +17507,6 @@ class LogicalOperator;
17483
17507
  class QueryNode;
17484
17508
  class TableRef;
17485
17509
 
17486
- class ExtraDependencies {};
17487
-
17488
17510
  class Relation : public std::enable_shared_from_this<Relation> {
17489
17511
  public:
17490
17512
  DUCKDB_API Relation(const std::shared_ptr<ClientContext> &context, RelationType type)
@@ -17499,7 +17521,7 @@ public:
17499
17521
 
17500
17522
  RelationType type;
17501
17523
 
17502
- unique_ptr<ExtraDependencies> extra_dependencies;
17524
+ shared_ptr<ExternalDependency> extra_dependencies;
17503
17525
 
17504
17526
  public:
17505
17527
  DUCKDB_API virtual const vector<ColumnDefinition> &Columns() = 0;
@@ -17599,6 +17621,7 @@ public:
17599
17621
  DUCKDB_API virtual Relation *ChildRelation() {
17600
17622
  return nullptr;
17601
17623
  }
17624
+ DUCKDB_API vector<shared_ptr<ExternalDependency>> GetAllDependencies();
17602
17625
 
17603
17626
  protected:
17604
17627
  DUCKDB_API string RenderWhitespace(idx_t depth);