Firebird Adds Optional Static fbclient Libraries, Including Symbol-Collision Prevention

Firebird’s client library, libfbclient / fbclient.dll, has always been distributed exclusively as a shared library. PR #9104 by Adriano dos Santos Fernandes, merged into the Firebird source tree on July 24, 2026, changes that: it introduces an optional, non-default static archive (libfbclient.a on POSIX, fbclient_static.lib on Windows) for applications that need to link the client library statically instead of loading it as a shared object/DLL.

Why static linking wasn’t offered before

The blocker wasn’t packaging — it was memory management. Firebird overrides the global C++ operators operator new, operator new[], operator delete, and operator delete[] (in src/common/classes/alloc.cpp) so that any bare, non-pool allocation inside Firebird is routed through its own internal memory pool.

In the shared library, this is harmless: a POSIX version script (and a Windows .def file) keeps those overridden symbols hidden, so an application linking against libfbclient.so or fbclient.dll keeps its own global allocator untouched.

A static archive has no such boundary. Its object files get merged directly into the host application at link time, so the linker would silently resolve the host’s own bare new/delete calls to Firebird’s internal definitions — hijacking the host application’s memory allocation without any warning. That’s a nasty, hard-to-diagnose class of bug, and it’s exactly why a static build was never shipped.

The fix: rename every internal symbol at the archive level

Rather than hand-maintain a list of symbols to hide, the PR takes a systematic approach: every internal global symbol not part of Firebird’s public API gets renamed with a __fbclient_ prefix as a post-processing step on the compiled archive. This covers the global operators, decNumber symbols, C++ mangled names, vtables, typeinfo, guard variables — everything — generated automatically from the existing export list rather than curated by hand.

On POSIX (Linux and macOS), this happens in two steps:

  1. Archive slimmingld -r with -u flags seeded from every symbol in builds/posix/firebird.vers pulls in only the archive members actually reachable from the public API, using cross-reference output (--cref on ELF, -map on Darwin) to identify and repack just those members.
  2. Symbol renamingobjcopy --redefine-syms (GNU objcopy on Linux, llvm-objcopy on macOS) renames every non-API global symbol to a __fbclient_-prefixed name, using a rename map generated automatically via nm --defined-only -g.

On Windows, a new fix_fbclient_static.bat parses builds/win32/defs/firebird.def for the public API, runs llvm-nm on every object file to collect defined symbols, and applies the same kind of rename map with llvm-objcopy --redefine-syms.

Regular pool-based allocation via FB_NEW / FB_NEW_POOL — the pattern used throughout the Firebird codebase — was never affected by any of this, since it never touched the global operators in the first place.

A side effect: no DllMain on Windows

A statically linked fbclient has no separate DLL module, so DllMain never runs for it. The one real functional gap this closes is per-thread cleanup, previously tied to DllMain‘s DLL_THREAD_DETACH notification. The PR adds a new ThreadCleanup class using Fiber-Local Storage (FlsAlloc/FlsSetValue/FlsFree) on Windows, mirroring what pthread_key_create‘s destructor already gives the POSIX build for free.

Building it

POSIX:

make -C temp/debug TARGET=Debug client_static

produces <firebird>/lib/libfbclient.a. Most third-party dependencies (tommath, tomcrypt) still need to be linked separately; decNumber/libdecFloat is merged directly into the archive.

Windows:

builds\win32\make_all.bat CLIENT_ONLY=STATIC

builds yvalve as fbclient_static.lib under new DebugStatic/ReleaseStatic configurations, then runs the symbol-fixup script automatically.

What’s in the diff

25 files changed, +2168/-268 lines, across three commits, including new CI workflows (.github/workflows/static-build.yml) to build and validate the static client on Linux, macOS, and Windows, and a new, thorough doc/README.StaticClient.md covering the rationale, build steps, and verification commands for both platforms.

For any project embedding Firebird’s client library directly into a host binary, this closes a real gap — and it does it without punting the symbol-collision risk onto the integrator.

Source: FirebirdSQL/firebird PR #9104. Also posted on Mariuz’s Blog.

IBX for Lazarus 2.7.11 and 2.7.12 released

MWA Software has published two bug-fix releases of IBX for Lazarus, the Lazarus components for accessing Firebird databases.

2.7.11 (2 June) fixes field-to-column mapping when a SELECT uses aggregate or concatenation functions without an explicit alias. Firebird reports the same alias name for each function of a given type, and IBX’s disambiguation could previously associate fields with the wrong column.

2.7.12 (21 June, Build 1676) ensures that ApplyUpdates respects “OLD_” parameter values in custom update SQL — typically when updating a key field and the WHERE clause refers to the old key value (WHERE MYKEY = :OLD_MYKEY). Regression tests 4, 18 and 20 were extended to cover key updates.

Downloads are available from the GitHub release pages above or via the Lazarus Online Package Manager.

node-firebird v2.6.0 – v2.14.0: roadmap complete, issue tracker at zero

The pure-JavaScript node-firebird driver for Node.js shipped eight releases in under a week (v2.6.0 – v2.14.0), completing its entire roadmap and closing all 47 open issues — some dating back to 2015.

Highlights for Firebird users:

  • Firebird 6.0 Protocol 20 fully supported — the long-standing prepare hang was root-caused and fixed (v2.10.0)
  • The sporadic Srp/Srp256 authentication failure solved — ~1.2–1.7% of attaches failed with “Your user name and password are not defined”; retry workarounds can be retired (v2.8.1)
  • Real single-byte codepage support — WIN1250–WIN1258, ISO8859_2–9/13, KOI8R/KOI8U, DOS866, encode and decode (v2.13.0)
  • Firebird 4 batch API — bulk inserts via executeBatch (5–10× faster) and a new batchStream writable stream
  • Multi-host pooling (poolCluster) for primary/replica topologies on Firebird 4+ logical replication (v2.14.0)
  • Tagged-template queries, savepoints, affectedRows metadata, query cancellation with AbortSignal, first-class ESM

Read the full write-up on Mariuz’s blog.

Get it from npm, browse the code on GitHub, or see the detailed release notes.

Laravel-Firebird (Benson Fork)

TL;DR

We started from an already working, mature Firebird driver for Laravel and brought it to real parity with the first-party drivers (MySQL, PostgreSQL, SQL Server). The result: from an estimated ~51% to ~96% functional parity, 216 tests running against Firebird 3, 4 and 5 (dialects 1 and 3), ~87% line coverage, and a green CI across the whole matrix (PHP 8.3/8.4 × Firebird 3/4/5).

This write-up is for people who live and breathe Firebird — the details below are engine-specific.

The codebase it builds on

benson/laravel-firebird is a fork of harrygulliford/laravel-firebird, which itself descends from the pioneering jacquestvanzuydam/laravel-firebird. Much of the foundation (query grammar, schema grammar, Eloquent integration, FIRST/SKIP pagination, INSERT ... RETURNING, MERGE-based upsert, join mutations via RDB$DB_KEY) already came from that prior work. What we describe here is the refinement and parity layer we built on top of that base.

Why it matters

Firebird has quirks no generic ORM handles on its own: case-sensitive identifiers when quoted, DATE with no time part in dialect 3, NUMERIC/DECIMAL stored as a scaled integer, no lastInsertId(), dialect 1 without delimited identifiers… each one can become a silent production bug. We tackled them head-on.

Real, Firebird-specific bug fixes

1. Scale loss on DECIMAL/NUMERIC (the nastiest one).
Inserting the PHP integer 40 into a DECIMAL(5,2) column stored 0.40 — off by 100×. Cause: Laravel binds integers with PDO::PARAM_INT, and pdo_firebird treats them as the column’s raw scaled value. We now bind integers as PARAM_STR, and Firebird converts the literal to the column type with the correct scale. Strings, floats, where clauses and booleans stay untouched.

