duckdb 0.10.3-dev8.0 → 1.0.1-dev15.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 (55) hide show
  1. package/.github/workflows/Electron.yml +293 -0
  2. package/.github/workflows/HighPriorityIssues.yml +1 -1
  3. package/.github/workflows/NodeJS.yml +3 -3
  4. package/package.json +1 -1
  5. package/scripts/electron-versions.json +64 -0
  6. package/scripts/node_build.sh +12 -0
  7. package/scripts/node_build_win.sh +12 -0
  8. package/src/duckdb/extension/parquet/parquet_extension.cpp +7 -1
  9. package/src/duckdb/src/catalog/dependency_manager.cpp +4 -0
  10. package/src/duckdb/src/common/enum_util.cpp +29 -0
  11. package/src/duckdb/src/common/error_data.cpp +5 -2
  12. package/src/duckdb/src/common/local_file_system.cpp +5 -0
  13. package/src/duckdb/src/common/multi_file_reader.cpp +3 -0
  14. package/src/duckdb/src/common/printer.cpp +1 -1
  15. package/src/duckdb/src/common/string_util.cpp +1 -1
  16. package/src/duckdb/src/core_functions/aggregate/holistic/approximate_quantile.cpp +14 -5
  17. package/src/duckdb/src/core_functions/aggregate/holistic/quantile.cpp +11 -3
  18. package/src/duckdb/src/execution/operator/helper/physical_load.cpp +2 -2
  19. package/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp +3 -1
  20. package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +13 -10
  21. package/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp +2 -2
  22. package/src/duckdb/src/function/table/system/duckdb_extensions.cpp +2 -3
  23. package/src/duckdb/src/function/table/version/pragma_version.cpp +5 -5
  24. package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -0
  25. package/src/duckdb/src/include/duckdb/common/enums/copy_overwrite_mode.hpp +18 -0
  26. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +1 -0
  27. package/src/duckdb/src/include/duckdb/common/shared_ptr.hpp +3 -3
  28. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp +2 -1
  29. package/src/duckdb/src/include/duckdb/main/attached_database.hpp +6 -0
  30. package/src/duckdb/src/include/duckdb/main/config.hpp +4 -0
  31. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +6 -6
  32. package/src/duckdb/src/include/duckdb/main/settings.hpp +20 -0
  33. package/src/duckdb/src/include/duckdb/planner/operator/logical_comparison_join.hpp +7 -7
  34. package/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp +2 -1
  35. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  36. package/src/duckdb/src/include/duckdb.h +126 -4
  37. package/src/duckdb/src/main/attached_database.cpp +7 -6
  38. package/src/duckdb/src/main/capi/stream-c.cpp +17 -8
  39. package/src/duckdb/src/main/capi/table_function-c.cpp +11 -7
  40. package/src/duckdb/src/main/config.cpp +2 -0
  41. package/src/duckdb/src/main/extension/extension_helper.cpp +3 -25
  42. package/src/duckdb/src/main/extension/extension_install.cpp +10 -6
  43. package/src/duckdb/src/main/settings/settings.cpp +32 -0
  44. package/src/duckdb/src/optimizer/pushdown/pushdown_cross_product.cpp +3 -3
  45. package/src/duckdb/src/optimizer/rule/move_constants.cpp +4 -0
  46. package/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp +2 -2
  47. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +17 -4
  48. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +26 -15
  49. package/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +29 -11
  50. package/src/duckdb/src/planner/operator/logical_copy_to_file.cpp +3 -3
  51. package/src/duckdb/src/storage/storage_manager.cpp +17 -8
  52. package/test/replacement_scan.test.ts +2 -0
  53. /package/src/duckdb/src/include/duckdb/common/{enable_shared_from_this.ipp → enable_shared_from_this_ipp.hpp} +0 -0
  54. /package/src/duckdb/src/include/duckdb/common/{shared_ptr.ipp → shared_ptr_ipp.hpp} +0 -0
  55. /package/src/duckdb/src/include/duckdb/common/{weak_ptr.ipp → weak_ptr_ipp.hpp} +0 -0
