| 97 | }; |
| 98 | |
| 99 | unique_ptr<FunctionData> BindExtensionFunction(ClientContext &context, ScalarFunction &bound_function, |
| 100 | vector<unique_ptr<Expression>> &arguments) { |
| 101 | // if this is triggered we are trying to call a method that is present in an extension |
| 102 | // but the extension is not loaded |
| 103 | // try to autoload the extension |
| 104 | // first figure out which extension we need to auto-load |
| 105 | auto &function_info = bound_function.GetExtraFunctionInfo().Cast<ExtensionFunctionInfo>(); |
| 106 | auto &extension_name = function_info.extension; |
| 107 | auto &db = *context.db; |
| 108 | |
| 109 | if (!ExtensionHelper::CanAutoloadExtension(extension_name)) { |
| 110 | throw BinderException("Trying to call function \"%s\" which is present in extension \"%s\" - but the extension " |
| 111 | "is not loaded and could not be auto-loaded", |
| 112 | bound_function.name, extension_name); |
| 113 | } |
| 114 | // auto-load the extension |
| 115 | ExtensionHelper::AutoLoadExtension(db, extension_name); |
| 116 | |
| 117 | // now find the function in the catalog |
| 118 | auto &catalog = Catalog::GetSystemCatalog(db); |
| 119 | auto &function_entry = catalog.GetEntry<ScalarFunctionCatalogEntry>(context, DEFAULT_SCHEMA, bound_function.name); |
| 120 | // override the function with the extension function |
| 121 | bound_function = function_entry.functions.GetFunctionByArguments(context, bound_function.arguments); |
| 122 | // call the original bind (if any) |
| 123 | if (!bound_function.HasBindCallback()) { |
| 124 | return nullptr; |
| 125 | } |
| 126 | return bound_function.GetBindCallback()(context, bound_function, arguments); |
| 127 | } |
| 128 | |
| 129 | void BuiltinFunctions::AddExtensionFunction(ScalarFunctionSet set) { |
| 130 | CreateScalarFunctionInfo info(std::move(set)); |
nothing calls this directly
no test coverage detected