drizzle-team / drizzle-team/drizzle-orm

[BUG]: Querying relations which contain bigint columns from Pglite causes precision loss

Open
#3,106 3 comments 7 reactions 0 assignees View on GitHub
bug db/postgres driver/pglite priority qb/cte
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### What version of `drizzle-orm` are you using?

0.33.0

### What version of `drizzle-kit` are you using?

0.24.2

### Describe the Bug

Drizzle-ORM queries relations from PostgreSQL as JSON arrays. Pglite uses the following parser when it encounters a JSON data type:

https://github.com/electric-sql/pglite/blob/0c7a62753bc3dfe2813c081e21e9b37cbcf1ab39/packages/pglite/src/types.ts#L118

As such, all the columns of the relation go through `JSON.parse`, including ones stored as bigint. This results in precision loss for integers outside of the `Number.MIN_SAFE_INTEGER..Number.MAX_SAFE_INTEGER` range.

While I haven't tested this, this issue might also occur with other data types, like decimal. It might also occur using other Pg drivers.

### Reproduction

```ts
export const user = pgTable('user', {
id: bigint('id', { mode: 'bigint' }).primaryKey(),
});

export const userDetails = pgTable('userDetails', {
userId: bigint('id', { mode: 'bigint' }).primaryKey().references(() => user.id),
otherColumn: bigint('otherColumn', { mode: 'bigint' }).notNull(),
});

export const userRelations = relations(user, ({ many, one }) => ({
details: one(userDetails, {
fields: [user.id],
references: [userDetails.id],
}),
}));

const userId = BigInt(Number.MAX_SAFE_INTEGER) + 20n;
const reallyBigInt = BigInt(Number.MAX_SAFE_INTEGER) * 3n;

await drizzle.insert(user).values({
id: userId,
});

await drizzle.insert(userDetails).values({
userId,
otherColumn: reallyBigInt,
}).execute();

const result = await drizzle.query.user.findFirst({
with: {
details: true,
},
}).execute();

assert(result.id === userId); // true
assert(result.details.userId === userId); // false
assert(result.details.otherColumn === reallyBigInt); // false
```

### Expected behavior

BigInts should be parsed as specified in the column type. Ideally, this could be specified as string (#813).

### Environment & setup

Node.js v22.8.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.