From fe2ab3560e7a305468d84e64bd1b1f344a1cc180 Mon Sep 17 00:00:00 2001 From: jkomyno Date: Mon, 20 May 2024 16:23:09 +0200 Subject: [PATCH 1/5] feat(adapter-d1): set maxBindValues: 100 --- packages/adapter-d1/src/d1.ts | 9 ++++++++- packages/driver-adapter-utils/src/types.ts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/adapter-d1/src/d1.ts b/packages/adapter-d1/src/d1.ts index ee013d4035f9..ab8ab5886a64 100644 --- a/packages/adapter-d1/src/d1.ts +++ b/packages/adapter-d1/src/d1.ts @@ -1,5 +1,6 @@ import { D1Database, D1Response } from '@cloudflare/workers-types' import { + ConnectionInfo, Debug, DriverAdapter, err, @@ -152,13 +153,19 @@ export class PrismaD1 extends D1Queryable 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 { + return ok({ + maxBindValues: 100, + }) + } + // eslint-disable-next-line @typescript-eslint/require-await async startTransaction(): Promise> { const options: TransactionOptions = { diff --git a/packages/driver-adapter-utils/src/types.ts b/packages/driver-adapter-utils/src/types.ts index d466ddb1d8b6..b4fde18c3d54 100644 --- a/packages/driver-adapter-utils/src/types.ts +++ b/packages/driver-adapter-utils/src/types.ts @@ -68,6 +68,7 @@ export type Error = export type ConnectionInfo = { schemaName?: string + maxBindValues?: number } // Current list of official Prisma adapters From 780d93ceba6bd9ea9f5e807ee7704a38c99a04d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joe=CC=88l=20Galeran?= Date: Wed, 22 May 2024 16:35:52 +0200 Subject: [PATCH 2/5] add 2 tests --- .../functional/max_bind_value/_matrix.ts | 4 ++ .../max_bind_value/prisma/_schema.ts | 33 +++++++++ .../tests/functional/max_bind_value/tests.ts | 71 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 packages/client/tests/functional/max_bind_value/_matrix.ts create mode 100644 packages/client/tests/functional/max_bind_value/prisma/_schema.ts create mode 100644 packages/client/tests/functional/max_bind_value/tests.ts diff --git a/packages/client/tests/functional/max_bind_value/_matrix.ts b/packages/client/tests/functional/max_bind_value/_matrix.ts new file mode 100644 index 000000000000..2ba8dc0e7c92 --- /dev/null +++ b/packages/client/tests/functional/max_bind_value/_matrix.ts @@ -0,0 +1,4 @@ +import { defineMatrix } from '../_utils/defineMatrix' +import { allProviders, Providers } from '../_utils/providers' + +export default defineMatrix(() => [allProviders]) diff --git a/packages/client/tests/functional/max_bind_value/prisma/_schema.ts b/packages/client/tests/functional/max_bind_value/prisma/_schema.ts new file mode 100644 index 000000000000..53aa9aeba9ad --- /dev/null +++ b/packages/client/tests/functional/max_bind_value/prisma/_schema.ts @@ -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? + } + ` +}) diff --git a/packages/client/tests/functional/max_bind_value/tests.ts b/packages/client/tests/functional/max_bind_value/tests.ts new file mode 100644 index 000000000000..28cfdd27c4f6 --- /dev/null +++ b/packages/client/tests/functional/max_bind_value/tests.ts @@ -0,0 +1,71 @@ +import testMatrix from './_matrix' +// @ts-ignore +import type { Post, PrismaClient } from './node_modules/@prisma/client' + +declare let prisma: PrismaClient + +testMatrix.setupTestSuite(() => { + const posts: Pick[] = [] + + beforeAll(async () => { + // Create x users with 2 posts each + for (let i = 0; i < 200; 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(1) + }) + + // 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.toHaveLength(1) + }) +}) From e8a46296ddbad315643d80458831bb556ae04480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joe=CC=88l=20Galeran?= Date: Wed, 22 May 2024 16:50:14 +0200 Subject: [PATCH 3/5] fix test and lint --- packages/client/tests/functional/max_bind_value/_matrix.ts | 2 +- packages/client/tests/functional/max_bind_value/tests.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/client/tests/functional/max_bind_value/_matrix.ts b/packages/client/tests/functional/max_bind_value/_matrix.ts index 2ba8dc0e7c92..a8bc6494be0c 100644 --- a/packages/client/tests/functional/max_bind_value/_matrix.ts +++ b/packages/client/tests/functional/max_bind_value/_matrix.ts @@ -1,4 +1,4 @@ import { defineMatrix } from '../_utils/defineMatrix' -import { allProviders, Providers } from '../_utils/providers' +import { allProviders } from '../_utils/providers' export default defineMatrix(() => [allProviders]) diff --git a/packages/client/tests/functional/max_bind_value/tests.ts b/packages/client/tests/functional/max_bind_value/tests.ts index 28cfdd27c4f6..2445fe81dcfe 100644 --- a/packages/client/tests/functional/max_bind_value/tests.ts +++ b/packages/client/tests/functional/max_bind_value/tests.ts @@ -6,10 +6,11 @@ declare let prisma: PrismaClient testMatrix.setupTestSuite(() => { const posts: Pick[] = [] + const numberOfUsers = 200 beforeAll(async () => { // Create x users with 2 posts each - for (let i = 0; i < 200; i++) { + for (let i = 0; i < numberOfUsers; i++) { await prisma.user.create({ data: { email: `user${i}@example.com`, @@ -46,7 +47,7 @@ testMatrix.setupTestSuite(() => { posts: true, }, }), - ).resolves.toHaveLength(1) + ).resolves.toBeArrayOfSize(numberOfUsers) }) // It used to error on D1 with @@ -66,6 +67,6 @@ testMatrix.setupTestSuite(() => { posts: true, }, }), - ).resolves.toHaveLength(1) + ).resolves.toBeObject() }) }) From 3daadbf5fbf7bd0bc6522d2abadaa441857fbb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joe=CC=88l=20Galeran?= Date: Wed, 22 May 2024 17:03:36 +0200 Subject: [PATCH 4/5] Fix Property 'toBeObject' does not exist --- packages/client/tests/functional/max_bind_value/tests.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/client/tests/functional/max_bind_value/tests.ts b/packages/client/tests/functional/max_bind_value/tests.ts index 2445fe81dcfe..f71acdce8df1 100644 --- a/packages/client/tests/functional/max_bind_value/tests.ts +++ b/packages/client/tests/functional/max_bind_value/tests.ts @@ -67,6 +67,9 @@ testMatrix.setupTestSuite(() => { posts: true, }, }), - ).resolves.toBeObject() + ).resolves.toMatchObject({ + id: expect.any(String), + // ... + }) }) }) From 12c8fb318ca934cba67a2d3178da5a62f43ea803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joe=CC=88l=20Galeran?= Date: Wed, 22 May 2024 17:05:04 +0200 Subject: [PATCH 5/5] also replace toBeArrayOfSize --- packages/client/tests/functional/max_bind_value/tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/tests/functional/max_bind_value/tests.ts b/packages/client/tests/functional/max_bind_value/tests.ts index f71acdce8df1..cc8392d805e1 100644 --- a/packages/client/tests/functional/max_bind_value/tests.ts +++ b/packages/client/tests/functional/max_bind_value/tests.ts @@ -47,7 +47,7 @@ testMatrix.setupTestSuite(() => { posts: true, }, }), - ).resolves.toBeArrayOfSize(numberOfUsers) + ).resolves.toHaveLength(numberOfUsers) }) // It used to error on D1 with