duckdb 0.2.10-dev320.0 → 0.2.10-dev331.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.2.10-dev320.0",
4
+ "version": "0.2.10-dev331.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -18182,6 +18182,10 @@ FileSystem &FileSystem::GetFileSystem(ClientContext &context) {
18182
18182
  return *context.db->config.file_system;
18183
18183
  }
18184
18184
 
18185
+ FileOpener *FileSystem::GetFileOpener(ClientContext &context) {
18186
+ return context.file_opener.get();
18187
+ }
18188
+
18185
18189
  #ifndef _WIN32
18186
18190
  string FileSystem::PathSeparator() {
18187
18191
  return "/";
@@ -18283,7 +18287,7 @@ string FileSystem::GetHomeDirectory() {
18283
18287
 
18284
18288
  // LCOV_EXCL_START
18285
18289
  unique_ptr<FileHandle> FileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock,
18286
- FileCompressionType compression) {
18290
+ FileCompressionType compression, FileOpener *opener) {
18287
18291
  throw NotImplementedException("%s: OpenFile is not implemented!", GetName());
18288
18292
  }
18289
18293
 
@@ -20215,7 +20219,8 @@ namespace duckdb {
20215
20219
  class LocalFileSystem : public FileSystem {
20216
20220
  public:
20217
20221
  unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK,
20218
- FileCompressionType compression = FileCompressionType::UNCOMPRESSED) override;
20222
+ FileCompressionType compression = FileCompressionType::UNCOMPRESSED,
20223
+ FileOpener *opener = nullptr) override;
20219
20224
 
20220
20225
  //! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is
20221
20226
  //! equivalent to calling SetFilePointer(location) followed by calling Read().
@@ -20363,7 +20368,7 @@ public:
20363
20368
  };
20364
20369
 
20365
20370
  unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type,
20366
- FileCompressionType compression) {
20371
+ FileCompressionType compression, FileOpener *opener) {
20367
20372
  if (compression != FileCompressionType::UNCOMPRESSED) {
20368
20373
  throw NotImplementedException("Unsupported compression type for default file system");
20369
20374
  }
@@ -20721,7 +20726,7 @@ public:
20721
20726
  };
20722
20727
 
20723
20728
  unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type,
20724
- FileCompressionType compression) {
20729
+ FileCompressionType compression, FileOpener *opener) {
20725
20730
  if (compression != FileCompressionType::UNCOMPRESSED) {
20726
20731
  throw NotImplementedException("Unsupported compression type for default file system");
20727
20732
  }
@@ -28380,7 +28385,7 @@ namespace duckdb {
28380
28385
 
28381
28386
  class BufferedFileReader : public Deserializer {
28382
28387
  public:
28383
- BufferedFileReader(FileSystem &fs, const char *path);
28388
+ BufferedFileReader(FileSystem &fs, const char *path, FileOpener *opener = nullptr);
28384
28389
 
28385
28390
  FileSystem &fs;
28386
28391
  unique_ptr<data_t[]> data;
@@ -28412,9 +28417,10 @@ private:
28412
28417
 
28413
28418
  namespace duckdb {
28414
28419
 
28415
- BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path)
28420
+ BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path, FileOpener *opener)
28416
28421
  : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), read_data(0), total_read(0) {
28417
- handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ, FileLockType::READ_LOCK);
28422
+ handle =
28423
+ fs.OpenFile(path, FileFlags::FILE_FLAGS_READ, FileLockType::READ_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
28418
28424
  file_size = fs.GetFileSize(*handle);
28419
28425
  }
28420
28426
 
@@ -28467,9 +28473,12 @@ bool BufferedFileReader::Finished() {
28467
28473
 
28468
28474
  namespace duckdb {
28469
28475
 
28470
- BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags)
28476
+ // Remove this when we switch C++17: https://stackoverflow.com/a/53350948
28477
+ constexpr uint8_t BufferedFileWriter::DEFAULT_OPEN_FLAGS;
28478
+
28479
+ BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags, FileOpener *opener)
28471
28480
  : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), total_written(0) {
28472
- handle = fs.OpenFile(path, open_flags, FileLockType::WRITE_LOCK);
28481
+ handle = fs.OpenFile(path, open_flags, FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
28473
28482
  }
28474
28483
 
28475
28484
  int64_t BufferedFileWriter::GetFileSize() {
@@ -45310,7 +45319,8 @@ public:
45310
45319
  VirtualFileSystem();
45311
45320
 
45312
45321
  unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK,
45313
- FileCompressionType compression = FileCompressionType::UNCOMPRESSED) override;
45322
+ FileCompressionType compression = FileCompressionType::UNCOMPRESSED,
45323
+ FileOpener *opener = nullptr) override;
45314
45324
 
