fix(sql): return JS number for PostgreSQL bigint values within safe integer range

When the `bigint` option is not set (the default), PostgreSQL int8/bigint
values that fit within Number.MAX_SAFE_INTEGER (±2^53-1) are now returned
as JavaScript numbers instead of strings. Values outside that range continue
to be returned as strings to avoid precision loss. This makes common
operations like COUNT(*) return numbers as users expect.

Fixes #22188

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Bot
2026-02-14 23:48:15 +00:00
parent 38f41dccdf
commit 5d661a4487
2 changed files with 56 additions and 7 deletions

View File

@@ -2775,8 +2775,35 @@ if (isDockerEnabled()) {
// return ['select 1', result]
// })
test("bigint is returned as String", async () => {
test("bigint outside safe integer range is returned as String", async () => {
expect(typeof (await sql`select 9223372036854777 as x`)[0].x).toBe("string");
expect((await sql`select 9223372036854777 as x`)[0].x).toBe("9223372036854777");
});
test("bigint within safe integer range is returned as Number", async () => {
// Values within Number.MAX_SAFE_INTEGER should be numbers, not strings
const result = (await sql`select 9007199254740991::int8 as x`)[0].x;
expect(typeof result).toBe("number");
expect(result).toBe(9007199254740991);
// Negative safe integer boundary
const result2 = (await sql`select (-9007199254740991)::int8 as x`)[0].x;
expect(typeof result2).toBe("number");
expect(result2).toBe(-9007199254740991);
// COUNT(*) returns bigint - should be a number for typical counts
const result3 = (await sql`select count(*) from information_schema.tables`)[0].count;
expect(typeof result3).toBe("number");
});
test("bigint just outside safe integer range is returned as String", async () => {
const result = (await sql`select 9007199254740992::int8 as x`)[0].x;
expect(typeof result).toBe("string");
expect(result).toBe("9007199254740992");
const result2 = (await sql`select (-9007199254740992)::int8 as x`)[0].x;
expect(typeof result2).toBe("string");
expect(result2).toBe("-9007199254740992");
});
test("bigint is returned as BigInt", async () => {