@prisma/client-engine-runtime 6.14.0-dev.4 → 6.14.0-dev.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- // src/interpreter/DataMapper.ts
2
- import Decimal2 from "decimal.js";
1
+ // src/json-protocol.ts
2
+ import { Decimal as Decimal2 } from "decimal.js";
3
3
 
4
4
  // src/utils.ts
5
5
  import Decimal from "decimal.js";
@@ -93,7 +93,303 @@ function safeJsonStringify(obj) {
93
93
  });
94
94
  }
95
95
 
96
- // src/interpreter/DataMapper.ts
96
+ // src/json-protocol.ts
97
+ function normalizeJsonProtocolValues(result) {
98
+ if (result === null) {
99
+ return result;
100
+ }
101
+ if (Array.isArray(result)) {
102
+ return result.map(normalizeJsonProtocolValues);
103
+ }
104
+ if (typeof result === "object") {
105
+ if (isTaggedValue(result)) {
106
+ return normalizeTaggedValue(result);
107
+ }
108
+ if (result.constructor !== null && result.constructor.name !== "Object") {
109
+ return result;
110
+ }
111
+ return mapObjectValues(result, normalizeJsonProtocolValues);
112
+ }
113
+ return result;
114
+ }
115
+ function isTaggedValue(value) {
116
+ return value !== null && typeof value == "object" && typeof value["$type"] === "string";
117
+ }
118
+ function normalizeTaggedValue({ $type, value }) {
119
+ switch ($type) {
120
+ case "BigInt":
121
+ return { $type, value: String(value) };
122
+ case "Bytes":
123
+ return { $type, value };
124
+ case "DateTime":
125
+ return { $type, value: new Date(value).toISOString() };
126
+ case "Decimal":
127
+ return { $type, value: String(new Decimal2(value)) };
128
+ case "Json":
129
+ return { $type, value: JSON.stringify(JSON.parse(value)) };
130
+ default:
131
+ assertNever(value, "Unknown tagged value");
132
+ }
133
+ }
134
+ function mapObjectValues(object, mapper) {
135
+ const result = {};
136
+ for (const key of Object.keys(object)) {
137
+ result[key] = mapper(object[key], key);
138
+ }
139
+ return result;
140
+ }
141
+ function deserializeJsonResponse(result) {
142
+ if (result === null) {
143
+ return result;
144
+ }
145
+ if (Array.isArray(result)) {
146
+ return result.map(deserializeJsonResponse);
147
+ }
148
+ if (typeof result === "object") {
149
+ if (isTaggedValue(result)) {
150
+ return deserializeTaggedValue(result);
151
+ }
152
+ if (result.constructor !== null && result.constructor.name !== "Object") {
153
+ return result;
154
+ }
155
+ return mapObjectValues(result, deserializeJsonResponse);
156
+ }
157
+ return result;
158
+ }
159
+ function deserializeTaggedValue({ $type, value }) {
160
+ switch ($type) {
161
+ case "BigInt":
162
+ return BigInt(value);
163
+ case "Bytes": {
164
+ const { buffer, byteOffset, byteLength } = Buffer.from(value, "base64");
165
+ return new Uint8Array(buffer, byteOffset, byteLength);
166
+ }
167
+ case "DateTime":
168
+ return new Date(value);
169
+ case "Decimal":
170
+ return new Decimal2(value);
171
+ case "Json":
172
+ return JSON.parse(value);
173
+ default:
174
+ assertNever(value, "Unknown tagged value");
175
+ }
176
+ }
177
+
178
+ // src/user-facing-error.ts
179
+ import { isDriverAdapterError } from "@prisma/driver-adapter-utils";
180
+ var UserFacingError = class extends Error {
181
+ name = "UserFacingError";
182
+ code;
183
+ meta;
184
+ constructor(message, code, meta) {
185
+ super(message);
186
+ this.code = code;
187
+ this.meta = meta ?? {};
188
+ }
189
+ toQueryResponseErrorObject() {
190
+ return {
191
+ error: this.message,
192
+ user_facing_error: {
193
+ is_panic: false,
194
+ message: this.message,
195
+ meta: this.meta,
196
+ error_code: this.code
197
+ }
198
+ };
199
+ }
200
+ };
201
+ function rethrowAsUserFacing(error) {
202
+ if (!isDriverAdapterError(error)) {
203
+ throw error;
204
+ }
205
+ const code = getErrorCode(error);
206
+ const message = renderErrorMessage(error);
207
+ if (!code || !message) {
208
+ throw error;
209
+ }
210
+ throw new UserFacingError(message, code, { driverAdapterError: error });
211
+ }
212
+ function rethrowAsUserFacingRawError(error) {
213
+ if (!isDriverAdapterError(error)) {
214
+ throw error;
215
+ }
216
+ throw new UserFacingError(
217
+ `Raw query failed. Code: \`${error.cause.originalCode ?? "N/A"}\`. Message: \`${error.cause.originalMessage ?? renderErrorMessage(error)}\``,
218
+ "P2010",
219
+ { driverAdapterError: error }
220
+ );
221
+ }
222
+ function getErrorCode(err) {
223
+ switch (err.cause.kind) {
224
+ case "AuthenticationFailed":
225
+ return "P1000";
226
+ case "DatabaseNotReachable":
227
+ return "P1001";
228
+ case "DatabaseDoesNotExist":
229
+ return "P1003";
230
+ case "SocketTimeout":
231
+ return "P1008";
232
+ case "DatabaseAlreadyExists":
233
+ return "P1009";
234
+ case "DatabaseAccessDenied":
235
+ return "P1010";
236
+ case "TlsConnectionError":
237
+ return "P1011";
238
+ case "ConnectionClosed":
239
+ return "P1017";
240
+ case "TransactionAlreadyClosed":
241
+ return "P1018";
242
+ case "LengthMismatch":
243
+ return "P2000";
244
+ case "UniqueConstraintViolation":
245
+ return "P2002";
246
+ case "ForeignKeyConstraintViolation":
247
+ return "P2003";
248
+ case "UnsupportedNativeDataType":
249
+ return "P2010";
250
+ case "NullConstraintViolation":
251
+ return "P2011";
252
+ case "ValueOutOfRange":
253
+ return "P2020";
254
+ case "TableDoesNotExist":
255
+ return "P2021";
256
+ case "ColumnNotFound":
257
+ return "P2022";
258
+ case "InvalidIsolationLevel":
259
+ case "InconsistentColumnData":
260
+ return "P2023";
261
+ case "MissingFullTextSearchIndex":
262
+ return "P2030";
263
+ case "TransactionWriteConflict":
264
+ return "P2034";
265
+ case "GenericJs":
266
+ return "P2036";
267
+ case "TooManyConnections":
268
+ return "P2037";
269
+ case "postgres":
270
+ case "sqlite":
271
+ case "mysql":
272
+ case "mssql":
273
+ return;
274
+ default:
275
+ assertNever(err.cause, `Unknown error: ${err.cause}`);
276
+ }
277
+ }
278
+ function renderErrorMessage(err) {
279
+ switch (err.cause.kind) {
280
+ case "AuthenticationFailed": {
281
+ const user = err.cause.user ?? "(not available)";
282
+ return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
283
+ }
284
+ case "DatabaseNotReachable": {
285
+ const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
286
+ return `Can't reach database server${address ? ` at ${address}` : ""}`;
287
+ }
288
+ case "DatabaseDoesNotExist": {
289
+ const db = err.cause.db ?? "(not available)";
290
+ return `Database \`${db}\` does not exist on the database server`;
291
+ }
292
+ case "SocketTimeout":
293
+ return `Operation has timed out`;
294
+ case "DatabaseAlreadyExists": {
295
+ const db = err.cause.db ?? "(not available)";
296
+ return `Database \`${db}\` already exists on the database server`;
297
+ }
298
+ case "DatabaseAccessDenied": {
299
+ const db = err.cause.db ?? "(not available)";
300
+ return `User was denied access on the database \`${db}\``;
301
+ }
302
+ case "TlsConnectionError": {
303
+ return `Error opening a TLS connection: ${err.cause.reason}`;
304
+ }
305
+ case "ConnectionClosed": {
306
+ return "Server has closed the connection.";
307
+ }
308
+ case "TransactionAlreadyClosed":
309
+ return err.cause.cause;
310
+ case "LengthMismatch": {
311
+ const column = err.cause.column ?? "(not available)";
312
+ return `The provided value for the column is too long for the column's type. Column: ${column}`;
313
+ }
314
+ case "UniqueConstraintViolation":
315
+ return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
316
+ case "ForeignKeyConstraintViolation":
317
+ return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
318
+ case "UnsupportedNativeDataType":
319
+ return `Failed to deserialize column of type '${err.cause.type}'. If you're using $queryRaw and this column is explicitly marked as \`Unsupported\` in your Prisma schema, try casting this column to any supported Prisma type such as \`String\`.`;
320
+ case "NullConstraintViolation":
321
+ return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
322
+ case "ValueOutOfRange":
323
+ return `Value out of range for the type: ${err.cause.cause}`;
324
+ case "TableDoesNotExist": {
325
+ const table = err.cause.table ?? "(not available)";
326
+ return `The table \`${table}\` does not exist in the current database.`;
327
+ }
328
+ case "ColumnNotFound": {
329
+ const column = err.cause.column ?? "(not available)";
330
+ return `The column \`${column}\` does not exist in the current database.`;
331
+ }
332
+ case "InvalidIsolationLevel":
333
+ return `Error in connector: Conversion error: ${err.cause.level}`;
334
+ case "InconsistentColumnData":
335
+ return `Inconsistent column data: ${err.cause.cause}`;
336
+ case "MissingFullTextSearchIndex":
337
+ return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
338
+ case "TransactionWriteConflict":
339
+ return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
340
+ case "GenericJs":
341
+ return `Error in external connector (id ${err.cause.id})`;
342
+ case "TooManyConnections":
343
+ return `Too many database connections opened: ${err.cause.cause}`;
344
+ case "sqlite":
345
+ case "postgres":
346
+ case "mysql":
347
+ case "mssql":
348
+ return;
349
+ default:
350
+ assertNever(err.cause, `Unknown error: ${err.cause}`);
351
+ }
352
+ }
353
+ function renderConstraint(constraint) {
354
+ if (constraint && "fields" in constraint) {
355
+ return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
356
+ } else if (constraint && "index" in constraint) {
357
+ return `constraint: \`${constraint.index}\``;
358
+ } else if (constraint && "foreignKey" in constraint) {
359
+ return `foreign key`;
360
+ }
361
+ return "(not available)";
362
+ }
363
+
364
+ // src/batch.ts
365
+ function convertCompactedRows(rows, compiledBatch) {
366
+ const keysPerRow = rows.map(
367
+ (item) => compiledBatch.keys.reduce((acc, key) => {
368
+ acc[key] = deserializeJsonResponse(item[key]);
369
+ return acc;
370
+ }, {})
371
+ );
372
+ const selection = new Set(compiledBatch.nestedSelection);
373
+ return compiledBatch.arguments.map((args) => {
374
+ const rowIndex = keysPerRow.findIndex((rowKeys) => doKeysMatch(rowKeys, args));
375
+ if (rowIndex === -1) {
376
+ if (compiledBatch.expectNonEmpty) {
377
+ return new UserFacingError(
378
+ "An operation failed because it depends on one or more records that were required but not found",
379
+ "P2025"
380
+ );
381
+ } else {
382
+ return null;
383
+ }
384
+ } else {
385
+ const selected = Object.entries(rows[rowIndex]).filter(([k]) => selection.has(k));
386
+ return Object.fromEntries(selected);
387
+ }
388
+ });
389
+ }
390
+
391
+ // src/interpreter/data-mapper.ts
392
+ import Decimal3 from "decimal.js";
97
393
  var DataMapperError = class extends Error {
98
394
  name = "DataMapperError";
99
395
  };