2. dropAllTables() with legacy uppercase names.
Tables created without quotes live in UPPERCASE in the catalog (AUDITORIA). Introspection returned the name lowercased, and DROP TABLE "auditoria" failed with -607 Table does not exist. Dropping now uses the real catalog name, working for lowercase (quoted), UPPERCASE (legacy) and mixed-case tables in the same database.

3. date cast triggering conversion errors.
In dialect 3, DATE has no time. Laravel formats every date as Y-m-d H:i:s, and Firebird rejected it with -413 conversion error from string. We ship a SerializesFirebirdDates trait (and a base model) that stores date columns without the time component while keeping datetime intact — using the cast you already declare.

4. exists() over UNION queries.
FIRST 1 was applied only to the first union branch. We now wrap the query in a derived table before limiting.

Server-version aware features

Read more

Jaybird 6.0.5 and Jaybird 5.0.12 released

We are happy to announce the release of Jaybird 6.0.5 and Jaybird 5.0.12, providing bug fixes. Jaybird is the Firebird JDBC driver.

Changes

The following was fixed or changed in Jaybird 6.0.5:

  • JDBC 4.5 support: JaybirdTypeCodes.DECFLOAT and JaybirdType.DECFLOAT now use type code 2015 instead of -6001 (#906)
  • JDBC 4.5 support: implemented methods enquoteIdentifier, enquoteLiteral, enquoteNCharLiteral, and isSimpleIdentifier on FBConnection, and added them to interface FirebirdConnection for access in older Java versions (#908)
  • JDBC 4.5 support: implemented “disable escape processing” JDBC escape ({\…\}) (#909)
  • JDBC 4.5 support: FBDatabaseMetaData.getJDBCMinorVersion() should report 5 (for JDBC 4.5) on Java 26 and higher (#915)
  • Fixed: JDBC escapes should not be parsed inside dialect 3 delimited identifiers or dialect 1 string literals (#921)
  • Fixed: IndexOutOfBoundsException in FBCachedBlob.getBytes(long, int) for position or length beyond end of data (#923)
  • Fixed: Using native client, password is limited to 255 bytes (#925)
  • Fixed: Infinite loop in FBPooledConnection#fireConnectionError(SQLException) if the exception has a chained exception and neither is fatal (#927)

The following was fixed or changed in Jaybird 5.0.12:

  • JDBC 4.5 support: JaybirdTypeCodes.DECFLOAT and JaybirdType.DECFLOAT now use type code 2015 instead of -6001 (#917)
  • JDBC 4.5 support: implemented methods enquoteIdentifier, enquoteLiteral, enquoteNCharLiteral, and isSimpleIdentifier on FBConnection, and added them to interface FirebirdConnection for access in older Java versions (#918)
  • JDBC 4.5 support: implemented “disable escape processing” JDBC escape ({\…\}) (#920)
  • Fixed: JDBC escapes should not be parsed inside dialect 3 delimited identifiers or dialect 1 string literals (#922)
  • Fixed: IndexOutOfBoundsException in FBCachedBlob.getBytes(long, int) for position or length beyond end of data (#924)
  • Fixed: Using native client, password is limited to 255 bytes (#926)
  • Fixed: Infinite loop in FBPooledConnection#fireConnectionError(SQLException) if the exception has a chained exception and neither is fatal (#928)
  • JDBC 4.5 support: FBDatabaseMetaData.getJDBCMinorVersion() should report 5 (for JDBC 4.5) on Java 26 and higher (#929)

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

Jaybird 6.0.5

Jaybird 6 supports Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 17, Java 21, Java 25, and Java 26.

See also:

Jaybird 5.0.12

Jaybird 5 supports Firebird 2.5, Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 8, Java 11, Java 17, Java 21, Java 25, and Java 26 (support for Java 11 and higher using the Java 11 version of the driver). 

See also:

Jaybird 6.0.4 and Jaybird 5.0.11 released

We are happy to announce the release of Jaybird 6.0.4 and Jaybird 5.0.11, providing bug fixes. Jaybird is the Firebird JDBC driver.

Changes

The following was fixed or changed in Jaybird 6.0.4:

  • Fixed: Statement close of a leaked statement by the cleaner did not detect fatal connection errors (#879)
  • Fixed: Statement.cancel() causes lockup (#892)
  • Fixed: Negative buffer size on Firebird 2.5 if information response is 32KiB or greater (#895)
  • Fixed: FBServiceManager.getAuthPlugins() reported the dbCryptConfig value (#901)
  • Dependency update: updated net.java.dev.jna:jna-jpms from 5.17.0 to 5.18.1 (used by jaybird-native) (#910)
  • Dependency update: updated org.bouncycastle:bcprov-jdk18on from 1.81 to 1.83 (used by chacha64-plugin) (#912)
  • Fixed: FBDatabaseMetaData.getJDBCMinorVersion() should report 4 (for JDBC 4.4) on Java 24 and higher (#913)

The following was fixed or changed in Jaybird 5.0.11:

  • Backported fatal error detection improvements for FBPooledConnection from Jaybird 6 (#899)
  • Fixed: FBServiceManager.getAuthPlugins() reported the dbCryptConfig value (#902)
  • Fixed: Statement.cancel() causes lockup (#904)
  • Fixed: Incomplete detection of fatal connection errors for deferred actions (#905)
  • Dependency update: updated net.java.dev.jna:jna from 5.17.0 to 5.18.1 (used by native and embedded protocols) (#911)
  • Fixed: FBDatabaseMetaData.getJDBCMinorVersion() should report 4 (for JDBC 4.4) on Java 24 and higher (#914)

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

Jaybird 6.0.4

Jaybird 6 supports Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 17, Java 21, and Java 25.

See also:

Jaybird 5.0.11

Jaybird 5 supports Firebird 2.5, Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 8, Java 11, Java 17, Java 21, and Java 25 (support for Java 11 and higher using the Java 11 version of the driver). 

See also:

Jaybird 5.0.10 released

We are happy to announce the release of Jaybird 5.0.10, providing a bug fix. Jaybird is the Firebird JDBC driver.

The following was fixed or changed since Jaybird 5.0.9:

  • Fixed: Negative buffer size on Firebird 2.5 if information response is 32KiB or greater (#894)

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

Jaybird 5 supports Firebird 2.5, Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 8, Java 11, Java 17, Java 21, and Java 24 (support for Java 11 and higher using the Java 11 version of the driver). 

See also:

Jaybird 6.0.3 and Jaybird 5.0.9 released

We are happy to announce the release of Jaybird 6.0.3 and Jaybird 5.0.9, providing bug fixes. Jaybird is the Firebird JDBC driver.

Changes

The following was fixed or changed in Jaybird 6.0.3:

  • Fixed: statement close could cause a hang of the connection (#876)
  • Fixed: ResultSet move incorrectly closes input Clob (#880)
  • Fixed: Batch execution with multiple empty strings resulted in error “Repeated blob id 0:0 in registerBlob()” (#888)
  • Dependency update: updated org.bouncycastle:bcprov-jdk18on from 1.80 to 1.81 (used by chacha64-plugin) (#889)
  • Fixed: On Java 24, Connection.abort, Connection.setNetworkTimeout, and OperationMonitor.initOperationAware always throw “java.lang.SecurityException: checking permissions is not supported” (#890)

The following was fixed or changed in Jaybird 5.0.9:

  • Fixed: ResultSet move incorrectly closes input Clob (#881)

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

Jaybird 6.0.3

Jaybird 6 supports Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 17, Java 21, and Java 24.

See also:

Jaybird 5.0.9

Jaybird 5 supports Firebird 2.5, Firebird 3.0, Firebird 4.0, and Firebird 5.0, on Java 8, Java 11, Java 17, Java 21, and Java 24 (support for Java 11 and higher using the Java 11 version of the driver). 

See also:

Jaybird 6.0.2 and Jaybird 5.0.8 released

We are happy to announce the release of Jaybird 6.0.2 and Jaybird 5.0.8. Both releases provide support for upcoming Firebird 5.0.3 inline blobs, and some other improvements.

For more information on inline blobs, for Firebird 5.0.3 and higher, see also New Article: Data access methods used in Firebird.

Changes

The following was fixed or changed since Jaybird 6.0.1 / Jaybird 5.0.7:

  • Improvement: added authPlugins property on FBManager (#866 / #865)
  • Improvement: increased default and maximum SQL info sizes used for retrieving statement information like columns, parameters and plan information (#869 / #868)
  • Improvement: backported inline blob support (Firebird 5.0.3 and higher) from Jaybird 7 (#870 / #871)
  • Improvement: The time zone mapping was updated (#874 / #875)

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

Jaybird 6.0.2

Jaybird 6 supports Firebird 3.0 and higher, on Java 17, Java 21, and Java 24.

See also:

Jaybird 5.0.8

Jaybird 5 supports Firebird 2.5 and higher, on Java 8, Java 11, Java 17, Java 21, and Java 24 (support for Java 11 and higher using the Java 11 version of the driver). 

See also:

Jaybird 6.0.1 and Jaybird 5.0.7 released

We are happy to announce the release of Jaybird 6.0.1 and Jaybird 5.0.7. Both releases provide a number of performance improvements to blob handling, and some bug fixes.

We plan to offer more blob performance improvements in upcoming releases of Jaybird 5 and 6, for Firebird 5.0.3 and higher (see also New Article: Data access methods used in Firebird).

Jaybird 6.0.1

The following was fixed or changed since Jaybird 6.0.0:

  • Improvement: backported deferred blob open optimization from Jaybird 7 (#842)
  • Fixed: NullPointerException in getGeneratedKeys() with blob columns after (auto)commit (#846)
  • Fixed: Fetch response with status=0 (FETCH_OK) and count=0 was logged on DEBUG as an unexpected response (#848)
  • Improvement: backported fetching all known blob info items on open from Jaybird 7 (#852)
  • Dependency update: updated net.java.dev.jna:jna-jpms from 5.16.0 to 5.17.0 (used by jaybird-native) (#854)
  • Dependency update: updated org.bouncycastle:bcprov-jdk18on from 1.79 to 1.80 (used by chacha64-plugin) (#856)

Jaybird 6 supports Firebird 3.0 and higher, on Java 17, Java 21, and Java 24.

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

See also:

Jaybird 5.0.7

The following has been changed or fixed since Jaybird 5.0.6:

  • Improvement: backported deferred blob open optimization from Jaybird 7 (#841)
  • Fixed: NullPointerException in getGeneratedKeys() with blob columns after (auto)commit (#846)
  • Fixed: Fetch response with status=0 (FETCH_OK) and count=0 was logged on DEBUG as an unexpected response (#848)
  • Improvement: backported performance improvements for blob reading and writing from Jaybird 6 (#850)
  • Improvement: backported fetching all known blob info items on open from Jaybird 7 (#852)
  • Dependency update: updated net.java.dev.jna:jna-jpms from 5.15.0 to 5.17.0 (used by native and embedded protocols) (#855)

Jaybird 5 supports Firebird 2.5 and higher, on Java 8, Java 11, Java 17, Java 21, and Java 24 (support for Java 11 and higher using the Java 11 version of the driver).

Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to Firebird-java or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.

See also:

1 2 3 58