Skip to content

BigInt precision loss in nested relations with relationJoins preview feature #29010

Description

@polaz

Bug description

When using driver adapters (e.g., @prisma/adapter-pg) with previewFeatures = ["relationJoins"], BigInt values in nested relations lose precision silently.

The root cause is that relationJoins uses PostgreSQL lateral joins with JSON aggregation to fetch related data. When this JSON is parsed with JSON.parse(), integers exceeding Number.MAX_SAFE_INTEGER (2^53 - 1) are converted to JavaScript Numbers, causing precision loss.

How to reproduce

Schema

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters", "relationJoins"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id    BigInt     @id @default(autoincrement())
  files UserFile[]
}

model UserFile {
  id     String @id @default(uuid())
  userId BigInt
  user   User   @relation(fields: [userId], references: [id])
}

Test code

import { PrismaClient } from '@prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
import { Pool } from 'pg'

const pool = new Pool({ connectionString: process.env.DATABASE_URL })
const adapter = new PrismaPg(pool)
const prisma = new PrismaClient({ adapter })

async function main() {
  // Create test data
  const user = await prisma.user.create({ data: {} })
  console.log('Created user with id:', user.id) // e.g., 312590077454712834n

  const file = await prisma.userFile.create({
    data: { userId: user.id }
  })

  // Fetch with include (triggers relationJoins lateral join)
  const result = await prisma.userFile.findUnique({
    where: { id: file.id },
    include: { user: true }
  })

  console.log('Direct userId:', result.userId)      // 312590077454712834n (correct)
  console.log('Nested user.id:', result.user.id)    // 312590077454712832n (WRONG!)
  console.log('Match:', result.userId === result.user.id) // false!
}

main()

Expected behavior

result.userId should equal result.user.id - the BigInt value should be preserved exactly.

Actual behavior

The nested relation's BigInt value is corrupted:

  • result.userId = 312590077454712834n (correct, from direct column)
  • result.user.id = 312590077454712832n (corrupted, from JSON-parsed relation)

The type remains bigint, but the value is silently wrong.

Environment

  • Prisma version: 6.x / 7.x with relationJoins preview feature
  • Database: PostgreSQL
  • Driver adapter: @prisma/adapter-pg (likely affects all driver adapters)
  • OS: Any

Fix

PR: #29009

The fix adds a safeJsonParse() function that preserves large integers by converting them to strings before parsing. The existing data mapper then correctly converts these strings to BigInt.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug/1-unconfirmedBug should have enough information for reproduction, but confirmation has not happened yet.kind/bugA reported bug.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions