Skip to content

fix(csharp): support spec-correct driver manifests#4341

Merged
CurtHagenlocher merged 1 commit into
apache:mainfrom
CurtHagenlocher:GH-4329
May 21, 2026
Merged

fix(csharp): support spec-correct driver manifests#4341
CurtHagenlocher merged 1 commit into
apache:mainfrom
CurtHagenlocher:GH-4329

Conversation

@CurtHagenlocher
Copy link
Copy Markdown
Contributor

Closes #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.

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>
Comment on lines +59 to +64
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.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Curt, looks reasonable to me.

@CurtHagenlocher CurtHagenlocher merged commit e6818b3 into apache:main May 21, 2026
13 checks passed
@CurtHagenlocher CurtHagenlocher deleted the GH-4329 branch May 21, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

csharp: driver manager incorrectly loads and validates manifests

3 participants