@@ -105,17 +401,20 @@ function applyDataMap(data, structure, enums) {
105
401
  }
106
402
  return { count: data };
107
403
  case "Object":
108
- return mapArrayOrObject(data, structure.fields, enums);
404
+ return mapArrayOrObject(data, structure.fields, enums, structure.skipNulls);
109
405
  case "Value":
110
406
  return mapValue(data, "<result>", structure.resultType, enums);
111
407
  default:
112
408
  assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
113
409
  }
114
410
  }
115
- function mapArrayOrObject(data, fields, enums) {
411
+ function mapArrayOrObject(data, fields, enums, skipNulls) {
116
412
  if (data === null) return null;
117
413
  if (Array.isArray(data)) {
118
- const rows = data;
414
+ let rows = data;
415
+ if (skipNulls) {
416
+ rows = rows.filter((row) => row !== null);
417
+ }
119
418
  return rows.map((row) => mapObject(row, fields, enums));
120
419
  }
121
420
  if (typeof data === "object") {
@@ -131,7 +430,7 @@ function mapArrayOrObject(data, fields, enums) {
131
430
  cause: error
132
431
  });
133
432
  }
134
- return mapArrayOrObject(decodedData, fields, enums);
433
+ return mapArrayOrObject(decodedData, fields, enums, skipNulls);
135
434
  }
136
435
  throw new DataMapperError(`Expected an array or an object, got: ${typeof data}`);
137
436
  }
@@ -152,7 +451,7 @@ function mapObject(data, fields, enums) {
152
451
  );
153
452
  }
154
453
  const target = node.serializedName !== null ? data[node.serializedName] : data;
155
- result[name] = mapArrayOrObject(target, node.fields, enums);
454
+ result[name] = mapArrayOrObject(target, node.fields, enums, node.skipNulls);
156
455
  break;
157
456
  }
158
457
  case "Value":
