diff --git a/patches/duckdb/extension_install_rework_with_community.patch b/patches/duckdb/extension_install_rework_with_community.patch new file mode 100644 index 000000000..833177d58 --- /dev/null +++ b/patches/duckdb/extension_install_rework_with_community.patch @@ -0,0 +1,84 @@ +diff --git a/src/include/duckdb/main/database.hpp b/src/include/duckdb/main/database.hpp +index 222a36c051..b2bcd97599 100644 +--- a/src/include/duckdb/main/database.hpp ++++ b/src/include/duckdb/main/database.hpp +@@ -37,6 +37,7 @@ struct ExtensionInfo { + }; + + class DatabaseInstance : public enable_shared_from_this { ++ unordered_map extensionsRepos; + friend class DuckDB; + + public: +@@ -46,6 +47,16 @@ public: + DBConfig config; + + public: ++ void SetPreferredRepository(const string& extension, const string &repository) { ++ extensionsRepos[extension] = repository; ++ } ++ string GetPreferredRepository(const string& extension) const { ++ auto it = extensionsRepos.find(extension); ++ if (it != extensionsRepos.end()) { ++ return it->second; ++ } ++ return ""; ++ } + BufferPool &GetBufferPool() const; + DUCKDB_API SecretManager &GetSecretManager(); + DUCKDB_API BufferManager &GetBufferManager(); +diff --git a/src/main/extension/extension_install.cpp b/src/main/extension/extension_install.cpp +index b0ca9fb775..4774e26450 100644 +--- a/src/main/extension/extension_install.cpp ++++ b/src/main/extension/extension_install.cpp +@@ -144,6 +144,9 @@ bool ExtensionHelper::CreateSuggestions(const string &extension_name, string &me + unique_ptr ExtensionHelper::InstallExtension(DatabaseInstance &db, FileSystem &fs, + const string &extension, + ExtensionInstallOptions &options) { ++ if (options.repository) { ++ db.SetPreferredRepository(extension, options.repository->path); ++ } + #ifdef WASM_LOADABLE_EXTENSIONS + // Install is currently a no-op + return nullptr; +@@ -154,11 +157,14 @@ unique_ptr ExtensionHelper::InstallExtension(DatabaseInsta + + unique_ptr ExtensionHelper::InstallExtension(ClientContext &context, const string &extension, + ExtensionInstallOptions &options) { ++ auto &db = DatabaseInstance::GetDatabase(context); ++ if (options.repository) { ++ db.SetPreferredRepository(extension, options.repository->path); ++ } + #ifdef WASM_LOADABLE_EXTENSIONS + // Install is currently a no-op + return nullptr; + #endif +- auto &db = DatabaseInstance::GetDatabase(context); + auto &fs = FileSystem::GetFileSystem(context); + string local_path = ExtensionDirectory(context); + optional_ptr http_logger = +diff --git a/src/main/extension/extension_load.cpp b/src/main/extension/extension_load.cpp +index c0a37ea97a..2916dc2611 100644 +--- a/src/main/extension/extension_load.cpp ++++ b/src/main/extension/extension_load.cpp +@@ -301,7 +301,19 @@ bool ExtensionHelper::TryInitialLoad(DatabaseInstance &db, FileSystem &fs, const + direct_load = false; + string extension_name = ApplyExtensionAlias(extension); + #ifdef WASM_LOADABLE_EXTENSIONS +- string url_template = ExtensionUrlTemplate(&config, ""); ++ ExtensionRepository repository; ++ string custom_endpoint = db.config.options.custom_extension_repo; ++ if (!custom_endpoint.empty()) { ++ repository = ExtensionRepository("custom", custom_endpoint); ++ } ++ { ++ auto preferredRepo = db.GetPreferredRepository(extension); ++ if (!preferredRepo.empty()) { ++ repository = ExtensionRepository("x", preferredRepo); ++ } ++ } ++ ++ string url_template = ExtensionUrlTemplate(db, repository, ""); + string url = ExtensionFinalizeUrlTemplate(url_template, extension_name); + + char *str = (char *)EM_ASM_PTR(