45315
45325
  void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) override {
45316
45326
  handle.file_system.Read(handle, buffer, nr_bytes, location);
@@ -45414,7 +45424,7 @@ VirtualFileSystem::VirtualFileSystem() : default_fs(FileSystem::CreateLocal()) {
45414
45424
  }
45415
45425
 
45416
45426
  unique_ptr<FileHandle> VirtualFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock,
45417
- FileCompressionType compression) {
45427
+ FileCompressionType compression, FileOpener *opener) {
45418
45428
  if (compression == FileCompressionType::AUTO_DETECT) {
45419
45429
  // auto detect compression settings based on file name
45420
45430
  auto lower_path = StringUtil::Lower(path);
@@ -45425,7 +45435,7 @@ unique_ptr<FileHandle> VirtualFileSystem::OpenFile(const string &path, uint8_t f
45425
45435
  }
45426
45436
  }
45427
45437
  // open the base file handle
45428
- auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, FileCompressionType::UNCOMPRESSED);
45438
+ auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, FileCompressionType::UNCOMPRESSED, opener);
45429
45439
  if (file_handle->GetType() == FileType::FILE_TYPE_FIFO) {
45430
45440
  file_handle = PipeFileSystem::OpenPipe(move(file_handle));
45431
45441
  } else if (compression != FileCompressionType::UNCOMPRESSED) {
@@ -59462,6 +59472,7 @@ struct CopyInfo;
59462
59472
  struct FileHandle;
59463
59473
  struct StrpTimeFormat;
59464
59474
 
59475
+ class FileOpener;
59465
59476
  class FileSystem;
59466
59477
 
59467
59478
  //! The shifts array allows for linear searching of multi-byte values. For each position, it determines the next
@@ -59562,10 +59573,11 @@ public:
59562
59573
  BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options,
59563
59574
  const vector<LogicalType> &requested_types = vector<LogicalType>());
59564
59575
 
59565
- BufferedCSVReader(FileSystem &fs, BufferedCSVReaderOptions options,
59576
+ BufferedCSVReader(FileSystem &fs, FileOpener *opener, BufferedCSVReaderOptions options,
59566
59577
  const vector<LogicalType> &requested_types = vector<LogicalType>());
59567
59578
 
59568
59579
  FileSystem &fs;
59580
+ FileOpener *opener;
59569
59581
  BufferedCSVReaderOptions options;
59570
59582
  vector<LogicalType> sql_types;
59571
59583
  vector<string> col_names;
@@ -59798,16 +59810,17 @@ TextSearchShiftArray::TextSearchShiftArray(string search_term) : length(search_t
59798
59810
  }
59799
59811
  }
59800
59812
 
59801
- BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, BufferedCSVReaderOptions options_p,
59813
+ BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, FileOpener *opener_p, BufferedCSVReaderOptions options_p,
59802
59814
  const vector<LogicalType> &requested_types)