@@ -245,7 +544,7 @@ function mapValue(value, columnName, resultType, enums) {
245
544
  throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
246
545
  }
247
546
  case "Decimal":
248
- if (typeof value !== "number" && typeof value !== "string" && !Decimal2.isDecimal(value)) {
547
+ if (typeof value !== "number" && typeof value !== "string" && !Decimal3.isDecimal(value)) {
249
548
  throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
250
549
  }
251
550
  return { $type: "Decimal", value };
@@ -269,8 +568,10 @@ function mapValue(value, columnName, resultType, enums) {
269
568
  return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
270
569
  }
271
570
  case "Object": {
272
- const jsonValue = typeof value === "string" ? value : safeJsonStringify(value);
273
- return { $type: "Json", value: jsonValue };
571
+ return { $type: "Json", value: safeJsonStringify(value) };
572
+ }
573
+ case "Json": {
574
+ return { $type: "Json", value: `${value}` };
274
575
  }
275
576
  case "Bytes": {
276
577
  if (typeof value === "string" && value.startsWith("\\x")) {
@@ -291,7 +592,7 @@ function mapValue(value, columnName, resultType, enums) {
291
592
  }
292
593
  const enumValue = enumDef[`${value}`];
293
594
  if (enumValue === void 0) {
294
- throw new DataMapperError(`Unknown enum value '${value}' for enum '${resultType.inner}'`);
595
+ throw new DataMapperError(`Value '${value}' not found in enum '${resultType.inner}'`);
295
596
  }
296
597
  return enumValue;
297
598
  }
@@ -346,201 +647,25 @@ async function withQuerySpanAndEvent({
346
647
  {
347
648
  name: "db_query",
348
649
  kind: SpanKind.CLIENT,
349
- attributes: {
350
- "db.query.text": query.sql,
351
- "db.system.name": providerToOtelSystem(provider)
352
- }
353
- },
354
- async () => {
355
- const timestamp = /* @__PURE__ */ new Date();
356
- const startInstant = performance.now();
357
- const result = await execute();
358
- const endInstant = performance.now();
359
- onQuery?.({
360
- timestamp,
361
- duration: endInstant - startInstant,
362
- query: query.sql,
363
- params: query.args
364
- });
365
- return result;
366
- }
367
- );
368
- }
369
-
370
- // src/UserFacingError.ts
371
- import { isDriverAdapterError } from "@prisma/driver-adapter-utils";
372
- var UserFacingError = class extends Error {
373
- name = "UserFacingError";
374
- code;
375
- meta;
376
- constructor(message, code, meta) {
377
- super(message);
378
- this.code = code;
379
- this.meta = meta ?? {};
380
- }
381
- toQueryResponseErrorObject() {
382
- return {
383
- error: this.message,
384
- user_facing_error: {
385
- is_panic: false,
386
- message: this.message,
387
- meta: this.meta,
388
- error_code: this.code
389
- }
390
- };
391
- }
392
- };
393
- function rethrowAsUserFacing(error) {
394
- if (!isDriverAdapterError(error)) {
395
- throw error;
396
- }
397
- const code = getErrorCode(error);
398
- const message = renderErrorMessage(error);
399
- if (!code || !message) {
400
- throw error;
401
- }
402
- throw new UserFacingError(message, code, { driverAdapterError: error });
403
- }
404
- function getErrorCode(err) {
405
- switch (err.cause.kind) {
406
- case "AuthenticationFailed":
407
- return "P1000";
408
- case "DatabaseNotReachable":
409
- return "P1001";
410
- case "DatabaseDoesNotExist":
411
- return "P1003";
412
- case "SocketTimeout":
413
- return "P1008";
414
- case "DatabaseAlreadyExists":
415
- return "P1009";
416
- case "DatabaseAccessDenied":
417
- return "P1010";
418
- case "TlsConnectionError":
419
- return "P1011";
420
- case "ConnectionClosed":
421
- return "P1017";
422
- case "TransactionAlreadyClosed":
423
- return "P1018";
424
- case "LengthMismatch":
425
- return "P2000";
426
- case "UniqueConstraintViolation":
427
- return "P2002";
428
- case "ForeignKeyConstraintViolation":
429
- return "P2003";
430
- case "UnsupportedNativeDataType":
431
- return "P2010";
432
- case "NullConstraintViolation":
433
- return "P2011";
434
- case "ValueOutOfRange":
435
- return "P2020";
436
- case "TableDoesNotExist":
437
- return "P2021";
438
- case "ColumnNotFound":
439
- return "P2022";
440
- case "InvalidIsolationLevel":
441
- case "InconsistentColumnData":
442
- return "P2023";
443
- case "MissingFullTextSearchIndex":
444
- return "P2030";
445
- case "TransactionWriteConflict":
446
- return "P2034";
447
- case "GenericJs":
448
- return "P2036";
449
- case "TooManyConnections":
450
- return "P2037";
451
- case "postgres":
452
- case "sqlite":
453
- case "mysql":
454
- case "mssql":
455
- return;
456
- default:
457
- assertNever(err.cause, `Unknown error: ${err.cause}`);
458
- }
459
- }
460
- function renderErrorMessage(err) {
461
- switch (err.cause.kind) {
462
- case "AuthenticationFailed": {
463
- const user = err.cause.user ?? "(not available)";
464
- return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
465
- }
466
- case "DatabaseNotReachable": {
467
- const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
468
- return `Can't reach database server${address ? ` at ${address}` : ""}`;
469
- }
470
- case "DatabaseDoesNotExist": {
471
- const db = err.cause.db ?? "(not available)";
472
- return `Database \`${db}\` does not exist on the database server`;
473
- }
474
- case "SocketTimeout":
475
- return `Operation has timed out`;
476
- case "DatabaseAlreadyExists": {
477
- const db = err.cause.db ?? "(not available)";
478
- return `Database \`${db}\` already exists on the database server`;
479
- }
480
- case "DatabaseAccessDenied": {
481
- const db = err.cause.db ?? "(not available)";
482
- return `User was denied access on the database \`${db}\``;
483
- }
484
- case "TlsConnectionError": {
485
- return `Error opening a TLS connection: ${err.cause.reason}`;
486
- }
487
- case "ConnectionClosed": {
488
- return "Server has closed the connection.";
489
- }
490
- case "TransactionAlreadyClosed":
491
- return err.cause.cause;
492
- case "LengthMismatch": {
493
- const column = err.cause.column ?? "(not available)";
494
- return `The provided value for the column is too long for the column's type. Column: ${column}`;
495
- }
496
- case "UniqueConstraintViolation":
497
- return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
498
- case "ForeignKeyConstraintViolation":
499
- return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
500
- case "UnsupportedNativeDataType":
501
- return `Failed to deserialize column of type '${err.cause.type}'. If you're using $queryRaw and this column is explicitly marked as \`Unsupported\` in your Prisma schema, try casting this column to any supported Prisma type such as \`String\`.`;
502
- case "NullConstraintViolation":
503
- return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
504
- case "ValueOutOfRange":
505
- return `Value out of range for the type: ${err.cause.cause}`;
506
- case "TableDoesNotExist": {
507
- const table = err.cause.table ?? "(not available)";
508
- return `The table \`${table}\` does not exist in the current database.`;
509
- }
510
- case "ColumnNotFound": {
511
- const column = err.cause.column ?? "(not available)";
512
- return `The column \`${column}\` does not exist in the current database.`;
513
- }
514
- case "InvalidIsolationLevel":
515
- return `Invalid isolation level \`${err.cause.level}\``;
516
- case "InconsistentColumnData":
517
- return `Inconsistent column data: ${err.cause.cause}`;
518
- case "MissingFullTextSearchIndex":
519
- return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
520
- case "TransactionWriteConflict":
521
- return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
522
- case "GenericJs":
523
- return `Error in external connector (id ${err.cause.id})`;
524
- case "TooManyConnections":
525
- return `Too many database connections opened: ${err.cause.cause}`;
526
- case "sqlite":
527
- case "postgres":
528
- case "mysql":
529
- case "mssql":
530
- return;
531
- default:
532
- assertNever(err.cause, `Unknown error: ${err.cause}`);
533
- }
534
- }
535
- function renderConstraint(constraint) {
536
- if (constraint && "fields" in constraint) {
537
- return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
538
- } else if (constraint && "index" in constraint) {
539
- return `constraint: \`${constraint.index}\``;
540
- } else if (constraint && "foreignKey" in constraint) {
541
- return `foreign key`;
542
- }
543
- return "(not available)";
650
+ attributes: {
651
+ "db.query.text": query.sql,
652
+ "db.system.name": providerToOtelSystem(provider)
653
+ }
654
+ },
655
+ async () => {
656
+ const timestamp = /* @__PURE__ */ new Date();
657
+ const startInstant = performance.now();
658
+ const result = await execute();
659
+ const endInstant = performance.now();
660
+ onQuery?.({
661
+ timestamp,
662
+ duration: endInstant - startInstant,
663
+ query: query.sql,
664
+ params: query.args
665
+ });
666
+ return result;
667
+ }
668
+ );
544
669
  }
