diff --git a/src/docs/asciidoc/release_notes.adoc b/src/docs/asciidoc/release_notes.adoc index 5f2fee798..fd6cbc41e 100644 --- a/src/docs/asciidoc/release_notes.adoc +++ b/src/docs/asciidoc/release_notes.adoc @@ -816,7 +816,7 @@ Configuring values less than 512 will be ignored and use 512 instead. [#blob-performance-max-segment] ==== Maximum segment size raised -For connections to Firebird 2.1 and higherfootnote:[Formally, only Firebird 3.0 and higher are supported], the maximum segment size was raised from 32765 to 65535 bytes to match the maximum segment size supported by Firebird. +For connections to Firebird 3.0 and higher, the maximum segment size was raised from 32765 to 65535 bytes to match the maximum segment size supported by Firebird. The maximum segment size is the maximum size for sending segments (_put_) to the server. Due to protocol limitations, retrieving segments from the server (_get_) is two bytes (or multiples of two bytes) shorterfootnote:[For _get_ the maximum segment size is actually the maximum buffer size to receive one or more segments which are prefixed with two bytes for the length]. diff --git a/src/main/org/firebirdsql/gds/ng/AbstractFbBlob.java b/src/main/org/firebirdsql/gds/ng/AbstractFbBlob.java index d70b8dc72..ed8671540 100644 --- a/src/main/org/firebirdsql/gds/ng/AbstractFbBlob.java +++ b/src/main/org/firebirdsql/gds/ng/AbstractFbBlob.java @@ -451,15 +451,19 @@ public int getMaximumSegmentSize() { } private static int maximumSegmentSize(FbDatabase db) { - // Max size in FB 2.1 and higher is 2^16 - 1, not 2^15 - 3 (IB 6 docs mention max is 32KiB) - if (db != null && db.getServerVersion().isEqualOrAbove(2, 1)) { + /* Max size in FB 2.1 and higher is 2^16 - 1, not 2^15 - 3 (IB 6 docs mention max is 32KiB). However, + Firebird 2.1 and 2.5 have issues with conversion from SSHORT to 32-bit (applying sign extension), leading to + incorrect buffer sizes, instead of addressing that, we only apply the higher limit for Firebird 3.0 and + higher. */ + if (db != null && db.getServerVersion().isEqualOrAbove(3)) { /* NOTE: getSegment can retrieve at most 65533 bytes of blob data as the buffer to receive segments is max 65535 bytes, but the contents of the buffer are one or more segments prefixed with 2-byte lengths; putSegment can write max 65535 bytes, because the buffer *is* the segment */ return 65535; } - // NOTE: This should probably be Short.MAX_VALUE, but we can no longer run the relevant tests on Firebird 2.0 - // and older (which aren't supported any way), so we leave this as is + /* NOTE: This should probably be Short.MAX_VALUE, but we can no longer run the relevant tests on Firebird 2.0 + and older (which aren't supported any way), and for Firebird 2.1 and 2.5, this may cause the same issue with + sign extension and buffer sizes mentioned above, so we leave this as is. */ return Short.MAX_VALUE - 2; }