59803
- : fs(fs_p), options(move(options_p)), buffer_size(0), position(0), start(0) {
59815
+ : fs(fs_p), opener(opener_p), options(move(options_p)), buffer_size(0), position(0), start(0) {
59804
59816
  file_handle = OpenCSV(options);
59805
59817
  Initialize(requested_types);
59806
59818
  }
59807
59819
 
59808
59820
  BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p,
59809
59821
  const vector<LogicalType> &requested_types)
59810
- : BufferedCSVReader(FileSystem::GetFileSystem(context), move(options_p), requested_types) {
59822
+ : BufferedCSVReader(FileSystem::GetFileSystem(context), FileSystem::GetFileOpener(context), move(options_p),
59823
+ requested_types) {
59811
59824
  }
59812
59825
 
59813
59826
  void BufferedCSVReader::Initialize(const vector<LogicalType> &requested_types) {
@@ -59839,8 +59852,8 @@ unique_ptr<FileHandle> BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions
59839
59852
  this->compression = FileCompressionType::GZIP;
59840
59853
  }
59841
59854
 
59842
- auto result =
59843
- fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, this->compression);
59855
+ auto result = fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK,
59856
+ this->compression, this->opener);
59844
59857
  plain_file_source = result->OnDiskFile() && result->CanSeek();
59845
59858
  file_size = result->GetFileSize();
59846
59859
  return result;
@@ -61584,10 +61597,10 @@ static void WriteCatalogEntries(stringstream &ss, vector<CatalogEntry *> &entrie
61584
61597
  ss << std::endl;
61585
61598
  }
61586
61599
 
61587
- static void WriteStringStreamToFile(FileSystem &fs, stringstream &ss, const string &path) {
61600
+ static void WriteStringStreamToFile(FileSystem &fs, FileOpener *opener, stringstream &ss, const string &path) {
61588
61601
  auto ss_string = ss.str();
61589
61602
  auto handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW,
61590
- FileLockType::WRITE_LOCK);
61603
+ FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
61591
61604
  fs.Write(*handle, (void *)ss_string.c_str(), ss_string.size());
61592
61605
  handle.reset();
61593
61606
  }
@@ -61641,6 +61654,7 @@ static void WriteCopyStatement(FileSystem &fs, stringstream &ss, TableCatalogEnt
61641
61654
  void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chunk, PhysicalOperatorState *state) const {
61642
61655
  auto &ccontext = context.client;
61643
61656
  auto &fs = FileSystem::GetFileSystem(ccontext);
61657
+ auto *opener = FileSystem::GetFileOpener(ccontext);
61644
61658
 
61645
61659
  // gather all catalog types to export
61646
61660
  vector<CatalogEntry *> schemas;
@@ -61680,7 +61694,7 @@ void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chun
61680
61694
  WriteCatalogEntries(ss, views);
61681
61695
  WriteCatalogEntries(ss, indexes);
61682
61696
 
61683
- WriteStringStreamToFile(fs, ss, fs.JoinPath(info->file_path, "schema.sql"));
61697
+ WriteStringStreamToFile(fs, opener, ss, fs.JoinPath(info->file_path, "schema.sql"));
61684
61698
 
61685
61699
  // write the load.sql file
61686
61700
  // for every table, we write COPY INTO statement with the specified options
@@ -61690,7 +61704,7 @@ void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chun
61690
61704
  auto exported_table_info = kv.second;
61691
61705
  WriteCopyStatement(fs, load_ss, table, *info, exported_table_info, function);
61692
61706
  }
61693
- WriteStringStreamToFile(fs, load_ss, fs.JoinPath(info->file_path, "load.sql"));
61707
+ WriteStringStreamToFile(fs, opener, load_ss, fs.JoinPath(info->file_path, "load.sql"));
61694
61708
  state->finished = true;
61695
61709
  }
61696
61710
 