545
670
 
546
671
  // src/interpreter/generators.ts
@@ -644,7 +769,98 @@ var ProductGenerator = class {
644
769
  }
645
770
  };
646
771
 
647
- // src/QueryPlan.ts
772
+ // src/interpreter/in-memory-processing.ts
773
+ function processRecords(value, ops) {
774
+ if (value == null) {
775
+ return value;
776
+ }
777
+ if (typeof value === "string") {
778
+ return processRecords(JSON.parse(value), ops);
779
+ }
780
+ if (Array.isArray(value)) {
781
+ return processManyRecords(value, ops);
782
+ }
783
+ return processOneRecord(value, ops);
784
+ }
785
+ function processOneRecord(record, ops) {
786
+ if (ops.pagination) {
787
+ const { skip, take, cursor } = ops.pagination;
788
+ if (skip !== null && skip > 0) {
789
+ return null;
790
+ }
791
+ if (take === 0) {
792
+ return null;
793
+ }
794
+ if (cursor !== null && !doKeysMatch(record, cursor)) {
795
+ return null;
796
+ }
797
+ }
798
+ return processNestedRecords(record, ops.nested);
799
+ }
800
+ function processNestedRecords(record, opsMap) {
801
+ for (const [key, ops] of Object.entries(opsMap)) {
802
+ record[key] = processRecords(record[key], ops);
803
+ }
804
+ return record;
805
+ }
806
+ function processManyRecords(records, ops) {
807
+ if (ops.distinct !== null) {
808
+ const fields = ops.linkingFields !== null ? [...ops.distinct, ...ops.linkingFields] : ops.distinct;
809
+ records = distinctBy(records, fields);
810
+ }
811
+ if (ops.pagination) {
812
+ records = paginate(records, ops.pagination, ops.linkingFields);
813
+ }
814
+ if (ops.reverse) {
815
+ records.reverse();
816
+ }
817
+ if (Object.keys(ops.nested).length === 0) {
818
+ return records;
819
+ }
820
+ return records.map((record) => processNestedRecords(record, ops.nested));
821
+ }
822
+ function distinctBy(records, fields) {
823
+ const seen = /* @__PURE__ */ new Set();
824
+ const result = [];
825
+ for (const record of records) {
826
+ const key = getRecordKey(record, fields);
827
+ if (!seen.has(key)) {
828
+ seen.add(key);
829
+ result.push(record);
830
+ }
831
+ }
832
+ return result;
833
+ }
834
+ function paginate(records, pagination, linkingFields) {
835
+ if (linkingFields === null) {
836
+ return paginateSingleList(records, pagination);
837
+ }
838
+ const groupedByParent = /* @__PURE__ */ new Map();
839
+ for (const record of records) {
840
+ const parentKey = getRecordKey(record, linkingFields);
841
+ if (!groupedByParent.has(parentKey)) {
842
+ groupedByParent.set(parentKey, []);
843
+ }
844
+ groupedByParent.get(parentKey).push(record);
845
+ }
846
+ const groupList = Array.from(groupedByParent.entries());
847
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
848
+ return groupList.flatMap(([, elems]) => paginateSingleList(elems, pagination));
849
+ }
850
+ function paginateSingleList(list, { cursor, skip, take }) {
851
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
852
+ if (cursorIndex === -1) {
853
+ return [];
854
+ }
855
+ const start = cursorIndex + (skip ?? 0);
856
+ const end = take !== null ? start + take : list.length;
857
+ return list.slice(start, end);
858
+ }
859
+ function getRecordKey(record, fields) {
860
+ return JSON.stringify(fields.map((field) => record[field]));
861
+ }
862
+
863
+ // src/query-plan.ts
648
864
  function isPrismaValuePlaceholder(value) {
649
865
  return typeof value === "object" && value !== null && value["prisma__type"] === "param";
650
866
  }
@@ -658,18 +874,22 @@ function isPrismaValueBigInt(value) {
658
874
  return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
659
875
  }
660
876
 
661
- // src/interpreter/renderQuery.ts
662
- function renderQuery(dbQuery, scope, generators) {
877
+ // src/interpreter/render-query.ts
878
+ function renderQuery(dbQuery, scope, generators, maxChunkSize) {
663
879
  const queryType = dbQuery.type;
880
+ const params = evaluateParams(dbQuery.params, scope, generators);
664
881
  switch (queryType) {
665
882
  case "rawSql":
666
- return renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators));
667
- case "templateSql":
668
- return renderTemplateSql(
669
- dbQuery.fragments,
670
- dbQuery.placeholderFormat,
671
- evaluateParams(dbQuery.params, scope, generators)
672
- );
883
+ return [renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators))];
884
+ case "templateSql": {
885
+ const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, params, maxChunkSize) : [params];
886
+ return chunks.map((params2) => {
887
+ if (maxChunkSize !== void 0 && params2.length > maxChunkSize) {
888
+ throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
889
+ }
890
+ return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params2);
891
+ });
892
+ }
673
893
  default:
