Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/duckdb/src/common/file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ bool FileSystem::TryRemoveFile(const string &filename, optional_ptr<FileOpener>
return false;
}

void FileSystem::RemoveFiles(const vector<string> &filenames, optional_ptr<FileOpener> opener) {
for (const auto &filename : filenames) {
TryRemoveFile(filename, opener);
}
}

void FileSystem::FileSync(FileHandle &handle) {
throw NotImplementedException("%s: FileSync is not implemented!", GetName());
}
Expand Down Expand Up @@ -677,6 +683,10 @@ unique_ptr<FileHandle> FileSystem::OpenCompressedFile(QueryContext context, uniq
throw NotImplementedException("%s: OpenCompressedFile is not implemented!", GetName());
}

bool FileSystem::IsLocalFileSystem() const {
return false;
}

bool FileSystem::OnDiskFile(FileHandle &handle) {
throw NotImplementedException("%s: OnDiskFile is not implemented!", GetName());
}
Expand Down
19 changes: 19 additions & 0 deletions src/duckdb/src/common/virtual_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ VirtualFileSystem::VirtualFileSystem(unique_ptr<FileSystem> &&inner) : default_f
VirtualFileSystem::RegisterSubSystem(FileCompressionType::GZIP, make_uniq<GZipFileSystem>());
}

FileSystem &VirtualFileSystem::GetDefaultFileSystem() {
auto &fs = *default_fs;
if (SubSystemIsDisabled(fs.GetName())) {
throw PermissionException("File system %s has been disabled by configuration", fs.GetName());
}
return fs;
}

