Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(adapter-d1): set maxBindValues: 100 #24242

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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