674
894
  assertNever(queryType, `Invalid query type`);
675
895
  }
@@ -707,61 +927,36 @@ function evaluateParam(param, scope, generators) {
707
927
  return value;
708
928
  }
709
929
  function renderTemplateSql(fragments, placeholderFormat, params) {
710
- let paramIndex = 0;
711
- let placeholderNumber = 1;
930
+ let sql = "";
931
+ const ctx = { placeholderNumber: 1 };
712
932
  const flattenedParams = [];
713
- const sql = fragments.map((fragment) => {
714
- const fragmentType = fragment.type;
715
- switch (fragmentType) {
716
- case "parameter":
717
- if (paramIndex >= params.length) {
718
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
719
- }
720
- flattenedParams.push(params[paramIndex++]);
721
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
722
- case "stringChunk":
723
- return fragment.chunk;
724
- case "parameterTuple": {
725
- if (paramIndex >= params.length) {
726
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
727
- }
728
- const paramValue = params[paramIndex++];
729
- const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
730
- const placeholders = paramArray.length == 0 ? "NULL" : paramArray.map((value) => {
731
- flattenedParams.push(value);
732
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
733
- }).join(",");
734
- return `(${placeholders})`;
735
- }
736
- case "parameterTupleList": {
737
- if (paramIndex >= params.length) {
738
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
739
- }
740
- const paramValue = params[paramIndex++];
741
- if (!Array.isArray(paramValue)) {
742
- throw new Error(`Malformed query template. Tuple list expected.`);
743
- }
744
- if (paramValue.length === 0) {
745
- throw new Error(`Malformed query template. Tuple list cannot be empty.`);
746
- }
747
- const tupleList = paramValue.map((tuple) => {
748
- if (!Array.isArray(tuple)) {
749
- throw new Error(`Malformed query template. Tuple expected.`);
750
- }
751
- const elements = tuple.map((value) => {
752
- flattenedParams.push(value);
753
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
754
- }).join(fragment.itemSeparator);
755
- return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
756
- }).join(fragment.groupSeparator);
757
- return tupleList;
758
- }
759
- default:
760
- assertNever(fragmentType, "Invalid fragment type");
761
- }
762
- }).join("");
933
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
934
+ flattenedParams.push(...flattenedFragmentParams(fragment));
935
+ sql += renderFragment(fragment, placeholderFormat, ctx);
936
+ }
763
937
  return renderRawSql(sql, flattenedParams);
764
938
  }
939
+ function renderFragment(fragment, placeholderFormat, ctx) {
940
+ const fragmentType = fragment.type;
941
+ switch (fragmentType) {
942
+ case "parameter":
943
+ return formatPlaceholder(placeholderFormat, ctx.placeholderNumber++);
944
+ case "stringChunk":
945
+ return fragment.chunk;
946
+ case "parameterTuple": {
947
+ const placeholders = fragment.value.length == 0 ? "NULL" : fragment.value.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(",");
948
+ return `(${placeholders})`;
949
+ }
950
+ case "parameterTupleList": {
951
+ return fragment.value.map((tuple) => {
952
+ const elements = tuple.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(fragment.itemSeparator);
953
+ return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
954
+ }).join(fragment.groupSeparator);
955
+ }
956
+ default:
957
+ assertNever(fragmentType, "Invalid fragment type");
958
+ }
959
+ }
765
960
  function formatPlaceholder(placeholderFormat, placeholderNumber) {
766
961
  return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
767
962
  }
@@ -794,8 +989,145 @@ function toArgType(value) {
794
989
  function doesRequireEvaluation(param) {
795
990
  return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
796
991
  }
992
+ function* pairFragmentsWithParams(fragments, params) {
993
+ let index = 0;
994
+ for (const fragment of fragments) {
995
+ switch (fragment.type) {
996
+ case "parameter": {
997
+ if (index >= params.length) {
998
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
999
+ }
1000
+ yield { ...fragment, value: params[index++] };
1001
+ break;
1002
+ }
1003
+ case "stringChunk": {
1004
+ yield fragment;
1005
+ break;
1006
+ }
1007
+ case "parameterTuple": {
1008
+ if (index >= params.length) {
1009
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
1010
+ }
1011
+ const value = params[index++];
1012
+ yield { ...fragment, value: Array.isArray(value) ? value : [value] };
1013
+ break;
1014
+ }
1015
+ case "parameterTupleList": {
1016
+ if (index >= params.length) {
1017
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
1018
+ }
1019
+ const value = params[index++];
1020
+ if (!Array.isArray(value)) {
1021
+ throw new Error(`Malformed query template. Tuple list expected.`);
1022
+ }
1023
+ if (value.length === 0) {
1024
+ throw new Error(`Malformed query template. Tuple list cannot be empty.`);
1025
+ }
1026
+ for (const tuple of value) {
1027
+ if (!Array.isArray(tuple)) {
1028
+ throw new Error(`Malformed query template. Tuple expected.`);
1029
+ }
1030
+ }
1031
+ yield { ...fragment, value };
1032
+ break;
1033
+ }
1034
+ }
1035
+ }
1036
+ }
1037
+ function* flattenedFragmentParams(fragment) {
1038
+ switch (fragment.type) {
1039
+ case "parameter":
1040
+ yield fragment.value;
1041
+ break;
1042
+ case "stringChunk":
1043
+ break;
1044
+ case "parameterTuple":
1045
+ yield* fragment.value;
1046
+ break;
1047
+ case "parameterTupleList":
1048
+ for (const tuple of fragment.value) {
1049
+ yield* tuple;
1050
+ }
1051
+ break;
1052
+ }
1053
+ }
1054
+ function chunkParams(fragments, params, maxChunkSize) {
1055
+ let totalParamCount = 0;
1056
+ let maxParamsPerFragment = 0;
1057
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
1058
+ let paramSize = 0;
1059
+ for (const _ of flattenedFragmentParams(fragment)) {
1060
+ void _;
1061
+ paramSize++;
1062
+ }
1063
+ maxParamsPerFragment = Math.max(maxParamsPerFragment, paramSize);
1064
+ totalParamCount += paramSize;
1065
+ }
1066
+ let chunkedParams = [[]];
1067
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
1068
+ switch (fragment.type) {
1069
+ case "parameter": {
1070
+ for (const params2 of chunkedParams) {
1071
+ params2.push(fragment.value);
1072
+ }
1073
+ break;
1074
+ }
1075
+ case "stringChunk": {
1076
+ break;
1077
+ }
1078
+ case "parameterTuple": {
1079
+ const thisParamCount = fragment.value.length;
1080
+ let chunks = [];
1081
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1082
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1083
+ thisParamCount === maxParamsPerFragment && // Do we need chunking to fit the parameters?
1084
+ totalParamCount > maxChunkSize && // Would chunking enable us to fit the parameters?
1085
+ totalParamCount - thisParamCount < maxChunkSize) {
1086
+ const availableSize = maxChunkSize - (totalParamCount - thisParamCount);
1087
+ chunks = chunkArray(fragment.value, availableSize);
1088
+ } else {
1089
+ chunks = [fragment.value];
1090
+ }
1091
+ chunkedParams = chunkedParams.flatMap((params2) => chunks.map((chunk) => [...params2, chunk]));
1092
+ break;
1093
+ }
1094
+ case "parameterTupleList": {
1095
+ const thisParamCount = fragment.value.reduce((acc, tuple) => acc + tuple.length, 0);
1096
+ const completeChunks = [];
1097
+ let currentChunk = [];
1098
+ let currentChunkParamCount = 0;
1099
+ for (const tuple of fragment.value) {
1100
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1101
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1102
+ thisParamCount === maxParamsPerFragment && // Is there anything in the current chunk?
1103
+ currentChunk.length > 0 && // Will adding this tuple exceed the max chunk size?
1104
+ totalParamCount - thisParamCount + currentChunkParamCount + tuple.length > maxChunkSize) {
1105
+ completeChunks.push(currentChunk);
1106
+ currentChunk = [];
1107
+ currentChunkParamCount = 0;
1108
+ }
1109
+ currentChunk.push(tuple);
1110
+ currentChunkParamCount += tuple.length;
1111
+ }
1112
+ if (currentChunk.length > 0) {
1113
+ completeChunks.push(currentChunk);
1114
+ }
1115
+ chunkedParams = chunkedParams.flatMap((params2) => completeChunks.map((chunk) => [...params2, chunk]));
1116
+ break;
1117
+ }
1118
+ }
1119
+ }
1120
+ return chunkedParams;
1121
+ }
1122
+ function chunkArray(array, chunkSize) {
1123
+ const result = [];
1124
+ for (let i = 0; i < array.length; i += chunkSize) {
1125
+ result.push(array.slice(i, i + chunkSize));
1126
+ }
1127
+ return result;
1128
+ }
797
1129
 