@@ -136,18 +136,21 @@ bool ExtensionHelper::CreateSuggestions(const string &extension_name, string &me
136
136
  unique_ptr<ExtensionInstallInfo> ExtensionHelper::InstallExtension(DBConfig &config, FileSystem &fs,
137
137
  const string &extension, bool force_install,
138
138
  optional_ptr<ExtensionRepository> repository,
139
+ bool throw_on_origin_mismatch,
139
140
  const string &version) {
140
141
  #ifdef WASM_LOADABLE_EXTENSIONS
141
142
  // Install is currently a no-op
142
143
  return nullptr;
143
144
  #endif
144
145
  string local_path = ExtensionDirectory(config, fs);
145
- return InstallExtensionInternal(config, fs, local_path, extension, force_install, version, repository);
146
+ return InstallExtensionInternal(config, fs, local_path, extension, force_install, throw_on_origin_mismatch, version,
147
+ repository);
146
148
  }
147
149
 
148
150
  unique_ptr<ExtensionInstallInfo> ExtensionHelper::InstallExtension(ClientContext &context, const string &extension,
149
151
  bool force_install,
150
152
  optional_ptr<ExtensionRepository> repository,
153
+ bool throw_on_origin_mismatch,
151
154
  const string &version) {
152
155
  #ifdef WASM_LOADABLE_EXTENSIONS
153
156
  // Install is currently a no-op
@@ -158,8 +161,8 @@ unique_ptr<ExtensionInstallInfo> ExtensionHelper::InstallExtension(ClientContext
158
161
  string local_path = ExtensionDirectory(context);
159
162
  optional_ptr<HTTPLogger> http_logger =
160
163
  ClientConfig::GetConfig(context).enable_http_logging ? context.client_data->http_logger.get() : nullptr;
161
- return InstallExtensionInternal(db_config, fs, local_path, extension, force_install, version, repository,
162
- http_logger, context);
164
+ return InstallExtensionInternal(db_config, fs, local_path, extension, force_install, throw_on_origin_mismatch,
165
+ version, repository, http_logger, context);
163
166
  }
164
167
 
165
168
  unsafe_unique_array<data_t> ReadExtensionFileFromDisk(FileSystem &fs, const string &path, idx_t &file_size) {
@@ -445,8 +448,8 @@ static void ThrowErrorOnMismatchingExtensionOrigin(FileSystem &fs, const string
445
448
 
446
449
  unique_ptr<ExtensionInstallInfo>
447
450
  ExtensionHelper::InstallExtensionInternal(DBConfig &config, FileSystem &fs, const string &local_path,
448
- const string &extension, bool force_install, const string &version,
449
- optional_ptr<ExtensionRepository> repository,
451
+ const string &extension, bool force_install, bool throw_on_origin_mismatch,
452
+ const string &version, optional_ptr<ExtensionRepository> repository,
450
453
  optional_ptr<HTTPLogger> http_logger, optional_ptr<ClientContext> context) {
451
454
  #ifdef DUCKDB_DISABLE_EXTENSION_LOAD
452
455
  throw PermissionException("Installing external extensions is disabled through a compile time flag");
@@ -461,7 +464,8 @@ ExtensionHelper::InstallExtensionInternal(DBConfig &config, FileSystem &fs, cons
461
464
 
462
465
  if (fs.FileExists(local_extension_path) && !force_install) {
463
466
  // File exists: throw error if origin mismatches
464
- if (!config.options.allow_extensions_metadata_mismatch && fs.FileExists(local_extension_path + ".info")) {
467
+ if (throw_on_origin_mismatch && !config.options.allow_extensions_metadata_mismatch &&
468
+ fs.FileExists(local_extension_path + ".info")) {
465
469
  ThrowErrorOnMismatchingExtensionOrigin(fs, local_extension_path, extension_name, extension, repository);
466
470
  }
467
471
 
@@ -437,6 +437,38 @@ Value EnableExternalAccessSetting::GetSetting(const ClientContext &context) {
437
437
  return Value::BOOLEAN(config.options.enable_external_access);
438
438
  }
439
439
 
440
+ //===--------------------------------------------------------------------===//
441
+ // Enable Macro Dependencies
442
+ //===--------------------------------------------------------------------===//
443
+ void EnableMacrosDependencies::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
444
+ config.options.enable_macro_dependencies = input.GetValue<bool>();
445
+ }
446
+
447
+ void EnableMacrosDependencies::ResetGlobal(DatabaseInstance *db, DBConfig &config) {
448
+ config.options.enable_macro_dependencies = DBConfig().options.enable_macro_dependencies;
449
+ }
450
+
451
+ Value EnableMacrosDependencies::GetSetting(const ClientContext &context) {
452
+ auto &config = DBConfig::GetConfig(context);
453
+ return Value::BOOLEAN(config.options.enable_macro_dependencies);
454
+ }
455
+
456
+ //===--------------------------------------------------------------------===//
457
+ // Enable View Dependencies
458
+ //===--------------------------------------------------------------------===//
459
+ void EnableViewDependencies::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
460
+ config.options.enable_view_dependencies = input.GetValue<bool>();
461
+ }
462
+
463
+ void EnableViewDependencies::ResetGlobal(DatabaseInstance *db, DBConfig &config) {
464
+ config.options.enable_view_dependencies = DBConfig().options.enable_view_dependencies;
465
+ }
466
+
467
+ Value EnableViewDependencies::GetSetting(const ClientContext &context) {
468
+ auto &config = DBConfig::GetConfig(context);
469
+ return Value::BOOLEAN(config.options.enable_view_dependencies);
470
+ }
471
+
440
472
  //===--------------------------------------------------------------------===//
441
473
  // Enable FSST Vectors
442
474
  //===--------------------------------------------------------------------===//
@@ -52,9 +52,9 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownCrossProduct(unique_ptr<Logi
52
52
  vector<JoinCondition> conditions;
53
53
  vector<unique_ptr<Expression>> arbitrary_expressions;
54
54
  const auto join_type = JoinType::INNER;
55
- LogicalComparisonJoin::ExtractJoinConditions(GetContext(), join_type, op->children[0], op->children[1],
56
- left_bindings, right_bindings, join_expressions, conditions,
57
- arbitrary_expressions);
55
+ LogicalComparisonJoin::ExtractJoinConditions(GetContext(), join_type, join_ref_type, op->children[0],
56
+ op->children[1], left_bindings, right_bindings, join_expressions,
57
+ conditions, arbitrary_expressions);
58
58
  // create the join from the join conditions
59
59
  return LogicalComparisonJoin::CreateJoin(GetContext(), join_type, join_ref_type, std::move(op->children[0]),
60
60
  std::move(op->children[1]), std::move(conditions),
@@ -41,6 +41,10 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<refe
41
41
  D_ASSERT(arithmetic.return_type.IsIntegral());
42
42
  D_ASSERT(arithmetic.children[0]->return_type.IsIntegral());
43
43
  if (inner_constant.value.IsNull() || outer_constant.value.IsNull()) {
44
+ if (comparison.type == ExpressionType::COMPARE_DISTINCT_FROM ||
45
+ comparison.type == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
46
+ return nullptr;
47
+ }
44
48
  return make_uniq<BoundConstantExpression>(Value(comparison.return_type));
45
49
  }
46
50
  auto &constant_type = outer_constant.return_type;
@@ -417,8 +417,8 @@ unique_ptr<LogicalOperator> Binder::PlanLateralJoin(unique_ptr<LogicalOperator>
417
417
  vector<unique_ptr<Expression>> arbitrary_expressions;
418
418
  if (condition) {
419
419
  // extract join conditions, if there are any
420
- LogicalComparisonJoin::ExtractJoinConditions(context, join_type, left, right, std::move(condition), conditions,
421
- arbitrary_expressions);
420
+ LogicalComparisonJoin::ExtractJoinConditions(context, join_type, JoinRefType::REGULAR, left, right,
421
+ std::move(condition), conditions, arbitrary_expressions);
422
422
  }
423
423
 
424
424
  auto perform_delim = PerformDuplicateElimination(*this, correlated);
@@ -55,12 +55,13 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
55
55
  }
56
56
 
57
57
  bool use_tmp_file = true;
58
- bool overwrite_or_ignore = false;
58
+ CopyOverwriteMode overwrite_mode = CopyOverwriteMode::COPY_ERROR_ON_CONFLICT;
59
59
  FilenamePattern filename_pattern;
60
60
  bool user_set_use_tmp_file = false;
61
61
  bool per_thread_output = false;
62
62
  optional_idx file_size_bytes;
63
63
  vector<idx_t> partition_cols;
64
+ bool seen_overwrite_mode = false;
64
65
 
65
66
  CopyFunctionBindInput bind_input(*stmt.info);
66
67
 
@@ -74,8 +75,20 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
74
75
  if (loption == "use_tmp_file") {
75
76
  use_tmp_file = GetBooleanArg(context, option.second);
76
77
  user_set_use_tmp_file = true;
77
- } else if (loption == "overwrite_or_ignore") {
78
- overwrite_or_ignore = GetBooleanArg(context, option.second);
78
+ } else if (loption == "overwrite_or_ignore" || loption == "overwrite") {
79
+ if (seen_overwrite_mode) {
80
+ throw BinderException("Can only set one of OVERWRITE_OR_IGNORE or OVERWRITE");
81
+ }
82
+ seen_overwrite_mode = true;
83
+
84
+ auto boolean = GetBooleanArg(context, option.second);
85
+ if (boolean) {
86
+ if (loption == "overwrite_or_ignore") {
87
+ overwrite_mode = CopyOverwriteMode::COPY_OVERWRITE_OR_IGNORE;
88
+ } else if (loption == "overwrite") {
89
+ overwrite_mode = CopyOverwriteMode::COPY_OVERWRITE;
90
+ }
91
+ }
79
92
  } else if (loption == "filename_pattern") {
80
93
  if (option.second.empty()) {
81
94
  throw IOException("FILENAME_PATTERN cannot be empty");
@@ -146,7 +159,7 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
146
159
  auto copy = make_uniq<LogicalCopyToFile>(copy_function.function, std::move(function_data), std::move(stmt.info));
147
160
  copy->file_path = file_path;
148
161
  copy->use_tmp_file = use_tmp_file;
149
- copy->overwrite_or_ignore = overwrite_or_ignore;
162
+ copy->overwrite_mode = overwrite_mode;
150
163
  copy->filename_pattern = filename_pattern;
151
164
  copy->file_extension = bind_input.file_extension;
152
165
  copy->per_thread_output = per_thread_output;
@@ -145,13 +145,19 @@ void Binder::BindCreateViewInfo(CreateViewInfo &base) {
145
145
  auto view_binder = Binder::CreateBinder(context);
146
146
  auto &dependencies = base.dependencies;
147
147
  auto &catalog = Catalog::GetCatalog(context, base.catalog);
148
- view_binder->SetCatalogLookupCallback([&dependencies, &catalog](CatalogEntry &entry) {
149
- if (&catalog != &entry.ParentCatalog()) {
150
- // Don't register dependencies between catalogs
151
- return;
152
- }
153
- dependencies.AddDependency(entry);
154
- });
148
+
149
+ auto &db_config = DBConfig::GetConfig(context);
150
+ auto should_create_dependencies = db_config.options.enable_view_dependencies;
151
+
152
+ if (should_create_dependencies) {
153
+ view_binder->SetCatalogLookupCallback([&dependencies, &catalog](CatalogEntry &entry) {
154
+ if (&catalog != &entry.ParentCatalog()) {
155
+ // Don't register dependencies between catalogs
156
+ return;
157
+ }
158
+ dependencies.AddDependency(entry);
159
+ });
160
+ }
155
161
  view_binder->can_contain_nulls = true;
156
162
 
157
163
  auto copy = base.query->Copy();
@@ -204,14 +210,19 @@ SchemaCatalogEntry &Binder::BindCreateFunctionInfo(CreateInfo &info) {
204
210
  SelectBinder binder(*this, context, sel_node, group_info);
205
211
  auto &dependencies = base.dependencies;
206
212
  auto &catalog = Catalog::GetCatalog(context, info.catalog);
207
- binder.SetCatalogLookupCallback([&dependencies, &catalog](CatalogEntry &entry) {
208
- if (&catalog != &entry.ParentCatalog()) {
209
- // Don't register any cross-catalog dependencies
210
- return;
211
- }
212
- // Register any catalog entry required to bind the macro function
213
- dependencies.AddDependency(entry);
214
- });
213
+ auto &db_config = DBConfig::GetConfig(context);
214
+ auto should_create_dependencies = db_config.options.enable_macro_dependencies;
215
+
216
+ if (should_create_dependencies) {
217
+ binder.SetCatalogLookupCallback([&dependencies, &catalog](CatalogEntry &entry) {
218
+ if (&catalog != &entry.ParentCatalog()) {
219
+ // Don't register any cross-catalog dependencies
220
+ return;
221
+ }
222
+ // Register any catalog entry required to bind the macro function
223
+ dependencies.AddDependency(entry);
224
+ });
225
+ }
215
226
  error = binder.Bind(expression, 0, false);
216
227
  if (error.HasError()) {
217
228
  error.Throw();
@@ -20,6 +20,26 @@
20
20
 
21
21
  namespace duckdb {
22
22
 
23
+ //! Only use conditions that are valid for the join ref type
24
+ static bool IsJoinTypeCondition(const JoinRefType ref_type, const ExpressionType expr_type) {
25
+ switch (ref_type) {
26
+ case JoinRefType::ASOF:
27
+ switch (expr_type) {
28
+ case ExpressionType::COMPARE_EQUAL:
29
+ case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
30
+ case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
31
+ case ExpressionType::COMPARE_GREATERTHAN:
32
+ case ExpressionType::COMPARE_LESSTHANOREQUALTO:
33
+ case ExpressionType::COMPARE_LESSTHAN:
34
+ return true;
35
+ default:
36
+ return false;
37
+ }
38
+ default:
39
+ return true;
40
+ }
41
+ }
42
+
23
43
  //! Create a JoinCondition from a comparison
24
44
  static bool CreateJoinCondition(Expression &expr, const unordered_set<idx_t> &left_bindings,
25
45
  const unordered_set<idx_t> &right_bindings, vector<JoinCondition> &conditions) {
@@ -47,7 +67,7 @@ static bool CreateJoinCondition(Expression &expr, const unordered_set<idx_t> &le
47
67
  }
48
68
 
49
69
  void LogicalComparisonJoin::ExtractJoinConditions(
50
- ClientContext &context, JoinType type, unique_ptr<LogicalOperator> &left_child,
70
+ ClientContext &context, JoinType type, JoinRefType ref_type, unique_ptr<LogicalOperator> &left_child,
51
71
  unique_ptr<LogicalOperator> &right_child, const unordered_set<idx_t> &left_bindings,
52
72
  const unordered_set<idx_t> &right_bindings, vector<unique_ptr<Expression>> &expressions,
53
73
  vector<JoinCondition> &conditions, vector<unique_ptr<Expression>> &arbitrary_expressions) {
@@ -90,7 +110,8 @@ void LogicalComparisonJoin::ExtractJoinConditions(
90
110
 
91
111
  {
92
112
  // comparison, check if we can create a comparison JoinCondition
93
- if (CreateJoinCondition(*expr, left_bindings, right_bindings, conditions)) {
113
+ if (IsJoinTypeCondition(ref_type, expr->type) &&
114
+ CreateJoinCondition(*expr, left_bindings, right_bindings, conditions)) {
94
115
  // successfully created the join condition
95
116
  continue;
96
117
  }
@@ -99,7 +120,7 @@ void LogicalComparisonJoin::ExtractJoinConditions(
99
120
  }
100
121
  }
101
122
 
102
- void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinType type,
123
+ void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinType type, JoinRefType ref_type,
103
124
  unique_ptr<LogicalOperator> &left_child,
104
125
  unique_ptr<LogicalOperator> &right_child,
105
126
  vector<unique_ptr<Expression>> &expressions,
@@ -108,11 +129,11 @@ void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinTy
108
129
  unordered_set<idx_t> left_bindings, right_bindings;
109
130
  LogicalJoin::GetTableReferences(*left_child, left_bindings);
110
131
  LogicalJoin::GetTableReferences(*right_child, right_bindings);
111
- return ExtractJoinConditions(context, type, left_child, right_child, left_bindings, right_bindings, expressions,
112
- conditions, arbitrary_expressions);
132
+ return ExtractJoinConditions(context, type, ref_type, left_child, right_child, left_bindings, right_bindings,
133
+ expressions, conditions, arbitrary_expressions);
113
134
  }
114
135
 
115
- void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinType type,
136
+ void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinType type, JoinRefType ref_type,
116
137
  unique_ptr<LogicalOperator> &left_child,
117
138
  unique_ptr<LogicalOperator> &right_child,
118
139
  unique_ptr<Expression> condition, vector<JoinCondition> &conditions,
@@ -121,7 +142,7 @@ void LogicalComparisonJoin::ExtractJoinConditions(ClientContext &context, JoinTy
121
142
  vector<unique_ptr<Expression>> expressions;
122
143
  expressions.push_back(std::move(condition));
123
144
  LogicalFilter::SplitPredicates(expressions);
124
- return ExtractJoinConditions(context, type, left_child, right_child, expressions, conditions,
145
+ return ExtractJoinConditions(context, type, ref_type, left_child, right_child, expressions, conditions,
125
146
  arbitrary_expressions);
126
147
  }
127
148
 
@@ -135,9 +156,6 @@ unique_ptr<LogicalOperator> LogicalComparisonJoin::CreateJoin(ClientContext &con
135
156
  bool need_to_consider_arbitrary_expressions = true;
136
157
  switch (reftype) {
137
158
  case JoinRefType::ASOF: {
138
- if (!arbitrary_expressions.empty()) {
139
- throw BinderException("Invalid ASOF JOIN condition");
140
- }
141
159
  need_to_consider_arbitrary_expressions = false;
142
160
  auto asof_idx = conditions.size();
143
161
  for (size_t c = 0; c < conditions.size(); ++c) {
@@ -249,7 +267,7 @@ unique_ptr<LogicalOperator> LogicalComparisonJoin::CreateJoin(ClientContext &con
249
267
  unique_ptr<Expression> condition) {
250
268
  vector<JoinCondition> conditions;
251
269
  vector<unique_ptr<Expression>> arbitrary_expressions;
252
- LogicalComparisonJoin::ExtractJoinConditions(context, type, left_child, right_child, std::move(condition),
270
+ LogicalComparisonJoin::ExtractJoinConditions(context, type, reftype, left_child, right_child, std::move(condition),
253
271
  conditions, arbitrary_expressions);
254
272
  return LogicalComparisonJoin::CreateJoin(context, type, reftype, std::move(left_child), std::move(right_child),
255
273
  std::move(conditions), std::move(arbitrary_expressions));
@@ -13,7 +13,7 @@ void LogicalCopyToFile::Serialize(Serializer &serializer) const {
13
13
  serializer.WriteProperty(200, "file_path", file_path);
14
14
  serializer.WriteProperty(201, "use_tmp_file", use_tmp_file);
15
15
  serializer.WriteProperty(202, "filename_pattern", filename_pattern);
16
- serializer.WriteProperty(203, "overwrite_or_ignore", overwrite_or_ignore);
16
+ serializer.WriteProperty(203, "overwrite_or_ignore", overwrite_mode);
17
17
  serializer.WriteProperty(204, "per_thread_output", per_thread_output);
18
18
  serializer.WriteProperty(205, "partition_output", partition_output);
19
19
  serializer.WriteProperty(206, "partition_columns", partition_columns);
@@ -39,7 +39,7 @@ unique_ptr<LogicalOperator> LogicalCopyToFile::Deserialize(Deserializer &deseria
39
39
  auto file_path = deserializer.ReadProperty<string>(200, "file_path");
40
40
  auto use_tmp_file = deserializer.ReadProperty<bool>(201, "use_tmp_file");
41
41
  auto filename_pattern = deserializer.ReadProperty<FilenamePattern>(202, "filename_pattern");
42
- auto overwrite_or_ignore = deserializer.ReadProperty<bool>(203, "overwrite_or_ignore");
42
+ auto overwrite_mode = deserializer.ReadProperty<CopyOverwriteMode>(203, "overwrite_mode");
43
43
  auto per_thread_output = deserializer.ReadProperty<bool>(204, "per_thread_output");
44
44
  auto partition_output = deserializer.ReadProperty<bool>(205, "partition_output");
45
45
  auto partition_columns = deserializer.ReadProperty<vector<idx_t>>(206, "partition_columns");
@@ -86,7 +86,7 @@ unique_ptr<LogicalOperator> LogicalCopyToFile::Deserialize(Deserializer &deseria
86
86
  result->use_tmp_file = use_tmp_file;
87
87
  result->filename_pattern = filename_pattern;
88
88
  result->file_extension = file_extension;
89
- result->overwrite_or_ignore = overwrite_or_ignore;
89
+ result->overwrite_mode = overwrite_mode;
90
90
  result->per_thread_output = per_thread_output;
91
91
  result->partition_output = partition_output;
92
92
  result->partition_columns = partition_columns;
@@ -1,18 +1,20 @@
1
1
  #include "duckdb/storage/storage_manager.hpp"
2
- #include "duckdb/storage/checkpoint_manager.hpp"
3
- #include "duckdb/storage/in_memory_block_manager.hpp"
4
- #include "duckdb/storage/single_file_block_manager.hpp"
5
- #include "duckdb/storage/object_cache.hpp"
6
2
 
7
3
  #include "duckdb/catalog/catalog.hpp"
8
4
  #include "duckdb/common/file_system.hpp"
9
- #include "duckdb/main/database.hpp"
10
- #include "duckdb/main/client_context.hpp"
11
- #include "duckdb/function/function.hpp"
12
- #include "duckdb/transaction/transaction_manager.hpp"
13
5
  #include "duckdb/common/serializer/buffered_file_reader.hpp"
6
+ #include "duckdb/function/function.hpp"
14
7
  #include "duckdb/main/attached_database.hpp"
8
+ #include "duckdb/main/client_context.hpp"
9
+ #include "duckdb/main/database.hpp"
15
10
  #include "duckdb/main/database_manager.hpp"
11
+ #include "duckdb/storage/checkpoint_manager.hpp"
12
+ #include "duckdb/storage/in_memory_block_manager.hpp"
13
+ #include "duckdb/storage/object_cache.hpp"
14
+ #include "duckdb/storage/single_file_block_manager.hpp"
15
+ #include "duckdb/transaction/transaction_manager.hpp"
16
+
17
+ #include "duckdb/storage/storage_extension.hpp"
16
18
 
17
19
  namespace duckdb {
18
20
 
@@ -283,6 +285,9 @@ void SingleFileStorageManager::CreateCheckpoint(CheckpointOptions options) {
283
285
  if (InMemory() || read_only || !load_complete) {
284
286
  return;
285
287
  }
288
+ if (db.GetStorageExtension()) {
289
+ db.GetStorageExtension()->OnCheckpointStart(db, options);
290
+ }
286
291
  auto &config = DBConfig::Get(db);
287
292
  if (GetWALSize() > 0 || config.options.force_checkpoint || options.action == CheckpointAction::FORCE_CHECKPOINT) {
288
293
  // we only need to checkpoint if there is anything in the WAL
@@ -297,6 +302,10 @@ void SingleFileStorageManager::CreateCheckpoint(CheckpointOptions options) {
297
302
  if (options.wal_action == CheckpointWALAction::DELETE_WAL) {
298
303
  ResetWAL();
299
304
  }
305
+
306
+ if (db.GetStorageExtension()) {
307
+ db.GetStorageExtension()->OnCheckpointEnd(db, options);
308
+ }
300
309
  }
301
310
 
302
311
  DatabaseSize SingleFileStorageManager::GetDatabaseSize() {
@@ -31,6 +31,7 @@ const invalidResultKeys = (table: string) => {
31
31
  } as unknown as sqlite3.ReplacementScanResult;
32
32
  };
33
33
 
34
+ if (process?.platform != 'win32') {
34
35
  describe("replacement scan", () => {
35
36
  var db: sqlite3.Database;
36
37
  describe("without replacement scan", () => {
@@ -142,3 +143,4 @@ describe("replacement scan", () => {
142
143
  });
143
144
  });
144
145
  });
146
+ }