unique_ptr<FileHandle> VirtualFileSystem::OpenFileExtended(const OpenFileInfo &file, FileOpenFlags flags,
optional_ptr<FileOpener> opener) {

Expand Down Expand Up @@ -136,6 +144,17 @@ bool VirtualFileSystem::TryRemoveFile(const string &filename, optional_ptr<FileO
return FindFileSystem(filename).TryRemoveFile(filename, opener);
}

void VirtualFileSystem::RemoveFiles(const vector<string> &filenames, optional_ptr<FileOpener> opener) {
reference_map_t<FileSystem, vector<string>> files_by_fs;
for (const auto &filename : filenames) {
auto &fs = FindFileSystem(filename);
files_by_fs[fs].push_back(filename);
}
for (auto &entry : files_by_fs) {
entry.first.get().RemoveFiles(entry.second, opener);
}
}

string VirtualFileSystem::PathSeparator(const string &path) {
return FindFileSystem(path).PathSeparator(path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,7 @@ void CheckDirectory(FileSystem &fs, const string &file_path, CopyOverwriteMode o
return;
}
if (overwrite_mode == CopyOverwriteMode::COPY_OVERWRITE) {
for (auto &file : file_list) {
fs.RemoveFile(file);
}
fs.RemoveFiles(file_list);
} else {
throw IOException("Directory \"%s\" is not empty! Enable OVERWRITE option to overwrite files", file_path);
}
Expand Down
6 changes: 3 additions & 3 deletions src/duckdb/src/function/table/version/pragma_version.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef DUCKDB_PATCH_VERSION
#define DUCKDB_PATCH_VERSION "5-dev98"
#define DUCKDB_PATCH_VERSION "5-dev101"
#endif
#ifndef DUCKDB_MINOR_VERSION
#define DUCKDB_MINOR_VERSION 4
Expand All @@ -8,10 +8,10 @@
#define DUCKDB_MAJOR_VERSION 1
#endif
#ifndef DUCKDB_VERSION
#define DUCKDB_VERSION "v1.4.5-dev98"
#define DUCKDB_VERSION "v1.4.5-dev101"
#endif
#ifndef DUCKDB_SOURCE_ID
#define DUCKDB_SOURCE_ID "3b4213a993"
#define DUCKDB_SOURCE_ID "ca5f01efef"
#endif
#include "duckdb/function/table/system_functions.hpp"
#include "duckdb/main/database.hpp"
Expand Down
6 changes: 6 additions & 0 deletions src/duckdb/src/include/duckdb/common/file_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class FileSystem {
public:
DUCKDB_API static FileSystem &GetFileSystem(ClientContext &context);
DUCKDB_API static FileSystem &GetFileSystem(DatabaseInstance &db);
DUCKDB_API static FileSystem &GetLocal(DatabaseInstance &db);
DUCKDB_API static FileSystem &Get(AttachedDatabase &db);

DUCKDB_API virtual unique_ptr<FileHandle> OpenFile(const string &path, FileOpenFlags flags,
Expand Down Expand Up @@ -191,6 +192,8 @@ class FileSystem {
DUCKDB_API virtual void RemoveFile(const string &filename, optional_ptr<FileOpener> opener = nullptr);
//! Remvoe a file from disk if it exists - if it does not exist, return false
DUCKDB_API virtual bool TryRemoveFile(const string &filename, optional_ptr<FileOpener> opener = nullptr);
//! Remove multiple files from disk - does not error if any file does not exist
DUCKDB_API virtual void RemoveFiles(const vector<string> &filenames, optional_ptr<FileOpener> opener = nullptr);
//! Sync a file handle to disk
DUCKDB_API virtual void FileSync(FileHandle &handle);
//! Sets the working directory
Expand Down Expand Up @@ -274,6 +277,9 @@ class FileSystem {
//! Create a LocalFileSystem.
DUCKDB_API static unique_ptr<FileSystem> CreateLocal();

//! Whether this is a LocalFileSystem instance.
DUCKDB_API virtual bool IsLocalFileSystem() const;

//! Return the name of the filesytem. Used for forming diagnosis messages.
DUCKDB_API virtual std::string GetName() const = 0;

Expand Down
4 changes: 4 additions & 0 deletions src/duckdb/src/include/duckdb/common/local_file_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ class LocalFileSystem : public FileSystem {
return "LocalFileSystem";
}

bool IsLocalFileSystem() const override {
return true;
}

//! Returns the last Win32 error, in string format. Returns an empty string if there is no error, or on non-Windows
//! systems.
static std::string GetLastErrorAsString();
Expand Down
36 changes: 36 additions & 0 deletions src/duckdb/src/include/duckdb/common/opener_file_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,34 @@ class OpenerFileSystem : public FileSystem {
return FileSystem::ExpandPath(path, GetOpener());
}

bool DirectoryExists(const string &directory) {
return DirectoryExists(directory, nullptr);
}

void CreateDirectory(const string &directory) {
CreateDirectory(directory, nullptr);
}
void RemoveDirectory(const string &directory) {
RemoveDirectory(directory, nullptr);
}
void MoveFile(const string &source, const string &target) {
MoveFile(source, target, nullptr);
}
bool FileExists(const string &filename) {
return FileExists(filename, nullptr);
}
bool IsPipe(const string &filename) {
return IsPipe(filename, nullptr);
}
void RemoveFile(const string &filename) {
RemoveFile(filename, nullptr);
}
bool TryRemoveFile(const string &filename) {
return TryRemoveFile(filename, nullptr);
}
void RemoveFiles(const vector<string> &filenames) {
RemoveFiles(filenames, nullptr);
}
bool FileExists(const string &filename, optional_ptr<FileOpener> opener) override {
VerifyNoOpener(opener);
VerifyCanAccessFile(filename);
Expand All @@ -132,6 +160,14 @@ class OpenerFileSystem : public FileSystem {
return GetFileSystem().TryRemoveFile(filename, GetOpener());
}

void RemoveFiles(const vector<string> &filenames, optional_ptr<FileOpener> opener) override {
VerifyNoOpener(opener);
for (const auto &filename : filenames) {
VerifyCanAccessFile(filename);
}
GetFileSystem().RemoveFiles(filenames, GetOpener());
}

string PathSeparator(const string &path) override {
return GetFileSystem().PathSeparator(path);
}
Expand Down
3 changes: 3 additions & 0 deletions src/duckdb/src/include/duckdb/common/virtual_file_system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class VirtualFileSystem : public FileSystem {
bool IsPipe(const string &filename, optional_ptr<FileOpener> opener) override;
void RemoveFile(const string &filename, optional_ptr<FileOpener> opener) override;
bool TryRemoveFile(const string &filename, optional_ptr<FileOpener> opener) override;
void RemoveFiles(const vector<string> &filenames, optional_ptr<FileOpener> opener) override;

vector<OpenFileInfo> Glob(const string &path, FileOpener *opener = nullptr) override;

Expand All @@ -61,6 +62,8 @@ class VirtualFileSystem : public FileSystem {

vector<string> ListSubSystems() override;

FileSystem &GetDefaultFileSystem();

std::string GetName() const override;

void SetDisabledFileSystems(const vector<string> &names) override;
Expand Down
3 changes: 3 additions & 0 deletions src/duckdb/src/include/duckdb/main/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "duckdb/main/extension_manager.hpp"

namespace duckdb {
class LocalDatabaseFileSystem;
class BufferManager;
class DatabaseManager;
class StorageManager;
Expand Down Expand Up @@ -50,6 +51,7 @@ class DatabaseInstance : public enable_shared_from_this<DatabaseInstance> {
DUCKDB_API const BufferManager &GetBufferManager() const;
DUCKDB_API DatabaseManager &GetDatabaseManager();
DUCKDB_API FileSystem &GetFileSystem();
DUCKDB_API FileSystem &GetLocalFileSystem();
DUCKDB_API ExternalFileCache &GetExternalFileCache();
DUCKDB_API TaskScheduler &GetScheduler();
DUCKDB_API ObjectCache &GetObjectCache();
Expand Down Expand Up @@ -90,6 +92,7 @@ class DatabaseInstance : public enable_shared_from_this<DatabaseInstance> {
unique_ptr<ExtensionManager> extension_manager;
ValidChecker db_validity;
unique_ptr<DatabaseFileSystem> db_file_system;
unique_ptr<LocalDatabaseFileSystem> local_db_file_system;
unique_ptr<LogManager> log_manager;
unique_ptr<ExternalFileCache> external_file_cache;

Expand Down
17 changes: 17 additions & 0 deletions src/duckdb/src/include/duckdb/main/database_file_opener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "duckdb/common/opener_file_system.hpp"
#include "duckdb/main/config.hpp"
#include "duckdb/main/database.hpp"
#include "duckdb/common/local_file_system.hpp"
#include "duckdb/logging/log_manager.hpp"

namespace duckdb {
Expand Down Expand Up @@ -63,4 +64,20 @@ class DatabaseFileSystem : public OpenerFileSystem {
mutable DatabaseFileOpener database_opener;
};

class LocalDatabaseFileSystem : public OpenerFileSystem {
public:
explicit LocalDatabaseFileSystem(DatabaseInstance &db_p);

FileSystem &GetFileSystem() const override;
optional_ptr<FileOpener> GetOpener() const override {
return &database_opener;
}

private:
DatabaseInstance &db;
unique_ptr<FileSystem> owned_file_system;
FileSystem &local_fs;
mutable DatabaseFileOpener database_opener;
};

} // namespace duckdb
32 changes: 32 additions & 0 deletions src/duckdb/src/main/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "duckdb/catalog/catalog.hpp"
#include "duckdb/common/virtual_file_system.hpp"
#include "duckdb/common/local_file_system.hpp"
#include "duckdb/execution/index/index_type_set.hpp"
#include "duckdb/execution/operator/helper/physical_set.hpp"
#include "duckdb/function/cast/cast_function_set.hpp"
Expand Down Expand Up @@ -126,6 +127,10 @@ FileSystem &FileSystem::GetFileSystem(DatabaseInstance &db) {
return db.GetFileSystem();
}

FileSystem &FileSystem::GetLocal(DatabaseInstance &db) {
return db.GetLocalFileSystem();
}

FileSystem &FileSystem::Get(AttachedDatabase &db) {
return FileSystem::GetFileSystem(db.GetDatabase());
}
Expand Down Expand Up @@ -278,6 +283,7 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
create_api_v1 = CreateAPIv1Wrapper;

db_file_system = make_uniq<DatabaseFileSystem>(*this);
local_db_file_system = make_uniq<LocalDatabaseFileSystem>(*this);
db_manager = make_uniq<DatabaseManager>(*this);
if (config.buffer_manager) {
buffer_manager = config.buffer_manager;
Expand Down Expand Up @@ -380,6 +386,32 @@ FileSystem &DatabaseInstance::GetFileSystem() {
return *db_file_system;
}

FileSystem &DatabaseInstance::GetLocalFileSystem() {
return *local_db_file_system;
}

static FileSystem &ResolveLocalFileSystem(DatabaseInstance &db, unique_ptr<FileSystem> &owned) {
auto &vfs = static_cast<VirtualFileSystem &>(*db.config.file_system);
auto &default_fs = vfs.GetDefaultFileSystem();
if (default_fs.IsLocalFileSystem()) {
return default_fs;
}
owned = make_uniq<LocalFileSystem>();
return *owned;
}

LocalDatabaseFileSystem::LocalDatabaseFileSystem(DatabaseInstance &db_p)
: db(db_p), local_fs(ResolveLocalFileSystem(db_p, owned_file_system)), database_opener(db_p) {
}

FileSystem &LocalDatabaseFileSystem::GetFileSystem() const {
auto &vfs = static_cast<VirtualFileSystem &>(*db.config.file_system);
if (vfs.SubSystemIsDisabled(local_fs.GetName())) {
throw PermissionException("File system %s has been disabled by configuration", local_fs.GetName());
}
return local_fs;
}

ExternalFileCache &DatabaseInstance::GetExternalFileCache() {
return *external_file_cache;
}
Expand Down
8 changes: 5 additions & 3 deletions src/duckdb/src/main/extension/extension_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "duckdb/common/file_system.hpp"
#include "duckdb/common/serializer/binary_deserializer.hpp"
#include "duckdb/common/local_file_system.hpp"
#include "duckdb/main/database_file_opener.hpp"
#include "duckdb/common/serializer/buffered_file_reader.hpp"
#include "duckdb/common/string_util.hpp"
#include "duckdb/common/windows.hpp"
Expand Down Expand Up @@ -387,17 +389,17 @@ void ExtensionHelper::AutoLoadExtension(DatabaseInstance &db, const string &exte
}
auto &dbconfig = DBConfig::GetConfig(db);
try {
auto fs = FileSystem::CreateLocal();
auto &fs = FileSystem::GetLocal(db);
#ifndef DUCKDB_WASM
if (dbconfig.options.autoinstall_known_extensions) {
auto repository_url = GetAutoInstallExtensionsRepository(dbconfig.options);
auto autoinstall_repo = ExtensionRepository::GetRepositoryByUrl(repository_url);
ExtensionInstallOptions options;
options.repository = autoinstall_repo;
ExtensionHelper::InstallExtension(db, *fs, extension_name, options);
ExtensionHelper::InstallExtension(db, fs, extension_name, options);
}
#endif
ExtensionHelper::LoadExternalExtension(db, *fs, extension_name);
ExtensionHelper::LoadExternalExtension(db, fs, extension_name);
DUCKDB_LOG_INFO(db, "Loaded extension '%s'", extension_name);
} catch (std::exception &e) {
ErrorData error(e);
Expand Down
17 changes: 9 additions & 8 deletions src/duckdb/src/main/extension/extension_install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "duckdb/common/gzip_file_system.hpp"
#include "duckdb/common/http_util.hpp"
#include "duckdb/common/local_file_system.hpp"
#include "duckdb/main/database_file_opener.hpp"
#include "duckdb/common/serializer/binary_serializer.hpp"
#include "duckdb/common/string_util.hpp"
#include "duckdb/common/types/uuid.hpp"
Expand Down Expand Up @@ -373,11 +374,11 @@ static unique_ptr<ExtensionInstallInfo> InstallFromHttpUrl(DatabaseInstance &db,
optional_ptr<ClientContext> context) {
unique_ptr<ExtensionInstallInfo> install_info;
{
auto fs = FileSystem::CreateLocal();
if (fs->FileExists(local_extension_path + ".info")) {
auto &fs = FileSystem::GetLocal(db);
if (fs.FileExists(local_extension_path + ".info")) {
try {
install_info =
ExtensionInstallInfo::TryReadInfoFile(*fs, local_extension_path + ".info", extension_name);
ExtensionInstallInfo::TryReadInfoFile(fs, local_extension_path + ".info", extension_name);
} catch (...) {
if (!options.force_install) {
// We are going to rewrite the file anyhow, so this is fine
Expand Down Expand Up @@ -450,8 +451,8 @@ static unique_ptr<ExtensionInstallInfo> InstallFromHttpUrl(DatabaseInstance &db,
}

QueryContext query_context(context);
auto fs = FileSystem::CreateLocal();
WriteExtensionFiles(query_context, *fs, temp_path, local_extension_path, (void *)decompressed_body.data(),
auto &fs = FileSystem::GetLocal(db);
WriteExtensionFiles(query_context, fs, temp_path, local_extension_path, (void *)decompressed_body.data(),
decompressed_body.size(), info, db.config);

return make_uniq<ExtensionInstallInfo>(info);
Expand Down Expand Up @@ -548,15 +549,15 @@ unique_ptr<ExtensionInstallInfo> ExtensionHelper::InstallExtensionInternal(Datab

// Install extension from local, direct url
if (ExtensionHelper::IsFullPath(extension) && !IsHTTP(extension)) {
LocalFileSystem local_fs;
auto &local_fs = FileSystem::GetLocal(db);
return DirectInstallExtension(db, local_fs, extension, temp_path, extension, local_extension_path, options,
context);
}

// Install extension from local url based on a repository (Note that this will install it as a local file)
if (options.repository && !IsHTTP(options.repository->path)) {
LocalFileSystem local_fs;
return InstallFromRepository(db, fs, extension, extension_name, temp_path, local_extension_path, options,
auto &local_fs = FileSystem::GetLocal(db);
return InstallFromRepository(db, local_fs, extension, extension_name, temp_path, local_extension_path, options,
context);
}

Expand Down
Loading
Loading