@@ -76035,7 +76049,9 @@ static void PragmaLogQueryPath(ClientContext &context, const FunctionParameters
76035
76049
  // empty path: clean up query writer
76036
76050
  context.log_query_writer = nullptr;
76037
76051
  } else {
76038
- context.log_query_writer = make_unique<BufferedFileWriter>(FileSystem::GetFileSystem(context), str_val);
76052
+ context.log_query_writer =
76053
+ make_unique<BufferedFileWriter>(FileSystem::GetFileSystem(context), str_val,
76054
+ BufferedFileWriter::DEFAULT_OPEN_FLAGS, context.file_opener.get());
76039
76055
  }
76040
76056
  }
76041
76057
 
@@ -76243,12 +76259,15 @@ string PragmaVersion(ClientContext &context, const FunctionParameters &parameter
76243
76259
 
76244
76260
  string PragmaImportDatabase(ClientContext &context, const FunctionParameters &parameters) {
76245
76261
  auto &fs = FileSystem::GetFileSystem(context);
76262
+ auto *opener = FileSystem::GetFileOpener(context);
76263
+
76246
76264
  string query;
76247
76265
  // read the "shema.sql" and "load.sql" files
76248
76266
  vector<string> files = {"schema.sql", "load.sql"};
76249
76267
  for (auto &file : files) {
76250
76268
  auto file_path = fs.JoinPath(parameters.values[0].ToString(), file);
76251
- auto handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_READ);
76269
+ auto handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_READ, FileSystem::DEFAULT_LOCK,
76270
+ FileSystem::DEFAULT_COMPRESSION, opener);
76252
76271
  auto fsize = fs.GetFileSize(*handle);
76253
76272
  auto buffer = unique_ptr<char[]>(new char[fsize]);
76254
76273
  fs.Read(*handle, buffer.get(), fsize);
@@ -91223,9 +91242,9 @@ struct LocalReadCSVData : public LocalFunctionData {
91223
91242
  };
91224
91243
 
91225
91244
  struct GlobalWriteCSVData : public GlobalFunctionData {
91226
- GlobalWriteCSVData(FileSystem &fs, const string &file_path) : fs(fs) {
91245
+ GlobalWriteCSVData(FileSystem &fs, const string &file_path, FileOpener *opener) : fs(fs) {
91227
91246
  handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW,
91228
- FileLockType::WRITE_LOCK);
91247
+ FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
91229
91248
  }
91230
91249
 
91231
91250
  void WriteData(const_data_ptr_t data, idx_t size) {
@@ -91255,7 +91274,8 @@ static unique_ptr<LocalFunctionData> WriteCSVInitializeLocal(ClientContext &cont
91255
91274
  static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data) {
91256
91275
  auto &csv_data = (WriteCSVData &)bind_data;
91257
91276
  auto &options = csv_data.options;
91258
- auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0]);
91277
+ auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0],
91278
+ FileSystem::GetFileOpener(context));
91259
91279
 
91260
91280
  if (options.header) {
91261
91281
  BufferedSerializer serializer;
@@ -96978,6 +96998,61 @@ bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row) {
96978
96998
  return result->columns[col].nullmask[row];
96979
96999
  }
96980
97000
 
97001
+ //===----------------------------------------------------------------------===//
97002
+ // DuckDB
97003
+ //
97004
+ // duckdb/main/client_context_file_opener.hpp
97005
+ //
97006
+ //
97007
+ //===----------------------------------------------------------------------===//
97008
+
97009
+
97010
+
97011
+ //===----------------------------------------------------------------------===//
97012
+ // DuckDB
97013
+ //
97014
+ // duckdb/common/file_opener.hpp
97015
+ //
97016
+ //
97017
+ //===----------------------------------------------------------------------===//
97018
+
97019
+
97020
+
97021
+
97022
+
97023
+ namespace duckdb {
97024
+
97025
+ class Value;
97026
+
97027
+ //! Abstact type that provide client-spcific context to FileSystem.
97028
+ class FileOpener {
97029
+ public:
97030
+ virtual ~FileOpener() {};
97031
+
97032
+ virtual bool TryGetCurrentSetting(const string &key, Value &result) = 0;
97033
+ };
97034
+
97035
+ } // namespace duckdb
97036
+
97037
+ namespace duckdb {
97038
+
97039
+ class ClientContext;
97040
+
97041
+ //! ClientContext-specific FileOpener implemenation.
97042
+ //! This object is owned by ClientContext and never outlives it.
97043
+ class ClientContextFileOpener : public FileOpener {
97044
+ public:
97045
+ explicit ClientContextFileOpener(ClientContext &context_p) : context(context_p) {
97046
+ }
97047
+
97048
+ bool TryGetCurrentSetting(const string &key, Value &result) override;
97049
+
97050
+ private:
97051
+ ClientContext &context;
97052
+ };
97053
+
97054
+ } // namespace duckdb
97055
+
96981
97056
 
