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 056dc6871 feat(rust/driver_manager): reconcile with C++ driver manager 
(#4121)
056dc6871 is described below

commit 056dc6871fed522c22f1f77bd54ca989b27c319e
Author: David Li <[email protected]>
AuthorDate: Mon Mar 23 09:18:16 2026 +0900

    feat(rust/driver_manager): reconcile with C++ driver manager (#4121)
    
    Closes #4089.
---
 docs/source/format/connection_profiles.rst         |  83 +++---
 docs/source/format/driver_manifests.rst            |   6 +-
 docs/source/glossary.rst                           |   5 +
 javascript/__test__/profile.spec.ts                |   2 +-
 javascript/binding.d.ts                            |   3 +-
 javascript/lib/types.ts                            |  11 +-
 javascript/src/client.rs                           |  21 +-
 javascript/src/lib.rs                              |   6 +-
 rust/driver_manager/src/lib.rs                     |   8 +-
 rust/driver_manager/src/profile.rs                 | 120 +++++++--
 rust/driver_manager/src/search.rs                  |  14 +-
 rust/driver_manager/tests/common/mod.rs            |  27 ++
 rust/driver_manager/tests/connection_profile.rs    | 277 +++++++++++++++------
 rust/driver_manager/tests/test_env_var_profiles.rs |  45 +---
 14 files changed, 416 insertions(+), 212 deletions(-)

diff --git a/docs/source/format/connection_profiles.rst 
b/docs/source/format/connection_profiles.rst
index 87d8ac142..aaabc49e9 100644
--- a/docs/source/format/connection_profiles.rst
+++ b/docs/source/format/connection_profiles.rst
@@ -15,30 +15,37 @@
 .. specific language governing permissions and limitations
 .. under the License.
 
-==================================
-Driver Manager Connection Profiles
-==================================
+===========================================
+ADBC Driver Manager and Connection Profiles
+===========================================
 
-Overview
-========
+.. note:: This document describes using the :term:`driver manager` to load
+          drivers.  The driver manager is not required to use ADBC in general
+          but it allows loading drivers written in a different language from 
the
+          application and improves the experience when using multiple drivers 
in
+          a single application. For more information on how the driver manager
+          works see :doc:`how_manager`.
 
-There are two ways to pass connection options to driver managers:
+There are two ways to pass database options through the driver manager:
 
-1. Directly specifying all connection options as arguments to driver manager 
functions in your
-   application code. (see the `SetOption` family of functions in 
:doc:`specification` for details)
-2. Referring to a **connection profile** which contains connection options, 
and optionally overriding
-   some options in your application code.
+1. Directly specifying all options as arguments to the driver manager in your
+   application code (see the `SetOption` family of functions in
+   :doc:`specification` for details).
+2. Referring to a :term:`connection profile` which contains options, and
+   optionally overriding some options by setting them through the above
+   method.
 
-The ADBC driver manager supports **connection profiles** that specify a driver 
and connection options
-in a reusable configuration. This allows users to:
+Connection profiles combine a driver and database options in a reusable
+configuration. This allows users to:
 
 - Define connection information in files or environment variables
 - Share connection configurations across applications
 - Distribute standardized connection settings
 - Avoid hardcoding driver names and credentials in application code
 
-Profiles are loaded during ``AdbcDatabaseInit()`` before initializing the 
driver. Options
-from the profile are applied automatically but do not override options already 
set via ``AdbcDatabaseSetOption()``.
+Profiles are loaded during ``AdbcDatabaseInit()`` before initializing the
+driver. Options from the profile are applied automatically but do not override
+options already set via ``AdbcDatabaseSetOption()``.
 
 Quick Start
 ===========
@@ -74,9 +81,12 @@ Filesystem-based profiles use TOML format with the following 
structure:
 
 .. code-block:: toml
 
+   # The version is required.
    profile_version = 1
+   # The driver is optional, but if not provided it must be set by the 
application.
    driver = "snowflake"
 
+   # The Options table is required, even if empty
    [Options]
    # String options
    adbc.snowflake.sql.account = "mycompany"
@@ -111,18 +121,19 @@ driver
 
 The ``driver`` field specifies which ADBC driver to load. This can be:
 
-- A driver name (e.g., ``"snowflake"``)
+- A driver or driver manifest name (e.g., ``"snowflake"``)
 - A path to a shared library (e.g., 
``"/usr/local/lib/libadbc_driver_snowflake.so"``)
 - A path to a driver manifest (e.g., ``"/etc/adbc/drivers/snowflake.toml"``)
 
 If omitted, the driver must be specified through other means (e.g., the 
``driver`` option or ``uri`` parameter).
+If the application specifies a driver, and specifies a profile that itself 
references a driver, the two must match exactly, or it is an error.
 The driver will be loaded identically to if it was specified via 
``AdbcDatabaseSetOption("driver", "<driver>")``.
 For more detils, see :doc:`driver_manifests`.
 
 Options Section
 ---------------
 
-The ``[Options]`` section contains driver-specific configuration options. 
Options can be of the following types:
+The ``[Options]`` section contains driver-specific configuration options to 
apply to the ``AdbcDatabase`` upon creation. This section must be present, even 
if empty. Options can be of the following types:
 
 **String values**
    Applied using ``AdbcDatabaseSetOption()``
@@ -153,6 +164,10 @@ The ``[Options]`` section contains driver-specific 
configuration options. Option
 
       adbc.snowflake.sql.client_session_keep_alive = true
 
+.. warning:: If the application overrides option values but uses a different
+             type for the value than the profile does, it is undefined which
+             will take effect.
+
 Value Substitution
 ------------------
 
@@ -190,7 +205,7 @@ Profile Search Locations
 
 When using a profile name (not an absolute path), the driver manager searches 
for ``<profile_name>.toml`` in the following locations:
 
-1. **Additional Search Paths** (if configured via 
``AdbcDriverManagerDatabaseSetAdditionalSearchPathList()``)
+1. **Additional Search Paths** (if configured via 
``additional_profile_search_path_list`` option)
 2. **ADBC_PROFILE_PATH** environment variable (colon-separated on Unix, 
semicolon-separated on Windows)
 3. **Conda Environment** (if built with Conda support and ``CONDA_PREFIX`` is 
set):
 
@@ -561,34 +576,28 @@ Sets a custom connection profile provider. Must be called 
before ``AdbcDatabaseI
 Setting Additional Search Paths
 --------------------------------
 
-.. code-block:: c
-
-   AdbcStatusCode AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
-       struct AdbcDatabase* database,
-       const char* path_list,
-       struct AdbcError* error);
-
-Adds additional directories to search for profiles. Must be called before 
``AdbcDatabaseInit()``.
-
-**Parameters:**
-
-- ``database``: Database object to configure
-- ``path_list``: OS-specific path separator delimited list (``:``) on Unix, 
``;`` on Windows), or ``NULL`` to clear
-- ``error``: Optional error output
-
-**Returns:** ``ADBC_STATUS_OK`` on success, error code otherwise.
+This can be done via the ``additional_profile_search_path_list`` option. It
+must be set before ``AdbcDatabaseInit()``. The value of this option is an
+OS-specific delimited list (``:`` on Unix, ``;`` on Windows), or ``NULL`` to
+clear.
 
 **Example:**
 
 .. code-block:: c
 
    // Unix/Linux/macOS
