fix(csharp): support spec-correct driver manifests#4341
Conversation
Closes apache#4329 The driver manager was parsing every TOML file as a connection profile, so real driver manifests (with `manifest_version = 1` and a string `version`) were rejected with "The 'profile_version' field has an invalid value '1.5.2'. It must be an integer." Add a proper DriverManifest parser per docs/source/format/driver_manifests.rst, with [Driver.shared] as either a single string or a platform-tuple table. Managed (.NET) driver selection moves from the C#-specific `driver_type` field on connection profiles to a scheme-prefixed entrypoint on the manifest: `dotnet:Type` for modern .NET, `netfx:Type` for .NET Framework. The host rejects a manifest whose scheme doesn't match its runtime, so mismatches fail with a clear error instead of an assembly-loader mystery. Profile-driven managed loading uses the same scheme via an `entrypoint` option in `[Options]`, which the driver manager consumes and does not forward to the driver. Also aligns env_var placeholder support with the spec syntax `{{ env_var(NAME) }}` per docs/source/format/connection_profiles.rst: placeholders may be embedded anywhere in a value, repeated, missing vars expand to "" (matching the C/C++ driver manager), and unknown functions are rejected. End-to-end coverage against DuckDB lives in DriverManifestTests.FindLoadDriver_WithRealDriverManifest_LoadsDuckDbDriver. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Managed .NET drivers use a scheme-prefixed `entrypoint`: | ||
|
|
||
| - `dotnet:` for modern .NET (.NET 5 and later, including .NET 8 / .NET 10) | ||
| - `netfx:` for .NET Framework 4.x | ||
|
|
||
| The host process rejects a manifest whose scheme doesn't match its runtime, so a `dotnet:` manifest on a .NET Framework process (or vice versa) fails with a clear error rather than mysteriously failing inside the assembly loader. |
There was a problem hiding this comment.
@ianmcook, @davidhcoe, @esadek I've taken the liberty to amend the Driver Manager spec to accommodate drivers which are .NET assemblies and non-AOT compiled. This scheme could further be generalized to e.g. reference a .jar file or a Python-based implementation, if there ever were such a thing. Use of a scheme here is a backwards-compatible way to tell the driver manager how to consume the driver -- or perhaps that it is unable to. One could imagine (implausible as it likely is) that the C++ driver manager could see dotnet: and try to load the .NET runtime to load the driver. And of course, a naive examination of the entrypoint as written would fail to find the symbol in the library.
There was a problem hiding this comment.
Thanks Curt, looks reasonable to me.
Closes #4329
The driver manager was parsing every TOML file as a connection profile, so real driver manifests (with
manifest_version = 1and a stringversion) were rejected with "The 'profile_version' field has an invalid value '1.5.2'. It must be an integer." Add a proper DriverManifest parser per docs/source/format/driver_manifests.rst, with [Driver.shared] as either a single string or a platform-tuple table.Managed (.NET) driver selection moves from the C#-specific
driver_typefield on connection profiles to a scheme-prefixed entrypoint on the manifest:dotnet:Typefor modern .NET,netfx:Typefor .NET Framework. The host rejects a manifest whose scheme doesn't match its runtime, so mismatches fail with a clear error instead of an assembly-loader mystery. Profile-driven managed loading uses the same scheme via anentrypointoption in[Options], which the driver manager consumes and does not forward to the driver.Also aligns env_var placeholder support with the spec syntax
{{ env_var(NAME) }}per docs/source/format/connection_profiles.rst: placeholders may be embedded anywhere in a value, repeated, missing vars expand to "" (matching the C/C++ driver manager), and unknown functions are rejected.End-to-end coverage against DuckDB lives in
DriverManifestTests.FindLoadDriver_WithRealDriverManifest_LoadsDuckDbDriver.