Skip to content

Commit

Permalink
feat(adapter-d1): set maxBindValues: 100 (#24242)
Browse files Browse the repository at this point in the history
* feat(adapter-d1): set maxBindValues: 100

* add 2 tests

* fix test and lint

* Fix Property 'toBeObject' does not exist

* also replace toBeArrayOfSize

---------

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>
  • Loading branch information
jkomyno and Jolg42 committed May 31, 2024
1 parent 9156baa commit 6359463
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 1 deletion.
9 changes: 8 additions & 1 deletion packages/adapter-d1/src/d1.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { D1Database, D1Response } from '@cloudflare/workers-types'
import {
ConnectionInfo,
Debug,
DriverAdapter,
err,
Expand Down Expand Up @@ -152,13 +153,19 @@ export class PrismaD1 extends D1Queryable<StdClient> implements DriverAdapter {
* await prisma.$transaction([ ...moreQueries ])
* ```
*/
warnOnce = (key: string, message: string, ...args: unknown[]) => {
private warnOnce = (key: string, message: string, ...args: unknown[]) => {
if (!this.alreadyWarned.has(key)) {
this.alreadyWarned.add(key)
console.info(`${this.tags.warn} ${message}`, ...args)
}
}

getConnectionInfo(): Result<ConnectionInfo> {
return ok({
maxBindValues: 100,
})
}

// eslint-disable-next-line @typescript-eslint/require-await
async startTransaction(): Promise<Result<Transaction>> {
const options: TransactionOptions = {
Expand Down
4 changes: 4 additions & 0 deletions packages/client/tests/functional/max_bind_value/_matrix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { defineMatrix } from '../_utils/defineMatrix'
import { allProviders } from '../_utils/providers'

export default defineMatrix(() => [allProviders])
33 changes: 33 additions & 0 deletions packages/client/tests/functional/max_bind_value/prisma/_schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { idForProvider } from '../../_utils/idForProvider'
import testMatrix from '../_matrix'

export default testMatrix.setupSchema(({ provider }) => {
const id = idForProvider(provider)

return /* Prisma */ `
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "${provider}"
url = env("DATABASE_URI_${provider}")
}
model User {
id ${id}
email String @unique
name String?
posts Post[]
}
model Post {
id ${id}
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId String?
}
`
})
75 changes: 75 additions & 0 deletions packages/client/tests/functional/max_bind_value/tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import testMatrix from './_matrix'
// @ts-ignore
import type { Post, PrismaClient } from './node_modules/@prisma/client'

declare let prisma: PrismaClient

testMatrix.setupTestSuite(() => {
const posts: Pick<Post, 'id'>[] = []
const numberOfUsers = 200

beforeAll(async () => {
// Create x users with 2 posts each
for (let i = 0; i < numberOfUsers; i++) {
await prisma.user.create({
data: {
email: `user${i}@example.com`,
name: `User ${i}`,
posts: {
createMany: {
data: [
{
title: `Post ${i}a`,
content: `This is the content of the first post ${i}a by User ${i}`,
},
{
title: `Post ${i}b`,
content: `This is the content of the second post ${i}b by User ${i}`,
},
],
},
},
},
})
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
posts.push(...(await prisma.post.findMany({ select: { id: true } })))
})

// It used to error on D1 with
// Error in performIO: Error: D1_ERROR: too many SQL variables at offset 395
// see https://github.com/prisma/prisma/issues/23743
test('findMany() with more than 98 users with nested include should succeed', async () => {
await expect(
prisma.user.findMany({
include: {
posts: true,
},
}),
).resolves.toHaveLength(numberOfUsers)
})

// It used to error on D1 with
// Error in performIO: Error: D1_ERROR: Expression tree is too large (maximum depth 100)
// see https://github.com/prisma/prisma/issues/23919
test('create user with nested connect with more than 98 posts should succeed', async () => {
await expect(
prisma.user.create({
data: {
name: 'Foo',
email: 'foo@bar.org',
posts: {
connect: posts.map((it) => ({ id: it.id })),
},
},
include: {
posts: true,
},
}),
).resolves.toMatchObject({
id: expect.any(String),
// ...
})
})
})
1 change: 1 addition & 0 deletions packages/driver-adapter-utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export type Error =

export type ConnectionInfo = {
schemaName?: string
maxBindValues?: number
}

// Current list of official Prisma adapters
Expand Down

0 comments on commit 6359463

Please sign in to comment.