-   AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
-       &database, "/opt/app/profiles:/etc/app/profiles", &error);
+   AdbcDatabaseSetOption(
+       &database,
+       "additional_profile_search_path_list",
+       "/opt/app/profiles:/etc/app/profiles",
+       &error);
 
    // Windows
-   AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
-       &database, "C:\\App\\Profiles;C:\\ProgramData\\App\\Profiles", &error);
+   AdbcDatabaseSetOption(
+       &database,
+       "additional_profile_search_path_list",
+       "C:\\App\\Profiles;C:\\ProgramData\\App\\Profiles",
+       &error);
 
 
 See Also
diff --git a/docs/source/format/driver_manifests.rst 
b/docs/source/format/driver_manifests.rst
index 1d4896298..77753f81a 100644
--- a/docs/source/format/driver_manifests.rst
+++ b/docs/source/format/driver_manifests.rst
@@ -28,9 +28,9 @@ ADBC Driver Manager and Manifests
 
 There are two ways to load a driver with the driver manager:
 
-1. Directly specifying the dynamic library to load
-2. Referring to a driver manifest file which contains metadata along with the
-   location of the dynamic library to be loaded
+1. Directly specifying the dynamic library to load.
+2. Referring to a :term:`driver manifest` file which contains metadata along
+   with the location of the dynamic library to be loaded.
 
 With either method, you specify the dynamic library or driver manifest as the
 ``driver`` option to the driver manager or you can use an explicit function for
diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst
index 843493a98..ab87f4c6f 100644
--- a/docs/source/glossary.rst
+++ b/docs/source/glossary.rst
@@ -34,6 +34,11 @@ Glossary
      In ADBC, the connection object/struct represents a single connection to a
      database.  Multiple connections may be created from one :term:`database`.
 
+   connection profile
+     A preconfigured driver and options that can be loaded by the
+     :term:`driver manager` for convenience.  Specified via a TOML file.  See
+     :doc:`format/connection_profiles`.
+
    database
      In ADBC, the database object/struct holds state that is shared across
      connections.
diff --git a/javascript/__test__/profile.spec.ts 
b/javascript/__test__/profile.spec.ts
index 4f346f3c2..3fcab571e 100644
--- a/javascript/__test__/profile.spec.ts
+++ b/javascript/__test__/profile.spec.ts
@@ -47,7 +47,7 @@ test('profile: load database from profile:// URI', async () 
=> {
 
     const db = new AdbcDatabase({
       driver: 'profile://test_sqlite',
-      searchPaths: [tmpDir],
+      profileSearchPaths: [tmpDir],
     })
     const conn = await db.connect()
 
diff --git a/javascript/binding.d.ts b/javascript/binding.d.ts
index b6891e90a..2740d1655 100644
--- a/javascript/binding.d.ts
+++ b/javascript/binding.d.ts
@@ -43,7 +43,8 @@ export type _NativeAdbcStatement = NativeAdbcStatement
 export interface ConnectOptions {
   driver: string
   entrypoint?: string
-  searchPaths?: Array<string>
+  manifestSearchPaths?: Array<string>
+  profileSearchPaths?: Array<string>
   loadFlags?: number
   databaseOptions?: Record<string, string>
 }
diff --git a/javascript/lib/types.ts b/javascript/lib/types.ts
index 43b64856a..6a6b3ba12 100644
--- a/javascript/lib/types.ts
+++ b/javascript/lib/types.ts
@@ -118,7 +118,7 @@ export interface ConnectOptions {
    * - URI-style string: `"sqlite:file::memory:"`, 
`"postgresql://user:pass@host/db"` — the
    *   driver name is the URI scheme and the remainder is passed as the 
connection URI.
    * - Connection profile URI: `"profile://my_profile"` — loads a named 
profile from a
-   *   `.toml` file found in {@link searchPaths} or the default search 
directories.
+   *   `.toml` file found in {@link profileSearchPaths} or the default search 
directories.
    */
   driver: string
   /**
@@ -127,10 +127,15 @@ export interface ConnectOptions {
    */
   entrypoint?: string
   /**
-   * Additional directories to search for drivers and driver manifest 
(`.toml`) profile files (optional).
+   * Additional directories to search for drivers and driver manifest 
(`.toml`) files (optional).
    * Searched before the default system and user configuration directories.
    */
-  searchPaths?: string[]
+  manifestSearchPaths?: string[]
+  /**
+   * Additional directories to search for connection profile (`.toml`) files 
(optional).
+   * Searched before the default system and user configuration directories.
+   */
+  profileSearchPaths?: string[]
   /**
    * Bitmask controlling how the driver name is resolved (optional).
    * Use the {@link LoadFlags} constants to compose a value.
diff --git a/javascript/src/client.rs b/javascript/src/client.rs
index be3e627e4..66c695568 100644
--- a/javascript/src/client.rs
+++ b/javascript/src/client.rs
@@ -48,7 +48,8 @@ pub type Result<T> = std::result::Result<T, ClientError>;
 pub struct ConnectOptions {
   pub driver: String,
   pub entrypoint: Option<String>,
-  pub search_paths: Option<Vec<String>>,
+  pub manifest_search_paths: Option<Vec<String>>,
+  pub profile_search_paths: Option<Vec<String>>,
   pub load_flags: Option<u32>,
   pub database_options: Option<HashMap<String, String>>,
 }
@@ -78,20 +79,28 @@ impl AdbcDatabaseCore {
     let load_flags = opts.load_flags.unwrap_or(LOAD_FLAG_DEFAULT);
     let entrypoint = opts.entrypoint.as_ref().map(|s| s.as_bytes().to_vec());
 
-    let search_paths: Option<Vec<PathBuf>> = opts
-      .search_paths
+    let manifest_search_paths: Option<Vec<PathBuf>> = opts
+      .manifest_search_paths
+      .map(|paths| paths.into_iter().map(PathBuf::from).collect());
+
+    let profile_search_paths: Option<Vec<PathBuf>> = opts
+      .profile_search_paths
       .map(|paths| paths.into_iter().map(PathBuf::from).collect());
 
     let database_opts = opts.database_options.map(map_database_options);
 
     let database = if opts.driver.contains(':') {
+      let provider = 
adbc_driver_manager::profile::FilesystemProfileProvider::new_with_search_paths(
+        profile_search_paths,
+      );
       // URI-style ("sqlite:file::memory:") or profile URI 
("profile://my_profile")
-      ManagedDatabase::from_uri_with_opts(
+      ManagedDatabase::from_uri_with_profile_provider(
         &opts.driver,
         entrypoint.as_deref(),
         version,
         load_flags,
-        search_paths,
+        manifest_search_paths,
+        provider,
         database_opts.into_iter().flatten(),
       )?
     } else {
@@ -101,7 +110,7 @@ impl AdbcDatabaseCore {
         entrypoint.as_deref(),
         version,
         load_flags,
-        search_paths,
+        manifest_search_paths,
       )?;
       match database_opts {
         Some(db_opts) => driver.new_database_with_opts(db_opts)?,
diff --git a/javascript/src/lib.rs b/javascript/src/lib.rs
index 136e9292a..92bee8663 100644
--- a/javascript/src/lib.rs
+++ b/javascript/src/lib.rs
@@ -144,7 +144,8 @@ pub fn default_load_flags() -> u32 {
 pub struct ConnectOptions {
   pub driver: String,
   pub entrypoint: Option<String>,
-  pub search_paths: Option<Vec<String>>,
+  pub manifest_search_paths: Option<Vec<String>>,
+  pub profile_search_paths: Option<Vec<String>>,
   pub load_flags: Option<u32>,
   pub database_options: Option<HashMap<String, String>>,
 }
@@ -154,7 +155,8 @@ impl From<ConnectOptions> for CoreConnectOptions {
     Self {
       driver: opts.driver,
       entrypoint: opts.entrypoint,
-      search_paths: opts.search_paths,
+      manifest_search_paths: opts.manifest_search_paths,
+      profile_search_paths: opts.profile_search_paths,
       load_flags: opts.load_flags,
       database_options: opts.database_options,
     }
diff --git a/rust/driver_manager/src/lib.rs b/rust/driver_manager/src/lib.rs
index efd8cb91e..47970de48 100644
--- a/rust/driver_manager/src/lib.rs
+++ b/rust/driver_manager/src/lib.rs
@@ -494,14 +494,13 @@ impl ManagedDatabase {
         additional_search_paths: Option<Vec<PathBuf>>,
         opts: impl IntoIterator<Item = (<Self as Optionable>::Option, 
OptionValue)>,
     ) -> Result<Self> {
-        let profile_provider = FilesystemProfileProvider;
         Self::from_uri_with_profile_provider(
             uri,
             entrypoint,
             version,
             load_flags,
             additional_search_paths,
-            profile_provider,
+            FilesystemProfileProvider::default(),
             opts,
         )
     }
@@ -534,7 +533,7 @@ impl ManagedDatabase {
     /// use adbc_driver_manager::profile::FilesystemProfileProvider;
     /// use adbc_core::LOAD_FLAG_DEFAULT;
     ///
-    /// let provider = FilesystemProfileProvider;
+    /// let provider = FilesystemProfileProvider::default();
     /// let opts = vec![(OptionDatabase::Username, 
OptionValue::String("admin".to_string()))];
     ///
     /// let db = ManagedDatabase::from_uri_with_profile_provider(
@@ -575,8 +574,7 @@ impl ManagedDatabase {
                 (drv, final_opts)
             }
             DriverLocator::Profile(profile) => {
-                let profile =
-                    profile_provider.get_profile(profile, 
additional_search_paths.clone())?;
+                let profile = profile_provider.get_profile(profile)?;
                 let (driver_name, init_func) = profile.get_driver_name()?;
 
                 let drv: ManagedDriver;
diff --git a/rust/driver_manager/src/profile.rs 
b/rust/driver_manager/src/profile.rs
index 8e93ff19f..6697383f0 100644
--- a/rust/driver_manager/src/profile.rs
+++ b/rust/driver_manager/src/profile.rs
@@ -76,7 +76,6 @@ pub trait ConnectionProfileProvider {
     /// # Arguments
     ///
     /// * `name` - The profile name or path to locate
-    /// * `additional_path_list` - Optional additional directories to search 
for profiles
     ///
     /// # Returns
     ///
@@ -88,11 +87,7 @@ pub trait ConnectionProfileProvider {
     /// - The profile cannot be found
     /// - The profile file is malformed
     /// - The profile version is unsupported
-    fn get_profile(
-        &self,
-        name: &str,
-        additional_path_list: Option<Vec<PathBuf>>,
-    ) -> Result<Self::Profile>;
+    fn get_profile(&self, name: &str) -> Result<Self::Profile>;
 }
 
 /// Provides connection profiles from TOML files on the filesystem.
@@ -104,7 +99,7 @@ pub trait ConnectionProfileProvider {
 /// # Search Order
 ///
 /// Profiles are searched in the following order:
-/// 1. Additional paths provided via `get_profile()`
+/// 1. Additional paths provided via `new_with_search_paths`
 /// 2. `ADBC_PROFILE_PATH` environment variable paths
 /// 3. User configuration directory (`~/.config/adbc/profiles` on Linux,
 ///    `~/Library/Application Support/ADBC/Profiles` on macOS,
@@ -117,21 +112,27 @@ pub trait ConnectionProfileProvider {
 ///     ConnectionProfileProvider, FilesystemProfileProvider
 /// };
 ///
-/// let provider = FilesystemProfileProvider;
-/// let profile = provider.get_profile("my_database", None)?;
+/// let provider = FilesystemProfileProvider::default();
+/// let profile = provider.get_profile("my_database")?;
 /// # Ok::<(), adbc_core::error::Error>(())
 /// ```
-pub struct FilesystemProfileProvider;
+#[derive(Clone, Default)]
+pub struct FilesystemProfileProvider {
+    additional_paths: Option<Vec<PathBuf>>,
+}
+
+impl FilesystemProfileProvider {
+    /// Search the given paths (if any) for profiles.
+    pub fn new_with_search_paths(additional_paths: Option<Vec<PathBuf>>) -> 
Self {
+        Self { additional_paths }
+    }
+}
 
 impl ConnectionProfileProvider for FilesystemProfileProvider {
     type Profile = FilesystemProfile;
 
-    fn get_profile(
-        &self,
-        name: &str,
-        additional_path_list: Option<Vec<PathBuf>>,
-    ) -> Result<Self::Profile> {
-        let profile_path = find_filesystem_profile(name, 
additional_path_list)?;
+    fn get_profile(&self, name: &str) -> Result<Self::Profile> {
+        let profile_path = find_filesystem_profile(name, 
&self.additional_paths)?;
         FilesystemProfile::from_path(profile_path)
     }
 }
@@ -266,14 +267,28 @@ impl FilesystemProfile {
         let profile = DeTable::parse(&contents)
             .map_err(|e| Error::with_message_and_status(e.to_string(), 
Status::InvalidArguments))?;
 
-        let profile_version = profile
-            .get_ref()
-            .get("profile_version")
-            .and_then(|v| v.get_ref().as_integer())
-            .map(|v| v.as_str())
-            .unwrap_or("1");
+        let raw_profile_version = 
profile.get_ref().get("profile_version").ok_or_else(|| {
+            Error::with_message_and_status(
+                "missing 'profile_version' in profile".to_string(),
+                Status::InvalidArguments,
+            )
+        })?;
+
+        let profile_version = raw_profile_version
+            .as_ref()
+            .as_integer()
+            .and_then(|i| i64::from_str_radix(i.as_str(), i.radix()).ok())
+            .ok_or_else(|| {
+                Error::with_message_and_status(
+                    format!(
+                        "invalid 'profile_version' in profile: {:?}",
+                        raw_profile_version.as_ref()
+                    ),
+                    Status::InvalidArguments,
+                )
+            })?;
 
-        if profile_version != "1" {
+        if profile_version != 1 {
             return Err(Error::with_message_and_status(
                 format!(
                     "unsupported profile version '{}', expected '1'",
@@ -287,7 +302,12 @@ impl FilesystemProfile {
             .get_ref()
             .get("driver")
             .and_then(|v| v.get_ref().as_str())
-            .unwrap_or("")
+            .ok_or_else(|| {
+                Error::with_message_and_status(
+                    "missing or invalid 'driver' field in profile".to_string(),
+                    Status::InvalidArguments,
+                )
+            })?
             .to_string();
 
         let options_table = profile
@@ -707,6 +727,24 @@ key = "value"
                 "just a plain string",
                 Ok("just a plain string"),
             ),
+            TestCase(
+                "not actually a substitution",
+                vec![],
+                "{{ env_var(NONEXISTENT)",
+                Ok("{{ env_var(NONEXISTENT)"),
+            ),
+            TestCase(
+                "not actually a substitution (2)",
+                vec![],
+                "{{ env_var(NONEXISTENT) }",
+                Ok("{{ env_var(NONEXISTENT) }"),
+            ),
+            TestCase(
+                "not actually a substitution (3)",
+                vec![],
+                "{ env_var(NONEXISTENT) }",
+                Ok("{ env_var(NONEXISTENT) }"),
+            ),
             TestCase(
                 "string with special chars but no templates",
                 vec![],
@@ -731,6 +769,30 @@ key = "value"
                 "foo{{ env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ) }}bar",
                 Ok("foobar"),
             ),
+            TestCase(
+                "env var not set interpolates the empty string (2)",
+                vec![],
+                "foo{{ env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ) }}",
+                Ok("foo"),
+            ),
+            TestCase(
+                "env var not set interpolates the empty string (3)",
+                vec![],
+                "{{ env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ) }}bar",
+                Ok("bar"),
+            ),
+            TestCase(
+                "env var not set interpolates the empty string (4)",
+                vec![],
+                "foo{{ env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ) }}bar{{ 
env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ2) }}baz",
+                Ok("foobarbaz"),
+            ),
+            TestCase(
+                "env var not set interpolates the empty string (5)",
+                vec![],
+                "{{ env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ) }}foobarbaz{{ 
env_var(ADBC_TEST_PPV_NONEXISTENT_XYZ2) }}",
+                Ok("foobarbaz"),
+            ),
             TestCase(
                 "mixed literal text and env var",
                 vec![("ADBC_TEST_PPV_PORT", "5432")],
@@ -752,6 +814,12 @@ key = "value"
                 "{{  env_var(ADBC_TEST_PPV_DB)  }}",
                 Ok("mydb"),
             ),
+            TestCase(
+                "no whitespace inside braces",
+                vec![("ADBC_TEST_PPV_DB", "mydb")],
+                "{{env_var(ADBC_TEST_PPV_DB)}}",
+                Ok("mydb"),
+            ),
             TestCase(
                 "invalid expression not env_var",
                 vec![],
@@ -859,11 +927,11 @@ test_key = "test_value"
             });
             std::fs::write(&profile_path, profile_content).unwrap();
 
-            let provider = FilesystemProfileProvider;
             let search_paths = search_paths_opt.map(|mut paths| {
                 paths.push(tmp_dir.path().to_path_buf());
                 paths
             });
+            let provider = 
FilesystemProfileProvider::new_with_search_paths(search_paths);
 
             let profile_arg = if name.contains("absolute") {
                 profile_path.to_str().unwrap().to_string()
@@ -871,7 +939,7 @@ test_key = "test_value"
                 profile_name.to_string()
             };
 
-            let result = provider.get_profile(&profile_arg, search_paths);
+            let result = provider.get_profile(&profile_arg);
 
             if should_succeed {
                 let profile =
diff --git a/rust/driver_manager/src/search.rs 
b/rust/driver_manager/src/search.rs
index 904daabb0..2fa9f29fd 100644
--- a/rust/driver_manager/src/search.rs
+++ b/rust/driver_manager/src/search.rs
@@ -845,7 +845,7 @@ fn get_search_paths(lvls: LoadFlags) -> Vec<PathBuf> {
 /// Returns `Status::NotFound` if the profile cannot be located in any search 
path.
 pub(crate) fn find_filesystem_profile(
     name: &str,
-    additional_path_list: Option<Vec<PathBuf>>,
+    additional_path_list: &Option<Vec<PathBuf>>,
 ) -> Result<PathBuf> {
     // Convert the name to a PathBuf to ensure proper platform-specific path 
handling.
     // This normalizes forward slashes to backslashes on Windows.
@@ -905,8 +905,8 @@ pub(crate) fn find_filesystem_profile(
 /// # Returns
 ///
 /// A vector of paths to search for profiles, in priority order.
-fn get_profile_search_paths(additional_path_list: Option<Vec<PathBuf>>) -> 
Vec<PathBuf> {
-    let mut result = additional_path_list.unwrap_or_default();
+fn get_profile_search_paths(additional_path_list: &Option<Vec<PathBuf>>) -> 
Vec<PathBuf> {
+    let mut result = additional_path_list.clone().unwrap_or_default();
 
     // Add ADBC_PROFILE_PATH environment variable paths
     if let Some(paths) = env::var_os("ADBC_PROFILE_PATH") {
@@ -1741,7 +1741,7 @@ mod tests {
                 profile_name.to_string()
             };
 
-            let result = find_filesystem_profile(&profile_arg, search_paths);
+            let result = find_filesystem_profile(&profile_arg, &search_paths);
 
             if should_succeed {
                 assert!(
@@ -1793,7 +1793,7 @@ mod tests {
 
         let result = find_filesystem_profile(
             "searched_profile",
-            Some(vec![
+            &Some(vec![
                 tmp_dir1.path().to_path_buf(),
                 tmp_dir2.path().to_path_buf(),
             ]),
@@ -1813,7 +1813,7 @@ mod tests {
             .tempdir()
             .unwrap();
 
-        let paths = 
get_profile_search_paths(Some(vec![tmp_dir.path().to_path_buf()]));
+        let paths = 
get_profile_search_paths(&Some(vec![tmp_dir.path().to_path_buf()]));
 
         assert!(paths.contains(&tmp_dir.path().to_path_buf()));
         assert!(!paths.is_empty());
@@ -1823,7 +1823,7 @@ mod tests {
 
     #[test]
     fn test_get_profile_search_paths_empty() {
-        let paths = get_profile_search_paths(None);
+        let paths = get_profile_search_paths(&None);
         // Should still return some paths (env vars, user config, etc.)
         assert!(!paths.is_empty() || paths.is_empty()); // Just verify it 
doesn't panic
     }
diff --git a/rust/driver_manager/tests/common/mod.rs 
b/rust/driver_manager/tests/common/mod.rs
index 28df83f10..408398c0a 100644
--- a/rust/driver_manager/tests/common/mod.rs
+++ b/rust/driver_manager/tests/common/mod.rs
@@ -16,6 +16,7 @@
 // under the License.
 
 use std::collections::HashSet;
+use std::ffi::{OsStr, OsString};
 use std::ops::Deref;
 use std::sync::Arc;
 
@@ -340,3 +341,29 @@ pub fn test_ingestion_roundtrip(connection: &mut 
ManagedConnection) {
 
     connection.rollback().unwrap();
 }
+
+pub struct SetEnv {
+    env_var: &'static str,
+    original_value: Option<OsString>,
+}
+
+impl SetEnv {
+    pub fn new(env_var: &'static str, new_value: impl AsRef<OsStr>) -> Self {
+        let original_value = std::env::var_os(env_var);
+        std::env::set_var(env_var, new_value);
+        Self {
+            env_var,
+            original_value,
+        }
+    }
+}
+
+impl Drop for SetEnv {
+    fn drop(&mut self) {
+        if let Some(original_value) = &self.original_value {
+            std::env::set_var(self.env_var, original_value);
+        } else {
+            std::env::remove_var(self.env_var);
+        }
+    }
+}
diff --git a/rust/driver_manager/tests/connection_profile.rs 
b/rust/driver_manager/tests/connection_profile.rs
index 8a0eae3ae..57207d25e 100644
--- a/rust/driver_manager/tests/connection_profile.rs
+++ b/rust/driver_manager/tests/connection_profile.rs
@@ -126,12 +126,10 @@ uri = ":memory:"
 fn test_filesystem_profile_load_simple() {
     let (tmp_dir, profile_path) = write_profile_to_tempfile("simple", 
&simple_profile());
 
-    let provider = FilesystemProfileProvider;
+    let search_paths = Some(vec![tmp_dir.path().to_path_buf()]);
+    let provider = 
FilesystemProfileProvider::new_with_search_paths(search_paths);
     let profile = provider
-        .get_profile(
-            profile_path.to_str().unwrap(),
-            Some(vec![tmp_dir.path().to_path_buf()]),
-        )
+        .get_profile(profile_path.to_str().unwrap())
         .unwrap();
 
     let (driver_name, init_func) = profile.get_driver_name().unwrap();
@@ -158,12 +156,10 @@ fn test_filesystem_profile_nested_options() {
     let (tmp_dir, profile_path) =
         write_profile_to_tempfile("nested", &profile_with_nested_options());
 
-    let provider = FilesystemProfileProvider;
+    let search_paths = Some(vec![tmp_dir.path().to_path_buf()]);
+    let provider = 
FilesystemProfileProvider::new_with_search_paths(search_paths);
     let profile = provider
-        .get_profile(
-            profile_path.to_str().unwrap(),
-            Some(vec![tmp_dir.path().to_path_buf()]),
-        )
+        .get_profile(profile_path.to_str().unwrap())
         .unwrap();
 
     let options: Vec<_> = profile.get_options().unwrap().into_iter().collect();
@@ -194,12 +190,10 @@ fn test_filesystem_profile_nested_options() {
 fn test_filesystem_profile_all_option_types() {
     let (tmp_dir, profile_path) = write_profile_to_tempfile("all_types", 
&profile_with_all_types());
 
-    let provider = FilesystemProfileProvider;
+    let provider =
+        
FilesystemProfileProvider::new_with_search_paths(Some(vec![tmp_dir.path().to_path_buf()]));
     let profile = provider
-        .get_profile(
-            profile_path.to_str().unwrap(),
-            Some(vec![tmp_dir.path().to_path_buf()]),
-        )
+        .get_profile(profile_path.to_str().unwrap())
         .unwrap();
 
     let options: Vec<_> = profile.get_options().unwrap().into_iter().collect();
@@ -251,22 +245,85 @@ fn test_filesystem_profile_error_cases() {
             Status::InvalidArguments,
             "unsupported profile version",
         ),
+        (
+            "no version",
+            r#"
+driver = "adbc_driver_sqlite"
+[Options]
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "missing 'profile_version' in profile",
+        ),
+        (
+            "bad version",
+            r#"
+profile_version = "1"
+driver = "adbc_driver_sqlite"
+[Options]
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "invalid 'profile_version' in profile",
+        ),
         (
             "invalid toml",
             invalid_toml().to_string(),
             Status::InvalidArguments,
-            "",
+            "TOML parse error",
+        ),
+        (
+            "no driver",
+            r#"
+profile_version = 1
+[Options]
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "missing or invalid 'driver' field in profile",
+        ),
+        (
+            "numeric driver",
+            r#"
+profile_version = 1
+driver = 2
+[Options]
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "missing or invalid 'driver' field in profile",
+        ),
+        (
+            "table driver",
+            r#"
+profile_version = 1
+[driver]
+foo = "bar"
+[Options]
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "missing or invalid 'driver' field in profile",
+        ),
+        (
+            "no options",
+            r#"
+profile_version = 1
+driver = "foo"
+"#
+            .to_string(),
+            Status::InvalidArguments,
+            "missing or invalid 'Options' table in profile",
         ),
     ];
 
     for (name, profile_content, expected_status, expected_msg_fragment) in 
test_cases {
         let (tmp_dir, profile_path) = write_profile_to_tempfile(name, 
&profile_content);
 
-        let provider = FilesystemProfileProvider;
-        let result = provider.get_profile(
-            profile_path.to_str().unwrap(),
-            Some(vec![tmp_dir.path().to_path_buf()]),
-        );
+        let provider = 
FilesystemProfileProvider::new_with_search_paths(Some(vec![tmp_dir
+            .path()
+            .to_path_buf()]));
+        let result = provider.get_profile(profile_path.to_str().unwrap());
 
         assert!(result.is_err(), "Test case '{}': expected error", name);
         let err = result.unwrap_err();
@@ -293,8 +350,8 @@ fn test_filesystem_profile_error_cases() {
 
 #[test]
 fn test_filesystem_profile_not_found() {
-    let provider = FilesystemProfileProvider;
-    let result = provider.get_profile("nonexistent_profile", None);
+    let provider = FilesystemProfileProvider::default();
+    let result = provider.get_profile("nonexistent_profile");
 
     assert!(result.is_err());
     let err = result.unwrap_err();
@@ -302,27 +359,6 @@ fn test_filesystem_profile_not_found() {
     assert!(err.message.contains("Profile not found"));
 }
 
-#[test]
-fn test_filesystem_profile_without_driver() {
-    let (tmp_dir, profile_path) = write_profile_to_tempfile("no_driver", 
&profile_without_driver());
-
-    let provider = FilesystemProfileProvider;
-    let profile = provider
-        .get_profile(
-            profile_path.to_str().unwrap(),
-            Some(vec![tmp_dir.path().to_path_buf()]),
-        )
-        .unwrap();
-
-    let (driver_name, _) = profile.get_driver_name().unwrap();
-    // Should get empty string for missing driver
-    assert_eq!(driver_name, "");
-
-    tmp_dir
-        .close()
-        .expect("Failed to close/remove temporary directory");
-}
-
 #[test]
 #[cfg_attr(not(feature = "driver_manager_test_lib"), ignore)]
 fn test_database_from_uri_with_profile() {
@@ -385,12 +421,12 @@ fn test_profile_loading_scenarios() {
     for (name, profile_name, profile_content, use_search_path, use_absolute) 
in test_cases {
         let (tmp_dir, profile_path) = write_profile_to_tempfile(profile_name, 
&profile_content);
 
-        let provider = FilesystemProfileProvider;
         let search_paths = if use_search_path {
             Some(vec![tmp_dir.path().to_path_buf()])
         } else {
             None
         };
+        let provider = 
FilesystemProfileProvider::new_with_search_paths(search_paths);
 
         let profile_arg = if use_absolute {
             profile_path.to_str().unwrap()
@@ -399,7 +435,7 @@ fn test_profile_loading_scenarios() {
         };
 
         let profile = provider
-            .get_profile(profile_arg, search_paths)
+            .get_profile(profile_arg)
             .unwrap_or_else(|e| panic!("Test case '{}' failed: {:?}", name, 
e));
 
         let (driver_name, _) = profile.get_driver_name().unwrap();
@@ -419,9 +455,9 @@ fn test_profile_loading_scenarios() {
 fn test_profile_display() {
     let (tmp_dir, profile_path) = write_profile_to_tempfile("display", 
&simple_profile());
 
-    let provider = FilesystemProfileProvider;
+    let provider = FilesystemProfileProvider::default();
     let profile = provider
-        .get_profile(profile_path.to_str().unwrap(), None)
+        .get_profile(profile_path.to_str().unwrap())
         .unwrap();
 
     let display_str = format!("{}", profile);
@@ -460,8 +496,7 @@ fn test_profile_hierarchical_path_via_env_var() {
     );
 
     // Set ADBC_PROFILE_PATH to the parent directory
-    let prev_value = env::var_os("ADBC_PROFILE_PATH");
-    env::set_var("ADBC_PROFILE_PATH", tmp_dir.path());
+    let _guard = common::SetEnv::new("ADBC_PROFILE_PATH", tmp_dir.path());
 
     // Verify the environment variable is set correctly
     assert_eq!(
@@ -470,14 +505,8 @@ fn test_profile_hierarchical_path_via_env_var() {
     );
 
     // Try to load the profile using hierarchical relative path
-    let provider = FilesystemProfileProvider;
-    let result = provider.get_profile("databases/postgres/production", None);
-
-    // Restore the original environment variable
-    match prev_value {
-        Some(val) => env::set_var("ADBC_PROFILE_PATH", val),
-        None => env::remove_var("ADBC_PROFILE_PATH"),
-    }
+    let provider = FilesystemProfileProvider::default();
+    let result = provider.get_profile("databases/postgres/production");
 
     // Verify the profile was loaded successfully
     let profile = result.expect("Failed to load profile from hierarchical 
path");
@@ -501,8 +530,6 @@ fn test_profile_hierarchical_path_via_env_var() {
 #[test]
 #[serial]
 fn test_profile_hierarchical_path_with_extension_via_env_var() {
-    use std::env;
-
     let tmp_dir = tempfile::Builder::new()
         .prefix("adbc_profile_env_test2")
         .tempdir()
@@ -518,18 +545,11 @@ fn 
test_profile_hierarchical_path_with_extension_via_env_var() {
     std::fs::write(&profile_path, simple_profile()).expect("Failed to write 
profile");
 
     // Set ADBC_PROFILE_PATH to the parent directory
-    let prev_value = env::var_os("ADBC_PROFILE_PATH");
-    env::set_var("ADBC_PROFILE_PATH", tmp_dir.path());
+    let _guard = common::SetEnv::new("ADBC_PROFILE_PATH", tmp_dir.path());
 
     // Try to load the profile using hierarchical relative path with .toml 
extension
-    let provider = FilesystemProfileProvider;
-    let result = provider.get_profile("configs/dev/database.toml", None);
-
-    // Restore the original environment variable
-    match prev_value {
-        Some(val) => env::set_var("ADBC_PROFILE_PATH", val),
-        None => env::remove_var("ADBC_PROFILE_PATH"),
-    }
+    let provider = FilesystemProfileProvider::default();
+    let result = provider.get_profile("configs/dev/database.toml");
 
     // Verify the profile was loaded successfully
     let profile = result.expect("Failed to load profile from hierarchical path 
with extension");
@@ -558,11 +578,9 @@ fn 
test_profile_hierarchical_path_additional_search_paths() {
     std::fs::write(&profile_path, simple_profile()).expect("Failed to write 
profile");
 
     // Load profile using hierarchical path via additional_search_paths
-    let provider = FilesystemProfileProvider;
-    let result = provider.get_profile(
-        "projects/myapp/local",
-        Some(vec![tmp_dir.path().to_path_buf()]),
-    );
+    let provider =
+        
FilesystemProfileProvider::new_with_search_paths(Some(vec![tmp_dir.path().to_path_buf()]));
+    let result = provider.get_profile("projects/myapp/local");
 
     // Verify the profile was loaded successfully
     let profile = result.expect("Failed to load profile from hierarchical 
path");
@@ -606,18 +624,11 @@ fn test_profile_conda_prefix() {
     std::fs::write(&filepath, simple_profile()).expect("Failed to write 
profile");
 
     // Set CONDA_PREFIX environment variable
-    let prev_value = env::var("CONDA_PREFIX").ok();
-    env::set_var("CONDA_PREFIX", tmp_dir.path());
+    let _guard = common::SetEnv::new("CONDA_PREFIX", tmp_dir.path());
 
     let uri = "profile://sqlite-profile";
     let result = ManagedDatabase::from_uri(uri, None, AdbcVersion::V100, 
LOAD_FLAG_DEFAULT, None);
 
-    // Restore environment variable
-    match prev_value {
-        Some(val) => env::set_var("CONDA_PREFIX", val),
-        None => env::remove_var("CONDA_PREFIX"),
-    }
-
     if is_conda_build {
         assert!(result.is_ok(), "Expected success for conda build");
     } else {
@@ -635,3 +646,103 @@ fn test_profile_conda_prefix() {
         .close()
         .expect("Failed to close/remove temporary directory")
 }
+
+#[test]
+#[cfg_attr(not(feature = "driver_manager_test_lib"), ignore)]
+fn test_profile_load_manifest() {
+    let driver_path = PathBuf::from(
+        env::var_os("ADBC_DRIVER_MANAGER_TEST_LIB")
+            .expect("ADBC_DRIVER_MANAGER_TEST_LIB must be set for driver 
manager manifest tests"),
+    )
+    .to_string_lossy()
+    .to_string()
+    .replace("\\", "\\\\");
+    let manifest_dir = tempfile::Builder::new()
+        .prefix("adbc-test-manifest")
+        .tempdir()
+        .unwrap();
+    let profile_dir = tempfile::Builder::new()
+        .prefix("adbc-test-profile")
+        .tempdir()
+        .unwrap();
+
+    let manifest_contents = format!(
+        r#"
+manifest_version = 1
+[Driver]
+shared = "{driver_path}"
+"#
+    );
+
+    let manifest_path = manifest_dir.path().join("sqlite.toml");
+    std::fs::write(&manifest_path, &manifest_contents).unwrap();
+
+    let manifest_path = profile_dir.path().join("sqlitemani.toml");
+    std::fs::write(&manifest_path, &manifest_contents).unwrap();
+
+    let profile_contents = r#"
+profile_version = 1
+driver = "sqlite"
+[Options]
+uri = ":memory:"
+"#;
+
+    let profile_path = profile_dir.path().join("sqlitedev.toml");
+    std::fs::write(&profile_path, profile_contents).unwrap();
+    let profile_path = manifest_dir.path().join("sqliteprof.toml");
+    std::fs::write(&profile_path, profile_contents).unwrap();
+
+    let provider = 
FilesystemProfileProvider::new_with_search_paths(Some(vec![profile_dir
+        .path()
+        .to_path_buf()]));
+    let database = ManagedDatabase::from_uri_with_profile_provider(
+        "profile://sqlitedev",
+        None,
+        AdbcVersion::V100,
+        LOAD_FLAG_DEFAULT,
+        Some(vec![manifest_dir.path().to_path_buf()]),
+        provider.clone(),
+        std::iter::empty(),
+    )
+    .unwrap();
+
+    common::test_database(&database);
+
+    // should not be able to load a profile from manifest dir or vice versa
+    let result = ManagedDatabase::from_uri_with_profile_provider(
+        "profile://sqliteprof",
+        None,
+        AdbcVersion::V100,
+        LOAD_FLAG_DEFAULT,
+        Some(vec![manifest_dir.path().to_path_buf()]),
+        provider.clone(),
+        std::iter::empty(),
+    );
+    assert!(result.is_err());
+    let err = result.err().unwrap();
+    assert!(
+        err.message.contains("Profile not found: sqliteprof"),
+        "{}",
+        err.message
+    );
+
+    let result = ManagedDatabase::from_uri_with_profile_provider(
+        "sqlitemani://",
+        None,
+        AdbcVersion::V100,
+        LOAD_FLAG_DEFAULT,
+        Some(vec![manifest_dir.path().to_path_buf()]),
+        provider.clone(),
+        std::iter::empty(),
+    );
+    assert!(result.is_err());
+    #[cfg(not(windows))]
+    {
+        // The Windows error just says 'LoadLibraryExW failed'
+        let err = result.err().unwrap();
+        assert!(err.message.contains("sqlitemani"), "{}", err.message);
+    }
+
+    manifest_dir.close().unwrap();
+    profile_dir.close().unwrap();
+}
diff --git a/rust/driver_manager/tests/test_env_var_profiles.rs 
b/rust/driver_manager/tests/test_env_var_profiles.rs
index bd35d3453..d04610267 100644
--- a/rust/driver_manager/tests/test_env_var_profiles.rs
+++ b/rust/driver_manager/tests/test_env_var_profiles.rs
@@ -18,6 +18,8 @@
 use std::env;
 use std::path::PathBuf;
 
+mod common;
+
 use adbc_core::options::AdbcVersion;
 use adbc_core::{error::Status, LOAD_FLAG_DEFAULT};
 use adbc_driver_manager::ManagedDatabase;
@@ -37,8 +39,7 @@ fn test_env_var_replacement_basic() {
         .expect("Failed to create temporary directory");
 
     // Set a test environment variable
-    let prev_value = env::var_os("ADBC_TEST_ENV_VAR");
-    env::set_var("ADBC_TEST_ENV_VAR", ":memory:");
+    let _guard = common::SetEnv::new("ADBC_TEST_ENV_VAR", ":memory:");
 
     let profile_content = r#"
 profile_version = 1
@@ -53,12 +54,6 @@ uri = "{{ env_var(ADBC_TEST_ENV_VAR) }}"
 
     let result = ManagedDatabase::from_uri(&uri, None, AdbcVersion::V100, 
LOAD_FLAG_DEFAULT, None);
 
-    // Restore environment variable
-    match prev_value {
-        Some(val) => env::set_var("ADBC_TEST_ENV_VAR", val),
-        None => env::remove_var("ADBC_TEST_ENV_VAR"),
-    }
-
     match result {
         Ok(_db) => {
             // Successfully created database with env_var replacement
@@ -198,8 +193,7 @@ fn test_env_var_replacement_interpolation() {
         .expect("Failed to create temporary directory");
 
     // Set a test environment variable
-    let prev_value = env::var_os("ADBC_TEST_INTERPOLATE");
-    env::set_var("ADBC_TEST_INTERPOLATE", "middle_value");
+    let _guard = common::SetEnv::new("ADBC_TEST_INTERPOLATE", "middle_value");
 
     let profile_content = r#"
 profile_version = 1
@@ -215,12 +209,6 @@ test_option = "prefix_{{ env_var(ADBC_TEST_INTERPOLATE) 
}}_suffix"
 
     let result = ManagedDatabase::from_uri(&uri, None, AdbcVersion::V100, 
LOAD_FLAG_DEFAULT, None);
 
-    // Restore environment variable
-    match prev_value {
-        Some(val) => env::set_var("ADBC_TEST_INTERPOLATE", val),
-        None => env::remove_var("ADBC_TEST_INTERPOLATE"),
-    }
-
     assert!(result.is_err(), "Expected error for malformed env_var");
     if let Err(err) = result {
         assert_eq!(
@@ -243,10 +231,8 @@ fn test_env_var_replacement_multiple() {
         .expect("Failed to create temporary directory");
 
     // Set test environment variables
-    let prev_var1 = env::var_os("ADBC_TEST_VAR1");
-    let prev_var2 = env::var_os("ADBC_TEST_VAR2");
-    env::set_var("ADBC_TEST_VAR1", "first");
-    env::set_var("ADBC_TEST_VAR2", "second");
+    let _guard1 = common::SetEnv::new("ADBC_TEST_VAR1", "first");
+    let _guard2 = common::SetEnv::new("ADBC_TEST_VAR2", "second");
 
     let profile_content = r#"
 profile_version = 1
@@ -262,16 +248,6 @@ test_option = "{{ env_var(ADBC_TEST_VAR1) }}_and_{{ 
env_var(ADBC_TEST_VAR2) }}"
 
     let result = ManagedDatabase::from_uri(&uri, None, AdbcVersion::V100, 
LOAD_FLAG_DEFAULT, None);
 
-    // Restore environment variables
-    match prev_var1 {
-        Some(val) => env::set_var("ADBC_TEST_VAR1", val),
-        None => env::remove_var("ADBC_TEST_VAR1"),
-    }
-    match prev_var2 {
-        Some(val) => env::set_var("ADBC_TEST_VAR2", val),
-        None => env::remove_var("ADBC_TEST_VAR2"),
-    }
-
     assert!(result.is_err(), "Expected error for malformed env_var");
     if let Err(err) = result {
         assert_eq!(
@@ -294,8 +270,7 @@ fn test_env_var_replacement_whitespace() {
         .expect("Failed to create temporary directory");
 
     // Set a test environment variable
-    let prev_value = env::var_os("ADBC_TEST_WHITESPACE");
-    env::set_var("ADBC_TEST_WHITESPACE", "value");
+    let _guard = common::SetEnv::new("ADBC_TEST_WHITESPACE", "value");
 
     let profile_content = r#"
 profile_version = 1
@@ -311,12 +286,6 @@ test_option = "{{   env_var(  ADBC_TEST_WHITESPACE  )   }}"
 
     let result = ManagedDatabase::from_uri(&uri, None, AdbcVersion::V100, 
LOAD_FLAG_DEFAULT, None);
 
-    // Restore environment variable
-    match prev_value {
-        Some(val) => env::set_var("ADBC_TEST_WHITESPACE", val),
-        None => env::remove_var("ADBC_TEST_WHITESPACE"),
-    }
-
     assert!(result.is_err(), "Expected error for malformed env_var");
     if let Err(err) = result {
         assert_eq!(


Reply via email to