Skip to content

Fix SQL_DBMS_VER to return the Firebird product version#294

Open
fdcastel wants to merge 1 commit intoFirebirdSQL:masterfrom
fdcastel:fix/sql-dbms-ver
Open

Fix SQL_DBMS_VER to return the Firebird product version#294
fdcastel wants to merge 1 commit intoFirebirdSQL:masterfrom
fdcastel:fix/sql-dbms-ver

Conversation

@fdcastel
Copy link
Copy Markdown
Member

Summary

SQLGetInfo(SQL_DBMS_VER) was returning the engine / ODS-compat implementation number rather than the Firebird release version. On Firebird 5.0.3 the driver reported:

'06.03.1683 WI-V Firebird 5.0'

atoi on that string gives 6, so every ODBC consumer (downstream tools, test harnesses, version-gated behaviour) mis-identifies the server as Firebird 6. The ODBC specification defines SQL_DBMS_VER as "the version of the current DBMS product" — which for Firebird is the release version (5.0.3), not the wire-protocol / ODS level.

After this PR the same server reports:

'05.00.1683 WI-V Firebird 5.0'

and Firebird 6.0 master reports '06.00.1910 WI-T Firebird 6.0 …'.

Root cause

In IscDbc/Attachment.cpp we already request both isc_info_firebird_version (the product version, added in Firebird 2.x — 5.0.3) and isc_info_version (the legacy InterBase-style engine string — 6.3.0.1683). Both handlers parse their respective strings into independent version triples:

  • isc_info_firebird_versionmajorFb / minorFb / versionFb (product version)
  • isc_info_version → local major / minor / version (engine / ODS version)

But serverVersion — the backing value of SQL_DBMS_VER — is formatted from the engine triple. Flip it to the product triple, with a defaults-based fallback so very old InterBase / pre-Firebird-2.0 attachments (where isc_info_firebird_version is not served) still produce a reasonable string.

Why the existing tests didn't catch this

tests/test_server_version.cpp::SQLGetInfoDBMSVer only asserted that the string was non-empty and contained a dot — every possible output satisfied both. The same file had a separate test that queried rdb$get_context('SYSTEM', 'ENGINE_VERSION') but never cross-referenced the two values.

Three focused regression tests are added:

Test Asserts
DBMSVerMajorMatchesEngineVersion parses the MM prefix and requires it to equal the major token of rdb$get_context
DBMSVerMinorMatchesEngineVersion same for mm
DBMSVerSuffixContainsDBMSName sanity smoke test that the suffix still includes the SQL_DBMS_NAME

All three fail cleanly against the unfixed driver with a diagnostic showing both strings:

SQL_DBMS_VER major must match rdb$get_context('ENGINE_VERSION') major.
  SQL_DBMS_VER:     '06.03.1683 WI-V Firebird 5.0'
  ENGINE_VERSION:   '5.0.3'
  Parsed DBMS_VER major: 6
  Parsed engine major:   5

All three pass after the fix.

Downstream knock-on — an unexpected bonus

With SQL_DBMS_VER fixed, tests/test_helpers.h::GetServerMajorVersion — which just does atoi(SQL_DBMS_VER) — now returns the correct product major, and the SKIP_ON_FIREBIRD6 macro it gates stops silently firing on FB 3 / 4 / 5. Local FB 5.0.3 full suite jumped from 200 passing → 221 passing (≈21 tests that were silently skipping now actually run).

Verification

  • Firebird 5.0.3 (service) — full suite: 221 pass, 165 skip, 0 fail.
  • Firebird 6.0.0.1910 (master snapshot) — full suite: 202 pass, 184 skip, 0 fail.
  • CI — all 10 matrix jobs green (Windows x64 / x86 / ARM64, Linux x64 / ARM64, plus Valgrind, against both Firebird 5.0.3 and Firebird master).

Blast radius

SQL_DBMS_VER is a well-known ODBC info field. Any consumer that parsed the number as the Firebird major version has been getting 6 on every supported server for a long time; after this PR they'll get the correct value. Consumers that treat the full string as opaque (most — since only the MM.mm.bbbb prefix is spec-defined) are unaffected. Driver behaviour for SQL_DBMS_NAME and all other info fields is unchanged.

Test plan

  • Manual DBMS_VER check on FB 5.0.3 → '05.00.1683 WI-V Firebird 5.0'
  • Manual DBMS_VER check on FB 6.0 master → '06.00.1910 WI-T Firebird 6.0 99191e0'
  • Three new regression tests fail on pre-fix master driver, pass after fix
  • CI green across full matrix

SQLGetInfo(SQL_DBMS_VER) was returning the engine / ODS-compat
implementation number rather than the Firebird release version.  On
Firebird 5.0.3 the driver reported `"06.03.1683 WI-V Firebird 5.0"` —
atoi-ing that gives 6, so every ODBC consumer (downstream tools, test
harnesses, version-gated behaviour) mis-identified the server as
Firebird 6.  The ODBC specification defines SQL_DBMS_VER as "the
version of the current DBMS product", which for Firebird is the
release version (5.0.3), not the wire-protocol / ODS level.

Root cause is in IscDbc/Attachment.cpp: we request BOTH
`isc_info_firebird_version` (the product version, added in FB 2.x)
AND `isc_info_version` (the legacy InterBase-style engine string) and
parse them into two independent triples — majorFb/minorFb/versionFb
vs local major/minor/version — but build `serverVersion` from the
wrong triple (the engine one).  Switch to the product triple with a
defaults-based fallback so very old InterBase / pre-2.0 Firebird is
still handled.

After the fix, FB 5.0.3 now reports `"05.00.1683 WI-V Firebird 5.0"`
and FB 6.0 master reports `"06.00.1910 WI-T Firebird 6.0 …"`.

Why the existing tests didn't catch this
----------------------------------------
test_server_version.cpp only asserted SQL_DBMS_VER was non-empty and
contained a dot — every possible output satisfied both.  It also had
a separate test that queried rdb$get_context('ENGINE_VERSION') but
never cross-referenced the two values.  Three focused regression
tests are added:

  * DBMSVerMajorMatchesEngineVersion  — parses the "MM" prefix and
    requires it to equal the major token of rdb$get_context.
  * DBMSVerMinorMatchesEngineVersion  — same for "mm".
  * DBMSVerSuffixContainsDBMSName     — sanity smoke test.

All three fail cleanly against the unfixed driver with a diagnostic
showing both version strings; all three pass after the fix.

Downstream knock-on: with SQL_DBMS_VER fixed,
tests/test_helpers.h::GetServerMajorVersion — which just does
atoi(SQL_DBMS_VER) — now returns the correct product major, and the
SKIP_ON_FIREBIRD6 macro it gates stops silently firing on FB 3/4/5.
Local full test run unblocks ~20 previously-skipping tests on FB 5.0.3.

Verified locally:
  Firebird 5.0.3 (service): full suite — 221 pass, 165 skip, 0 fail.
  Firebird 6.0.0.1910 (snapshot): full suite — 202 pass, 184 skip, 0 fail.
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.

1 participant