96982
97057
 
96983
97058
 
@@ -97428,7 +97503,8 @@ private:
97428
97503
  ClientContext::ClientContext(shared_ptr<DatabaseInstance> database)
97429
97504
  : profiler(make_unique<QueryProfiler>()), query_profiler_history(make_unique<QueryProfilerHistory>()),
97430
97505
  db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), executor(*this),
97431
- temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)), open_result(nullptr) {
97506
+ temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
97507
+ file_opener(make_unique<ClientContextFileOpener>(*this)), open_result(nullptr) {
97432
97508
  std::random_device rd;
97433
97509
  random_engine.seed(rd());
97434
97510
 
@@ -97895,7 +97971,8 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) {
97895
97971
  #ifdef DUCKDB_FORCE_QUERY_LOG
97896
97972
  try {
97897
97973
  string log_path(DUCKDB_FORCE_QUERY_LOG);
97898
- log_query_writer = make_unique<BufferedFileWriter>(FileSystem::GetFileSystem(*this), log_path);
97974
+ log_query_writer = make_unique<BufferedFileWriter>(
97975
+ FileSystem::GetFileSystem(*this), log_path, BufferedFileWriter::DEFAULT_OPEN_FLAGS, file_opener.get());
97899
97976
  } catch (...) {
97900
97977
  return;
97901
97978
  }
@@ -98315,6 +98392,16 @@ bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result)
98315
98392
 
98316
98393
 
98317
98394
 
98395
+ namespace duckdb {
98396
+
98397
+ bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &result) {
98398
+ return context.TryGetCurrentSetting(key, result);
98399
+ }
98400
+
98401
+ } // namespace duckdb
98402
+
98403
+
98404
+
98318
98405
  namespace duckdb {
98319
98406
 
98320
98407
  static ConfigurationOption internal_options[] = {
@@ -145876,6 +145963,29 @@ idx_t LocalStorage::Delete(DataTable *table, Vector &row_ids, idx_t count) {
145876
145963
  idx_t chunk_idx = GetChunk(row_ids);
145877
145964
  D_ASSERT(chunk_idx < storage->collection.ChunkCount());
145878
145965
 
145966
+ // delete from unique indices (if any)
145967
+ if (!storage->indexes.empty()) {
145968
+ // Index::Delete assumes that ALL rows are being deleted, so
145969
+ // Slice out the rows that are being deleted from the storage Chunk
145970
+ auto &chunk = storage->collection.GetChunk(chunk_idx);
145971
+
145972
+ VectorData row_ids_data;
145973
+ row_ids.Orrify(count, row_ids_data);
145974
+ auto row_identifiers = (const row_t *)row_ids_data.data;
145975
+ SelectionVector sel(count);
145976
+ for (idx_t i = 0; i < count; ++i) {
145977
+ const auto idx = row_ids_data.sel->get_index(i);
145978
+ sel.set_index(i, row_identifiers[idx] - MAX_ROW_ID);
145979
+ }
145980
+
145981
+ DataChunk deleted;
145982
+ deleted.InitializeEmpty(chunk.GetTypes());
145983
+ deleted.Slice(chunk, sel, count);
145984
+ for (auto &index : storage->indexes) {
145985
+ index->Delete(deleted, row_ids);
145986
+ }
145987
+ }
145988
+
145879
145989
  // get a pointer to the deleted entries for this chunk
145880
145990
  bool *deleted;
145881
145991
  auto entry = storage->deleted_entries.find(chunk_idx);
package/src/duckdb.hpp CHANGED
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
10
10
 
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
- #define DUCKDB_SOURCE_ID "153b23b3a"
14
- #define DUCKDB_VERSION "0.2.10-dev320"
13
+ #define DUCKDB_SOURCE_ID "7dd852e1d"
14
+ #define DUCKDB_VERSION "0.2.10-dev331"
15
15
  //===----------------------------------------------------------------------===//
16
16
  // DuckDB
17
17
  //
@@ -1710,6 +1710,7 @@ enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZ
1710
1710
  namespace duckdb {
1711
1711
  class ClientContext;
1712
1712
  class DatabaseInstance;
1713
+ class FileOpener;
1713
1714
  class FileSystem;
1714
1715
 
1715
1716
  enum class FileType {
@@ -1787,12 +1788,15 @@ public:
1787
1788
  }
1788
1789
 
1789
1790
  public:
1791
+ static constexpr FileLockType DEFAULT_LOCK = FileLockType::NO_LOCK;
1792
+ static constexpr FileCompressionType DEFAULT_COMPRESSION = FileCompressionType::UNCOMPRESSED;
1790
1793
  static FileSystem &GetFileSystem(ClientContext &context);
1791
1794
  static FileSystem &GetFileSystem(DatabaseInstance &db);
1795
+ static FileOpener *GetFileOpener(ClientContext &context);
1792
1796
 
1793
- virtual unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags,
1794
- FileLockType lock = FileLockType::NO_LOCK,
1795
- FileCompressionType compression = FileCompressionType::UNCOMPRESSED);
1797
+ virtual unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = DEFAULT_LOCK,
1798
+ FileCompressionType compression = DEFAULT_COMPRESSION,
1799
+ FileOpener *opener = nullptr);
1796
1800
 
1797
1801
  //! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is
1798
1802
  //! equivalent to calling SetFilePointer(location) followed by calling Read().
@@ -1889,10 +1893,12 @@ namespace duckdb {
1889
1893
 
1890
1894
  class BufferedFileWriter : public Serializer {
1891
1895
  public:
1896
+ static constexpr uint8_t DEFAULT_OPEN_FLAGS = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE;
1897
+
1892
1898
  //! Serializes to a buffer allocated by the serializer, will expand when
1893
1899
  //! writing past the initial threshold
1894
- BufferedFileWriter(FileSystem &fs, const string &path,
1895
- uint8_t open_flags = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE);
1900
+ BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags = DEFAULT_OPEN_FLAGS,
1901
+ FileOpener *opener = nullptr);
1896
1902
 
1897
1903
  FileSystem &fs;
1898
1904
  unique_ptr<data_t[]> data;
@@ -13058,6 +13064,7 @@ class Appender;
13058
13064
  class Catalog;
13059
13065
  class ChunkCollection;
13060
13066
  class DatabaseInstance;
13067
+ class FileOpener;
13061
13068
  class LogicalOperator;
13062
13069
  class PreparedStatementData;
13063
13070
  class Relation;
@@ -13129,6 +13136,8 @@ public:
13129
13136
  //! The schema search path, in order by which entries are searched if no schema entry is provided
13130
13137
  vector<string> catalog_search_path = {TEMP_SCHEMA, DEFAULT_SCHEMA, "pg_catalog"};
13131
13138
 
13139
+ unique_ptr<FileOpener> file_opener;
13140
+
13132
13141
  public:
13133
13142
  DUCKDB_API Transaction &ActiveTransaction() {
13134
13143
  return transaction.ActiveTransaction();