From d9459f8540b66b49bd973e037b807bc86abc2960 Mon Sep 17 00:00:00 2001 From: Angus Comrie Date: Sat, 20 Dec 2025 00:49:12 +0200 Subject: [PATCH] Fix postgres empty check when handling arrays (#25607) ### What does this PR do? Closes #25505. This adjusts the byte length check in `DataCell: fromBytes` to 12 bytes instead of 16, as zero-dimensional arrays will have a shorter preamble. ### How did you verify your code works? Test suite passes, and I've added a new test that fails in the main branch but passes with this change. The issue only seems to crop up when a connection is _reused_, which is curious. --- src/sql/postgres/DataCell.zig | 2 +- test/js/sql/sql.test.ts | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sql/postgres/DataCell.zig b/src/sql/postgres/DataCell.zig index e020f14731..70d8196500 100644 --- a/src/sql/postgres/DataCell.zig +++ b/src/sql/postgres/DataCell.zig @@ -461,7 +461,7 @@ pub fn fromBytes(binary: bool, bigint: bool, oid: types.Tag, bytes: []const u8, // TODO: .int2_array, .float8_array inline .int4_array, .float4_array => |tag| { if (binary) { - if (bytes.len < 16) { + if (bytes.len < 12) { return error.InvalidBinaryData; } // https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/arrayfuncs.c#L1549-L1645 diff --git a/test/js/sql/sql.test.ts b/test/js/sql/sql.test.ts index ade5843122..5067ec783c 100644 --- a/test/js/sql/sql.test.ts +++ b/test/js/sql/sql.test.ts @@ -12342,5 +12342,25 @@ CREATE TABLE ${table_name} ( }); }); }); // Close "Misc" describe + test("Handles empty integer array stored as {}", async () => { + await using db = postgres(options); + const tableName = `test_${randomUUIDv7("hex").replaceAll("-", "")}`; + + await db`CREATE TEMPORARY TABLE ${db(tableName)} (id SERIAL PRIMARY KEY, numbers INTEGER[])`; + + // Inserting using the SQL array constructor triggers the "Failed to read data" error on SELECT. + await db`INSERT INTO ${db(tableName)} (numbers) VALUES (ARRAY[]::integer[])`; + + // Read back - this succeeds on the first try + const result1 = await db`SELECT * FROM ${db(tableName)}`; + expect(result1).toBeArray(); + expect(Array.from(result1[0].numbers)).toEqual([]); + + // Second read to trigger connection reuse issue + // This is where it fails with ERR_POSTGRES_INVALID_BINARY_DATA in bun 1.3.5 + const result2 = await db`SELECT * FROM ${db(tableName)}`; + expect(result2).toBeArray(); + expect(Array.from(result2[0].numbers)).toEqual([]); + }); }); // Close "PostgreSQL tests" describe } // Close if (isDockerEnabled())