798
- // src/interpreter/serializeSql.ts
1130
+ // src/interpreter/serialize-sql.ts
799
1131
  import { ColumnTypeEnum } from "@prisma/driver-adapter-utils";
800
1132
  function serializeSql(resultSet) {
801
1133
  const mappers = resultSet.columnTypes.map((type) => {
@@ -826,29 +1158,90 @@ function serializeSql(resultSet) {
826
1158
  );
827
1159
  }
828
1160
  function serializeRawSql(resultSet) {
829
- const types = resultSet.columnTypes.map((type) => serializeColumnType(type));
830
- const mappers = types.map((type) => {
831
- switch (type) {
832
- case "bytes":
833
- return (value) => Array.isArray(value) ? new Uint8Array(value) : value;
834
- case "int":
835
- return (value) => value === null ? null : typeof value === "number" ? value : parseInt(`${value}`, 10);
836
- case "bigint":
837
- return (value) => value === null ? null : typeof value === "bigint" ? value : BigInt(`${value}`);
838
- case "json":
839
- return (value) => typeof value === "string" ? JSON.parse(value) : value;
840
- case "bool":
841
- return (value) => typeof value === "string" ? value === "true" || value === "1" : typeof value === "number" ? value === 1 : value;
842
- default:
843
- return (value) => value;
844
- }
845
- });
846
1161
  return {
847
1162
  columns: resultSet.columnNames,
848
1163
  types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
849
- rows: resultSet.rows.map((row) => row.map((value, index) => mappers[index](value)))
1164
+ rows: resultSet.rows.map(
1165
+ (row) => row.map((value, index) => serializeRawValue(value, resultSet.columnTypes[index]))
1166
+ )
850
1167
  };
851
1168
  }
1169
+ function serializeRawValue(value, type) {
1170
+ if (value === null) {
1171
+ return null;
1172
+ }
1173
+ switch (type) {
1174
+ case ColumnTypeEnum.Int32:
1175
+ switch (typeof value) {
1176
+ case "number":
1177
+ return Math.trunc(value);
1178
+ case "string":
1179
+ return Math.trunc(Number(value));
1180
+ default:
1181
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32`);
1182
+ }
1183
+ case ColumnTypeEnum.Int32Array:
1184
+ if (!Array.isArray(value)) {
1185
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32Array`);
1186
+ }
1187
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Int32));
1188
+ case ColumnTypeEnum.Int64:
1189
+ switch (typeof value) {
1190
+ case "number":
1191
+ return BigInt(Math.trunc(value));
1192
+ case "string":
1193
+ return value;
1194
+ default:
1195
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64`);
1196
+ }
1197
+ case ColumnTypeEnum.Int64Array:
1198
+ if (!Array.isArray(value)) {
1199
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64Array`);
1200
+ }
1201
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Int64));
1202
+ case ColumnTypeEnum.Json:
1203
+ switch (typeof value) {
1204
+ case "string":
1205
+ return JSON.parse(value);
1206
+ default:
1207
+ throw new Error(`Cannot serialize value of type ${typeof value} as Json`);
1208
+ }
1209
+ case ColumnTypeEnum.JsonArray:
1210
+ if (!Array.isArray(value)) {
1211
+ throw new Error(`Cannot serialize value of type ${typeof value} as JsonArray`);
1212
+ }
1213
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Json));
1214
+ case ColumnTypeEnum.Bytes:
1215
+ if (Array.isArray(value)) {
1216
+ return new Uint8Array(value);
1217
+ } else {
1218
+ throw new Error(`Cannot serialize value of type ${typeof value} as Bytes`);
1219
+ }
1220
+ case ColumnTypeEnum.BytesArray:
1221
+ if (!Array.isArray(value)) {
1222
+ throw new Error(`Cannot serialize value of type ${typeof value} as BytesArray`);
1223
+ }
1224
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Bytes));
1225
+ case ColumnTypeEnum.Boolean:
1226
+ switch (typeof value) {
1227
+ case "boolean":
1228
+ return value;
1229
+ case "string":
1230
+ return value === "true" || value === "1";
1231
+ case "number":
1232
+ return value === 1;
1233
+ default:
1234
+ throw new Error(`Cannot serialize value of type ${typeof value} as Boolean`);
1235
+ }
1236
+ case ColumnTypeEnum.BooleanArray:
1237
+ if (!Array.isArray(value)) {
1238
+ throw new Error(`Cannot serialize value of type ${typeof value} as BooleanArray`);
1239
+ }
1240
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Boolean));
1241
+ default:
1242
+ return value;
1243
+ }
1244
+ }
852
1245
  function serializeColumnType(columnType) {
853
1246
  switch (columnType) {
854
1247
  case ColumnTypeEnum.Int32:
@@ -993,7 +1386,7 @@ function getErrorCode2(error) {
993
1386
  }
994
1387
  }
995
1388
 
996
- // src/interpreter/QueryInterpreter.ts
1389
+ // src/interpreter/query-interpreter.ts
997
1390
  var QueryInterpreter = class _QueryInterpreter {
998
1391
  #transactionManager;
999
1392
  #placeholderValues;
@@ -1003,6 +1396,7 @@ var QueryInterpreter = class _QueryInterpreter {
1003
1396
  #serializer;
1004
1397
  #rawSerializer;
1005
1398
  #provider;
1399
+ #connectioInfo;
1006
1400
  constructor({
1007
1401
  transactionManager,
1008
1402
  placeholderValues,
@@ -1010,7 +1404,8 @@ var QueryInterpreter = class _QueryInterpreter {
1010
1404
  tracingHelper,
1011
1405
  serializer,
1012
1406
  rawSerializer,
1013
- provider
1407
+ provider,
1408
+ connectionInfo
1014
1409
  }) {
1015
1410
  this.#transactionManager = transactionManager;
1016
1411
  this.#placeholderValues = placeholderValues;
@@ -1019,6 +1414,7 @@ var QueryInterpreter = class _QueryInterpreter {
1019
1414
  this.#serializer = serializer;
1020
1415
  this.#rawSerializer = rawSerializer ?? serializer;
1021
1416
  this.#provider = provider;
1417
+ this.#connectioInfo = connectionInfo;
1022
1418
  }
1023
1419
  static forSql(options) {
1024
1420
  return new _QueryInterpreter({
@@ -1028,7 +1424,8 @@ var QueryInterpreter = class _QueryInterpreter {
1028
1424
  tracingHelper: options.tracingHelper,
1029
1425
  serializer: serializeSql,
1030
1426
  rawSerializer: serializeRawSql,
1031
- provider: options.provider
1427
+ provider: options.provider,
1428
+ connectionInfo: options.connectionInfo
1032
1429
  });
1033
1430
  }
1034
1431
  async run(queryPlan, queryable) {
@@ -1089,21 +1486,41 @@ var QueryInterpreter = class _QueryInterpreter {
1089
1486
  };
1090
1487
  }
1091
1488
  case "execute": {
1092
- const query = renderQuery(node.args, scope, generators);
1093
- return this.#withQuerySpanAndEvent(query, queryable, async () => {
1094
- return { value: await queryable.executeRaw(query) };
1095
- });
1489
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1490
+ let sum = 0;
1491
+ for (const query of queries) {
1492
+ sum += await this.#withQuerySpanAndEvent(
1493
+ query,
1494
+ queryable,
1495
+ () => queryable.executeRaw(query).catch(
1496
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1497
+ )
1498
+ );
1499
+ }
1500
+ return { value: sum };
1096
1501
  }
1097
1502
  case "query": {
1098
- const query = renderQuery(node.args, scope, generators);
1099
- return this.#withQuerySpanAndEvent(query, queryable, async () => {
1100
- const result = await queryable.queryRaw(query);
1101
- if (node.args.type === "rawSql") {
1102
- return { value: this.#rawSerializer(result), lastInsertId: result.lastInsertId };
1503
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1504
+ let results;
1505
+ for (const query of queries) {
1506
+ const result = await this.#withQuerySpanAndEvent(
1507
+ query,
1508
+ queryable,
1509
+ () => queryable.queryRaw(query).catch(
1510
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1511
+ )
1512
+ );
1513
+ if (results === void 0) {
1514
+ results = result;
1103
1515
  } else {
1104
- return { value: this.#serializer(result), lastInsertId: result.lastInsertId };
1516
+ results.rows.push(...result.rows);
1517
+ results.lastInsertId = result.lastInsertId;
1105
1518
  }
1106
- });
1519
+ }
1520
+ return {
1521
+ value: node.args.type === "rawSql" ? this.#rawSerializer(results) : this.#serializer(results),
1522
+ lastInsertId: results?.lastInsertId
1523
+ };
1107
1524
  }
1108
1525
  case "reverse": {
1109
1526
  const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
@@ -1182,43 +1599,12 @@ var QueryInterpreter = class _QueryInterpreter {
1182
1599
  case "diff": {
1183
1600
  const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
1184
1601
  const { value: to } = await this.interpretNode(node.args.to, queryable, scope, generators);
1185
- const toSet = new Set(asList(to));
1186
- return { value: asList(from).filter((item) => !toSet.has(item)) };
1187
- }
1188
- case "distinctBy": {
1189
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
1190
- const seen = /* @__PURE__ */ new Set();
1191
- const result = [];
1192
- for (const item of asList(value)) {
1193
- const key = getRecordKey(item, node.args.fields);
1194
- if (!seen.has(key)) {
1195
- seen.add(key);
1196
- result.push(item);
1197
- }
1198
- }
1199
- return { value: result, lastInsertId };
1602
+ const toSet = new Set(asList(to).map((item) => JSON.stringify(item)));
1603
+ return { value: asList(from).filter((item) => !toSet.has(JSON.stringify(item))) };
1200
1604
  }
1201
- case "paginate": {
1605
+ case "process": {
1202
1606
  const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
1203
- const list = asList(value);
1204
- const linkingFields = node.args.pagination.linkingFields;
1205
- if (linkingFields !== null) {
1206
- const groupedByParent = /* @__PURE__ */ new Map();
1207
- for (const item of list) {
1208
- const parentKey = getRecordKey(item, linkingFields);
1209
- if (!groupedByParent.has(parentKey)) {
1210
- groupedByParent.set(parentKey, []);
1211
- }
1212
- groupedByParent.get(parentKey).push(item);
1213
- }
1214
- const groupList = Array.from(groupedByParent.entries());
1215
- groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
1216
- return {
1217
- value: groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination)),
1218
- lastInsertId
1219
- };
1220
- }
1221
- return { value: paginate(list, node.args.pagination), lastInsertId };
1607
+ return { value: processRecords(value, node.args.operations), lastInsertId };
1222
1608
  }
1223
1609
  case "initializeRecord": {
1224
1610
  const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
@@ -1240,6 +1626,34 @@ var QueryInterpreter = class _QueryInterpreter {
1240
1626
  assertNever(node, `Unexpected node type: ${node.type}`);
1241
1627
  }
1242
1628
  }
1629
+ #maxChunkSize() {
1630
+ if (this.#connectioInfo?.maxBindValues !== void 0) {
1631
+ return this.#connectioInfo.maxBindValues;
1632
+ }
1633
+ return this.#providerMaxChunkSize();
1634
+ }
1635
+ #providerMaxChunkSize() {
1636
+ if (this.#provider === void 0) {
1637
+ return void 0;
1638
+ }
1639
+ switch (this.#provider) {
1640
+ case "cockroachdb":
1641
+ case "postgres":
1642
+ case "postgresql":
1643
+ case "prisma+postgres":
1644
+ return 32766;
1645
+ case "mysql":
1646
+ return 65535;
1647
+ case "sqlite":
1648
+ return 999;
1649
+ case "sqlserver":
1650
+ return 2098;
1651
+ case "mongodb":
1652
+ return void 0;
1653
+ default:
1654
+ assertNever(this.#provider, `Unexpected provider: ${this.#provider}`);
1655
+ }
1656
+ }
1243
1657
  #withQuerySpanAndEvent(query, queryable, execute) {
1244
1658
  return withQuerySpanAndEvent({
1245
1659
  query,
@@ -1317,18 +1731,6 @@ function attachChildrenToParents(parentRecords, children) {
1317
1731
  }
1318
1732
  return parentRecords;
1319
1733
  }
1320
- function paginate(list, { cursor, skip, take }) {
1321
- const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
1322
- if (cursorIndex === -1) {
1323
- return [];
1324
- }
1325
- const start = cursorIndex + (skip ?? 0);
1326
- const end = take !== null ? start + take : list.length;
1327
- return list.slice(start, end);
1328
- }
1329
- function getRecordKey(record, fields) {
1330
- return JSON.stringify(fields.map((field) => record[field]));
1331
- }
1332
1734
  function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
1333
1735
  switch (initializer.type) {
1334
1736
  case "value":
@@ -1362,54 +1764,36 @@ function evalFieldOperation(op, value, scope, generators) {
1362
1764
  }
1363
1765
  }
1364
1766
 
1365
- // src/json-protocol.ts
1366
- import { Decimal as Decimal3 } from "decimal.js";
1367
- function normalizeJsonProtocolValues(result) {
1368
- if (result === null) {
1369
- return result;
1370
- }
1371
- if (Array.isArray(result)) {
1372
- return result.map(normalizeJsonProtocolValues);
1373
- }
1374
- if (typeof result === "object") {
1375
- if (isTaggedValue(result)) {
1376
- return normalizeTaggedValue(result);
1377
- }
1378
- if (result.constructor !== null && result.constructor.name !== "Object") {
1379
- return result;
1767
+ // src/raw-json-protocol.ts
1768
+ import Decimal4 from "decimal.js";
1769
+ function normalizeRawJsonProtocolResponse(response) {
1770
+ for (let i = 0; i < response.rows.length; i++) {
1771
+ const row = response.rows[i];
1772
+ for (let j = 0; j < row.length; j++) {
1773
+ row[j] = normalizeValue(response.types[j], row[j]);
1380
1774
  }
1381
- return mapObjectValues(result, normalizeJsonProtocolValues);
1382
1775
  }
1383
- return result;
1384
- }
1385
- function isTaggedValue(value) {
1386
- return value !== null && typeof value == "object" && typeof value["$type"] === "string";
1776
+ return response;
1387
1777
  }
1388
- function normalizeTaggedValue({ $type, value }) {
1389
- switch ($type) {
1390
- case "BigInt":
1391
- return { $type, value: String(value) };
1392
- case "Bytes":
1393
- return { $type, value };
1394
- case "DateTime":
1395
- return { $type, value: new Date(value).toISOString() };
1396
- case "Decimal":
1397
- return { $type, value: String(new Decimal3(value)) };
1398
- case "Json":
1399
- return { $type, value: JSON.stringify(JSON.parse(value)) };
1400
- default:
1401
- assertNever(value, "Unknown tagged value");
1778
+ function normalizeValue(type, value) {
1779
+ if (value === null) {
1780
+ return value;
1402
1781
  }
1403
- }
1404
- function mapObjectValues(object, mapper) {
1405
- const result = {};
1406
- for (const key of Object.keys(object)) {
1407
- result[key] = mapper(object[key], key);
1782
+ switch (type) {
1783
+ case "bigint":
1784
+ return String(BigInt(value));
1785
+ case "decimal":
1786
+ return String(new Decimal4(value));
1787
+ case "bigint-array":
1788
+ return value.map((v) => normalizeValue("bigint", v));
1789
+ case "decimal-array":
1790
+ return value.map((v) => normalizeValue("decimal", v));
1791
+ default:
1792
+ return value;
1408
1793
  }
1409
- return result;
1410
1794
  }
1411
1795
 
1412
- // src/transactionManager/TransactionManager.ts
1796
+ // src/transaction-manager/transaction-manager.ts
1413
1797
  import { Debug } from "@prisma/debug";
1414
1798
 
1415
1799
  // src/crypto.ts
@@ -1421,7 +1805,7 @@ async function randomUUID() {
1421
1805
  return crypto.randomUUID();
1422
1806
  }
1423
1807
 
1424
- // src/transactionManager/TransactionManagerErrors.ts
1808
+ // src/transaction-manager/transaction-manager-error.ts
1425
1809
  var TransactionManagerError = class extends UserFacingError {
1426
1810
  name = "TransactionManagerError";
1427
1811
  constructor(message, meta) {
@@ -1458,7 +1842,7 @@ var TransactionStartTimeoutError = class extends TransactionManagerError {
1458
1842
  var TransactionExecutionTimeoutError = class extends TransactionManagerError {
1459
1843
  constructor(operation, { timeout, timeTaken }) {
1460
1844
  super(
1461
- `A ${operation} cannot be executed on an expired transaction. The timeout for this transaction was ${timeout} ms, however ${timeTaken} ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction`,
1845
+ `A ${operation} cannot be executed on an expired transaction. The timeout for this transaction was ${timeout} ms, however ${timeTaken} ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction.`,
1462
1846
  { operation, timeout, timeTaken }
1463
1847
  );
1464
1848
  }
@@ -1474,7 +1858,7 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
1474
1858
  }
1475
1859
  };
1476
1860
 
1477
- // src/transactionManager/TransactionManager.ts
1861
+ // src/transaction-manager/transaction-manager.ts
1478
1862
  var MAX_CLOSED_TRANSACTIONS = 100;
1479
1863
  var debug = Debug("prisma:client:transactionManager");
1480
1864
  var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
@@ -1529,7 +1913,7 @@ var TransactionManager = class {
1529
1913
  this.transactions.set(transaction.id, transaction);
1530
1914
  let hasTimedOut = false;
1531
1915
  const startTimer = setTimeout(() => hasTimedOut = true, validatedOptions.maxWait);
1532
- transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
1916
+ transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel).catch(rethrowAsUserFacing);
1533
1917
  clearTimeout(startTimer);
1534
1918
  switch (transaction.status) {
1535
1919
  case "waiting":
@@ -1676,6 +2060,8 @@ export {
1676
2060
  TransactionManager,
1677
2061
  TransactionManagerError,
1678
2062
  UserFacingError,
2063
+ convertCompactedRows,
2064
+ deserializeJsonResponse,
1679
2065
  doKeysMatch,
1680
2066
  isDeepStrictEqual,
1681
2067
  isPrismaValueBigInt,
@@ -1684,5 +2070,6 @@ export {
1684
2070
  isPrismaValuePlaceholder,
1685
2071
  noopTracingHelper,
1686
2072
  normalizeJsonProtocolValues,
2073
+ normalizeRawJsonProtocolResponse,
1687
2074
  safeJsonStringify
1688
2075
  };