Skip to content

All database providers are loaded regardless of which one is configured #47

Description

@datadot

Summary

Every database provider's assemblies are loaded on any run, whichever provider the config actually names. That means a PostgreSQL-only user still loads — and still ships — the SQL Server, MySQL and CockroachDB providers, along with System.Data.SqlClient, MySql.Data and Npgsql.

Why it happens

SelectDbProvider, EnsureDb, DropDb and SelectJournal in ConfigurationHelper each reference every provider inside a single method body. The CLR resolves a method's assembly references when that method is JIT-compiled, so calling any one of them pulls in all of them.

Reproduction

Install the tool, delete one provider assembly you do not use, and run a PostgreSQL migration:

rm ~/.dotnet/tools/.store/dbup-cli/1.8.1/dbup-cli/1.8.1/tools/net7.0/any/dbup-cockroachdb.dll
dbup upgrade --ensure
Could not load file or assembly 'dbup-cockroachdb, Version=1.0.4.0,
Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

It fails before it reads the config.

Why it matters

Beyond startup cost, it means unused providers cannot be removed from a container image. System.Data.SqlClient 4.6.0 as shipped is CVE-2024-0056, and today there is no way for a PostgreSQL user to drop it — the tool stops working.

Suggested fix

Route each provider's work through a small [MethodImpl(MethodImplOptions.NoInlining)] method whose signature uses only dbup-core types. The dispatching switch then names no provider type directly, so its JIT does not resolve them. NoInlining is the load-bearing part — without it the JIT can fold the body back into the caller.

No behaviour change: same providers, same order, same errors.

I have a patch with before/after verification — building master and the patched branch, deleting every non-PostgreSQL provider assembly from each, and running a real 171-script migration against PostgreSQL 16. master fails as above; the patched build reports Upgrade successful. PR follows.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions