This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 33ba77a00 fix(rust/driver_manager): use platform library filenames in
search paths (#4155)
33ba77a00 is described below
commit 33ba77a001be8b9f466cd977e2e39ac558016e7e
Author: Mila Page <[email protected]>
AuthorDate: Tue Mar 31 09:32:58 2026 +0000
fix(rust/driver_manager): use platform library filenames in search paths
(#4155)
## Summary
Fix Rust `driver_manager` search-path loading for bare driver names.
This came up while testing local ADBC driver development through
additional search paths. We've used this plenty over the past year or
so. However, now `search_path_list()` in
`rust/driver_manager/src/search.rs` was joining a bare driver name like
`adbc_driver_bigquery` directly into the search directory and attempting
to load that path as-is. On macOS, that meant trying
`/path/to/adbc_driver_bigquery` instead of
`/path/to/libadbc_driver_bigquery.dylib`.
This change applies `libloading::library_filename(...)` before loading
from additional search paths so path-based search matches the existing
by-name loading behavior.
This also, I believe, aligns the Rust behavior with the existing C++
driver-manager search-path logic in
`c/driver_manager/adbc_driver_manager_driver_loading.cc`, where
`ManagedLibrary::SearchPathsForDriver()` removes the manifest suffix and
relies on `Load(...)` to add the platform library suffix during
path-based search.
If there's a different intent for this package, do let me know. Happy to
iterate if required 🙏
## Testing
`cargo +1.86 test -p adbc_driver_manager
test_load_additional_path_with_platform_library_filename`
I smoke tested this with my local project which was looking for the
extension-less filename, then once more began to find my drivers built
in arrow-adbc's go subrepo.
---
rust/driver_manager/src/search.rs | 42 +++++++++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/rust/driver_manager/src/search.rs
b/rust/driver_manager/src/search.rs
index 2fa9f29fd..a8d35fcb2 100644
--- a/rust/driver_manager/src/search.rs
+++ b/rust/driver_manager/src/search.rs
@@ -596,8 +596,15 @@ impl<'a> DriverLibrary<'a> {
}
full_path.set_extension(""); // Remove the extension to try
loading as a dynamic library.
- let result = DriverLibrary::load_library(&full_path)
- .map(|library| SearchHit::new(full_path, library, None));
+ let library_path = match
DriverLibrary::platform_library_path(&full_path) {
+ Ok(path) => path,
+ Err(err) => {
+ trace.push(err);
+ return None;
+ }
+ };
+ let result = DriverLibrary::load_library(&library_path)
+ .map(|library| SearchHit::new(library_path, library,
None));
match result {
Ok(res) => return Some(Ok(res)),
Err(err) => trace.push(err),
@@ -612,6 +619,16 @@ impl<'a> DriverLibrary<'a> {
})
}
+ fn platform_library_path(path: &Path) -> Result<PathBuf> {
+ let file_name = path.file_name().ok_or_else(|| {
+ Error::with_message_and_status(
+ "Driver search path must include a file name",
+ Status::Internal,
+ )
+ })?;
+ Ok(path.with_file_name(libloading::library_filename(file_name)))
+ }
+
/// Construct default entrypoint from the library path.
fn get_default_entrypoint(driver_path: impl AsRef<OsStr>) -> String {
// - libadbc_driver_sqlite.so.2.0.0 -> AdbcDriverSqliteInit
@@ -1418,6 +1435,27 @@ mod tests {
.expect("Failed to close/remove temporary directory");
}
+ #[test]
+ fn test_load_additional_path_with_platform_library_filename() {
+ let library_path =
+
DriverLibrary::platform_library_path(Path::new("drivers/adbc_driver_test")).unwrap();
+ assert_eq!(
+ library_path.extension(),
+ Some(OsStr::new(env::consts::DLL_EXTENSION))
+ );
+ assert_eq!(
+ library_path,
+
Path::new("drivers").join(libloading::library_filename("adbc_driver_test"))
+ );
+ }
+
+ #[test]
+ fn test_platform_library_path_requires_file_name() {
+ let err =
DriverLibrary::platform_library_path(Path::new("")).unwrap_err();
+ assert_eq!(err.status, Status::Internal);
+ assert_eq!(err.message, "Driver search path must include a file name");
+ }
+
#[test]
#[cfg_attr(not(feature = "driver_manager_test_lib"), ignore)]
fn test_load_non_ascii_path() {