Skip to content

Standardise DB-version detection & feature gating across dialects (connection-level, strict/non-strict) #6330

@mercmobily

Description

@mercmobily

Issue: Standardise DB-version detection and feature gating across dialects (connection-level, strict/non-strict)

I propose a unified approach for detecting server/version/capabilities and using that information for feature gating across all dialects achieving these goals:

  1. Normalise how we detect server/version/capabilities across all dialects.
  2. Make feature gating consistent, documented, and easy to use.
  3. Provide connection-level granularity (no client-level implicit reuse across pooled connections, unless indicated in options).
  4. Provide configurable behaviour:
    • Strict mode: fail if we cannot positively assert expected environment/capability.
    • Non-strict mode: degrade gracefully, log warnings.
    • Optional assume version override: user declares expected version/capabilities and we skip detection (or treat as satisfied). Skip detection?
  5. Ship safely: defaults must not break existing users unexpectedly.

Standardised “capabilities” contract

Each dialect provides a function that will query the database, receive the response, and and resolve:

  • serverName (string-ish, optional) and/or dialectName
  • serverVersion (numeric-ish; semver? )
  • possibly rawVersionString for diagnostics

Version selection/parsing

  • Each dialect’s detector may return a raw string and/or parsed numeric parts.
  • A shared normaliser picks the canonical numeric representation we use for gates.
  • If parsing fails, treat as unknown.

Feature gates helpers (addendum)

Provide helpers so dialect/feature code can say:

  • “requires >= X” OR “requires capability flag”
  • if unknown, behavior depends on strict/non-strict mode (default: assume lowest & warn)

Flags?

We could go further, and have the idea of "features": the version checker could generate, given the version, a list of "available features". These would be dialect-specific. It would not be a normalised, dialect-agnostic set of features; on the contrary, it would be a list of "flags" which can easily be checked in the dialect's code. This will make the code much more readable.


Context (discussion transcript)

mercmobily — 11:32
A unified, standard check on versions, meaning that every dialect does it. And

have it so that it happens by default at client-level, but it can be overridden to happen at connection level, for each connection
have it so that it will either throw a warning, or will assume the lowest possible number
document clearly how to make gates -- or even provide helpers so that if there is no verson, it will be assumed the lowest version

Each "version" control might return a string and a number, and the function that picks it will have to decide what name/version number to use

myndzi — 11:32
if we have "connection level" we don't need "client level"
client is meaningless in that case

mercmobily — 11:32
Well it would mean "do it once" or "do it every time"

myndzi — 11:32
though i seem to recall there's an option where we can specify the version of support we expect, and then skip the check
i would just override the connection-specific check with that value if specified

mercmobily — 11:33
Yeah
Sorry for the interruption

myndzi — 11:33
if we have connection-level granularity, it's meaningless to assign the version from one connection to all connections
i'm down with the idea of a strict mode, where it will fail to connect if the assertion isn't satisfied (e.g. require connections to support this)
and alternatively, the "assume this version" is fine by me too
(though personally i'd never use it - i don't expect that the extra overhead of a single query that is going to be extremely fast for a long-lived connection is huge)
so kinda to your point, the user can select their level of strictness:
have it so that it will either throw a warning, or will assume the lowest possible number
strict mode = error if we can't positively assert the expected environment. the migration path is that this is not enabled by default, which assuages my worry about pushing a change that breaks someone's shit
non-strict mode = gracefully degrade, log warnings
it's the kind of thing that people can set in testing / staging
we had something like that at stripe for tests, i forget what it was called
basically it'd throw on test but not in production, so that we didn't take down some app for an edge case that didn't get tested

mercmobily — 11:39
But this is not part of this commit right?

myndzi — 11:39
correct
since that discussion is closed, i'm popping off the stack to your initial query
which was about fixing this systematically -- a thing i'm very bullish on 🙂
so like:
add the feature in a safe way (CI mentality: master should always be "passing" - in this case, i'm substituting "passing" for "i'd feel good about publishing to NPM)
as a new PR, introduce an architectural change to normalize version detection for the purpose of feature gating

mercmobily — 11:48
Yeah agreed
But I will make an issue, not a PR. we want less PRs, not more...


Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions