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

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.js CHANGED
@@ -35,6 +35,8 @@ __export(index_exports, {
35
35
  TransactionManager: () => TransactionManager,
36
36
  TransactionManagerError: () => TransactionManagerError,
37
37
  UserFacingError: () => UserFacingError,
38
+ convertCompactedRows: () => convertCompactedRows,
39
+ deserializeJsonResponse: () => deserializeJsonResponse,
38
40
  doKeysMatch: () => doKeysMatch,
39
41
  isDeepStrictEqual: () => isDeepStrictEqual,
40
42
  isPrismaValueBigInt: () => isPrismaValueBigInt,
@@ -43,12 +45,13 @@ __export(index_exports, {
43
45
  isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
44
46
  noopTracingHelper: () => noopTracingHelper,
45
47
  normalizeJsonProtocolValues: () => normalizeJsonProtocolValues,
48
+ normalizeRawJsonProtocolResponse: () => normalizeRawJsonProtocolResponse,
46
49
  safeJsonStringify: () => safeJsonStringify
47
50
  });
48
51
  module.exports = __toCommonJS(index_exports);
49
52
 
50
- // src/interpreter/DataMapper.ts
51
- var import_decimal2 = __toESM(require("decimal.js"));
53
+ // src/json-protocol.ts
54
+ var import_decimal2 = require("decimal.js");
52
55
 
53
56
  // src/utils.ts
54
57
  var import_decimal = __toESM(require("decimal.js"));
@@ -142,7 +145,303 @@ function safeJsonStringify(obj) {
142
145
  });
143
146
  }
144
147
 
145
- // src/interpreter/DataMapper.ts
148
+ // src/json-protocol.ts
149
+ function normalizeJsonProtocolValues(result) {
150
+ if (result === null) {
151
+ return result;
152
+ }
153
+ if (Array.isArray(result)) {
154
+ return result.map(normalizeJsonProtocolValues);
155
+ }
156
+ if (typeof result === "object") {
157
+ if (isTaggedValue(result)) {
158
+ return normalizeTaggedValue(result);
159
+ }
160
+ if (result.constructor !== null && result.constructor.name !== "Object") {
161
+ return result;
162
+ }
163
+ return mapObjectValues(result, normalizeJsonProtocolValues);
164
+ }
165
+ return result;
166
+ }
167
+ function isTaggedValue(value) {
168
+ return value !== null && typeof value == "object" && typeof value["$type"] === "string";
169
+ }
170
+ function normalizeTaggedValue({ $type, value }) {
171
+ switch ($type) {
172
+ case "BigInt":
173
+ return { $type, value: String(value) };
174
+ case "Bytes":
175
+ return { $type, value };
176
+ case "DateTime":
177
+ return { $type, value: new Date(value).toISOString() };
178
+ case "Decimal":
179
+ return { $type, value: String(new import_decimal2.Decimal(value)) };
180
+ case "Json":
181
+ return { $type, value: JSON.stringify(JSON.parse(value)) };
182
+ default:
183
+ assertNever(value, "Unknown tagged value");
184
+ }
185
+ }
186
+ function mapObjectValues(object, mapper) {
187
+ const result = {};
188
+ for (const key of Object.keys(object)) {
189
+ result[key] = mapper(object[key], key);
190
+ }
191
+ return result;
192
+ }
193
+ function deserializeJsonResponse(result) {
194
+ if (result === null) {
195
+ return result;
196
+ }
197
+ if (Array.isArray(result)) {
198
+ return result.map(deserializeJsonResponse);
199
+ }
200
+ if (typeof result === "object") {
201
+ if (isTaggedValue(result)) {
202
+ return deserializeTaggedValue(result);
203
+ }
204
+ if (result.constructor !== null && result.constructor.name !== "Object") {
205
+ return result;
206
+ }
207
+ return mapObjectValues(result, deserializeJsonResponse);
208
+ }
209
+ return result;
210
+ }
211
+ function deserializeTaggedValue({ $type, value }) {
212
+ switch ($type) {
213
+ case "BigInt":
214
+ return BigInt(value);
215
+ case "Bytes": {
216
+ const { buffer, byteOffset, byteLength } = Buffer.from(value, "base64");
217
+ return new Uint8Array(buffer, byteOffset, byteLength);
218
+ }
219
+ case "DateTime":
220
+ return new Date(value);
221
+ case "Decimal":
222
+ return new import_decimal2.Decimal(value);
223
+ case "Json":
224
+ return JSON.parse(value);
225
+ default:
226
+ assertNever(value, "Unknown tagged value");
227
+ }
228
+ }
229
+
230
+ // src/user-facing-error.ts
231
+ var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
232
+ var UserFacingError = class extends Error {
233
+ name = "UserFacingError";
234
+ code;
235
+ meta;
236
+ constructor(message, code, meta) {
237
+ super(message);
238
+ this.code = code;
239
+ this.meta = meta ?? {};
240
+ }
241
+ toQueryResponseErrorObject() {
242
+ return {
243
+ error: this.message,
244
+ user_facing_error: {
245
+ is_panic: false,
246
+ message: this.message,
247
+ meta: this.meta,
248
+ error_code: this.code
249
+ }
250
+ };
251
+ }
252
+ };
253
+ function rethrowAsUserFacing(error) {
254
+ if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
255
+ throw error;
256
+ }
257
+ const code = getErrorCode(error);
258
+ const message = renderErrorMessage(error);
259
+ if (!code || !message) {
260
+ throw error;
261
+ }
262
+ throw new UserFacingError(message, code, { driverAdapterError: error });
263
+ }
264
+ function rethrowAsUserFacingRawError(error) {
265
+ if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
266
+ throw error;
267
+ }
268
+ throw new UserFacingError(
269
+ `Raw query failed. Code: \`${error.cause.originalCode ?? "N/A"}\`. Message: \`${error.cause.originalMessage ?? renderErrorMessage(error)}\``,
270
+ "P2010",
271
+ { driverAdapterError: error }
272
+ );
273
+ }
274
+ function getErrorCode(err) {
275
+ switch (err.cause.kind) {
276
+ case "AuthenticationFailed":
277
+ return "P1000";
278
+ case "DatabaseNotReachable":
279
+ return "P1001";
280
+ case "DatabaseDoesNotExist":
281
+ return "P1003";
282
+ case "SocketTimeout":
283
+ return "P1008";
284
+ case "DatabaseAlreadyExists":
285
+ return "P1009";
286
+ case "DatabaseAccessDenied":
287
+ return "P1010";
288
+ case "TlsConnectionError":
289
+ return "P1011";
290
+ case "ConnectionClosed":
291
+ return "P1017";
292
+ case "TransactionAlreadyClosed":
293
+ return "P1018";
294
+ case "LengthMismatch":
295
+ return "P2000";
296
+ case "UniqueConstraintViolation":
297
+ return "P2002";
298
+ case "ForeignKeyConstraintViolation":
299
+ return "P2003";
300
+ case "UnsupportedNativeDataType":
301
+ return "P2010";
302
+ case "NullConstraintViolation":
303
+ return "P2011";
304
+ case "ValueOutOfRange":
305
+ return "P2020";
306
+ case "TableDoesNotExist":
307
+ return "P2021";
308
+ case "ColumnNotFound":
309
+ return "P2022";
310
+ case "InvalidIsolationLevel":
311
+ case "InconsistentColumnData":
312
+ return "P2023";
313
+ case "MissingFullTextSearchIndex":
314
+ return "P2030";
315
+ case "TransactionWriteConflict":
316
+ return "P2034";
317
+ case "GenericJs":
318
+ return "P2036";
319
+ case "TooManyConnections":
320
+ return "P2037";
321
+ case "postgres":
322
+ case "sqlite":
323
+ case "mysql":
324
+ case "mssql":
325
+ return;
326
+ default:
327
+ assertNever(err.cause, `Unknown error: ${err.cause}`);
328
+ }
329
+ }
330
+ function renderErrorMessage(err) {
331
+ switch (err.cause.kind) {
332
+ case "AuthenticationFailed": {
333
+ const user = err.cause.user ?? "(not available)";
334
+ return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
335
+ }
336
+ case "DatabaseNotReachable": {
337
+ const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
338
+ return `Can't reach database server${address ? ` at ${address}` : ""}`;
339
+ }
340
+ case "DatabaseDoesNotExist": {
341
+ const db = err.cause.db ?? "(not available)";
342
+ return `Database \`${db}\` does not exist on the database server`;
343
+ }
344
+ case "SocketTimeout":
345
+ return `Operation has timed out`;
346
+ case "DatabaseAlreadyExists": {
347
+ const db = err.cause.db ?? "(not available)";
348
+ return `Database \`${db}\` already exists on the database server`;
349
+ }
350
+ case "DatabaseAccessDenied": {
351
+ const db = err.cause.db ?? "(not available)";
352
+ return `User was denied access on the database \`${db}\``;
353
+ }
354
+ case "TlsConnectionError": {
355
+ return `Error opening a TLS connection: ${err.cause.reason}`;
356
+ }
357
+ case "ConnectionClosed": {
358
+ return "Server has closed the connection.";
359
+ }
360
+ case "TransactionAlreadyClosed":
361
+ return err.cause.cause;
362
+ case "LengthMismatch": {
363
+ const column = err.cause.column ?? "(not available)";
364
+ return `The provided value for the column is too long for the column's type. Column: ${column}`;
365
+ }
366
+ case "UniqueConstraintViolation":
367
+ return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
368
+ case "ForeignKeyConstraintViolation":
369
+ return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
370
+ case "UnsupportedNativeDataType":
371
+ 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\`.`;
372
+ case "NullConstraintViolation":
373
+ return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
374
+ case "ValueOutOfRange":
375
+ return `Value out of range for the type: ${err.cause.cause}`;
376
+ case "TableDoesNotExist": {
377
+ const table = err.cause.table ?? "(not available)";
378
+ return `The table \`${table}\` does not exist in the current database.`;
379
+ }
380
+ case "ColumnNotFound": {
381
+ const column = err.cause.column ?? "(not available)";
382
+ return `The column \`${column}\` does not exist in the current database.`;
383
+ }
384
+ case "InvalidIsolationLevel":
385
+ return `Error in connector: Conversion error: ${err.cause.level}`;
386
+ case "InconsistentColumnData":
387
+ return `Inconsistent column data: ${err.cause.cause}`;
388
+ case "MissingFullTextSearchIndex":
389
+ return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
390
+ case "TransactionWriteConflict":
391
+ return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
392
+ case "GenericJs":
393
+ return `Error in external connector (id ${err.cause.id})`;
394
+ case "TooManyConnections":
395
+ return `Too many database connections opened: ${err.cause.cause}`;
396
+ case "sqlite":
397
+ case "postgres":
398
+ case "mysql":
399
+ case "mssql":
400
+ return;
401
+ default:
402
+ assertNever(err.cause, `Unknown error: ${err.cause}`);
403
+ }
404
+ }
405
+ function renderConstraint(constraint) {
406
+ if (constraint && "fields" in constraint) {
407
+ return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
408
+ } else if (constraint && "index" in constraint) {
409
+ return `constraint: \`${constraint.index}\``;
410
+ } else if (constraint && "foreignKey" in constraint) {
411
+ return `foreign key`;
412
+ }
413
+ return "(not available)";
414
+ }
415
+
416
+ // src/batch.ts
417
+ function convertCompactedRows(rows, compiledBatch) {
418
+ const keysPerRow = rows.map(
419
+ (item) => compiledBatch.keys.reduce((acc, key) => {
420
+ acc[key] = deserializeJsonResponse(item[key]);
421
+ return acc;
422
+ }, {})
423
+ );
424
+ const selection = new Set(compiledBatch.nestedSelection);
425
+ return compiledBatch.arguments.map((args) => {
426
+ const rowIndex = keysPerRow.findIndex((rowKeys) => doKeysMatch(rowKeys, args));
427
+ if (rowIndex === -1) {
428
+ if (compiledBatch.expectNonEmpty) {
429
+ return new UserFacingError(
430
+ "An operation failed because it depends on one or more records that were required but not found",
431
+ "P2025"
432
+ );
433
+ } else {
434
+ return null;
435
+ }
436
+ } else {
437
+ const selected = Object.entries(rows[rowIndex]).filter(([k]) => selection.has(k));
438
+ return Object.fromEntries(selected);
439
+ }
440
+ });
441
+ }
442
+
443
+ // src/interpreter/data-mapper.ts
444
+ var import_decimal3 = __toESM(require("decimal.js"));
146
445
  var DataMapperError = class extends Error {
147
446
  name = "DataMapperError";
148
447
  };
@@ -154,17 +453,20 @@ function applyDataMap(data, structure, enums) {
154
453
  }
155
454
  return { count: data };
156
455
  case "Object":
157
- return mapArrayOrObject(data, structure.fields, enums);
456
+ return mapArrayOrObject(data, structure.fields, enums, structure.skipNulls);
158
457
  case "Value":
159
458
  return mapValue(data, "<result>", structure.resultType, enums);
160
459
  default:
161
460
  assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
162
461
  }
163
462
  }
164
- function mapArrayOrObject(data, fields, enums) {
463
+ function mapArrayOrObject(data, fields, enums, skipNulls) {
165
464
  if (data === null) return null;
166
465
  if (Array.isArray(data)) {
167
- const rows = data;
466
+ let rows = data;
467
+ if (skipNulls) {
468
+ rows = rows.filter((row) => row !== null);
469
+ }
168
470
  return rows.map((row) => mapObject(row, fields, enums));
169
471
  }
170
472
  if (typeof data === "object") {
@@ -180,7 +482,7 @@ function mapArrayOrObject(data, fields, enums) {
180
482
  cause: error
181
483
  });
182
484
  }
183
- return mapArrayOrObject(decodedData, fields, enums);
485
+ return mapArrayOrObject(decodedData, fields, enums, skipNulls);
184
486
  }
185
487
  throw new DataMapperError(`Expected an array or an object, got: ${typeof data}`);
186
488
  }
@@ -201,7 +503,7 @@ function mapObject(data, fields, enums) {
201
503
  );
202
504
  }
203
505
  const target = node.serializedName !== null ? data[node.serializedName] : data;
204
- result[name] = mapArrayOrObject(target, node.fields, enums);
506
+ result[name] = mapArrayOrObject(target, node.fields, enums, node.skipNulls);
205
507
  break;
206
508
  }
207
509
  case "Value":
@@ -294,7 +596,7 @@ function mapValue(value, columnName, resultType, enums) {
294
596
  throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
295
597
  }
296
598
  case "Decimal":
297
- if (typeof value !== "number" && typeof value !== "string" && !import_decimal2.default.isDecimal(value)) {
599
+ if (typeof value !== "number" && typeof value !== "string" && !import_decimal3.default.isDecimal(value)) {
298
600
  throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
299
601
  }
300
602
  return { $type: "Decimal", value };
@@ -318,8 +620,10 @@ function mapValue(value, columnName, resultType, enums) {
318
620
  return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
319
621
  }
320
622
  case "Object": {
321
- const jsonValue = typeof value === "string" ? value : safeJsonStringify(value);
322
- return { $type: "Json", value: jsonValue };
623
+ return { $type: "Json", value: safeJsonStringify(value) };
624
+ }
625
+ case "Json": {
626
+ return { $type: "Json", value: `${value}` };
323
627
  }
324
628
  case "Bytes": {
325
629
  if (typeof value === "string" && value.startsWith("\\x")) {
@@ -340,7 +644,7 @@ function mapValue(value, columnName, resultType, enums) {
340
644
  }
341
645
  const enumValue = enumDef[`${value}`];
342
646
  if (enumValue === void 0) {
343
- throw new DataMapperError(`Unknown enum value '${value}' for enum '${resultType.inner}'`);
647
+ throw new DataMapperError(`Value '${value}' not found in enum '${resultType.inner}'`);
344
648
  }
345
649
  return enumValue;
346
650
  }
@@ -395,201 +699,25 @@ async function withQuerySpanAndEvent({
395
699
  {
396
700
  name: "db_query",
397
701
  kind: import_api.SpanKind.CLIENT,
398
- attributes: {
399
- "db.query.text": query.sql,
400
- "db.system.name": providerToOtelSystem(provider)
401
- }
402
- },
403
- async () => {
404
- const timestamp = /* @__PURE__ */ new Date();
405
- const startInstant = performance.now();
406
- const result = await execute();
407
- const endInstant = performance.now();
408
- onQuery?.({
409
- timestamp,
410
- duration: endInstant - startInstant,
411
- query: query.sql,
412
- params: query.args
413
- });
414
- return result;
415
- }
416
- );
417
- }
418
-
419
- // src/UserFacingError.ts
420
- var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
421
- var UserFacingError = class extends Error {
422
- name = "UserFacingError";
423
- code;
424
- meta;
425
- constructor(message, code, meta) {
426
- super(message);
427
- this.code = code;
428
- this.meta = meta ?? {};
429
- }
430
- toQueryResponseErrorObject() {
431
- return {
432
- error: this.message,
433
- user_facing_error: {
434
- is_panic: false,
435
- message: this.message,
436
- meta: this.meta,
437
- error_code: this.code
438
- }
439
- };
440
- }
441
- };
442
- function rethrowAsUserFacing(error) {
443
- if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
444
- throw error;
445
- }
446
- const code = getErrorCode(error);
447
- const message = renderErrorMessage(error);
448
- if (!code || !message) {
449
- throw error;
450
- }
451
- throw new UserFacingError(message, code, { driverAdapterError: error });
452
- }
453
- function getErrorCode(err) {
454
- switch (err.cause.kind) {
455
- case "AuthenticationFailed":
456
- return "P1000";
457
- case "DatabaseNotReachable":
458
- return "P1001";
459
- case "DatabaseDoesNotExist":
460
- return "P1003";
461
- case "SocketTimeout":
462
- return "P1008";
463
- case "DatabaseAlreadyExists":
464
- return "P1009";
465
- case "DatabaseAccessDenied":
466
- return "P1010";
467
- case "TlsConnectionError":
468
- return "P1011";
469
- case "ConnectionClosed":
470
- return "P1017";
471
- case "TransactionAlreadyClosed":
472
- return "P1018";
473
- case "LengthMismatch":
474
- return "P2000";
475
- case "UniqueConstraintViolation":
476
- return "P2002";
477
- case "ForeignKeyConstraintViolation":
478
- return "P2003";
479
- case "UnsupportedNativeDataType":
480
- return "P2010";
481
- case "NullConstraintViolation":
482
- return "P2011";
483
- case "ValueOutOfRange":
484
- return "P2020";
485
- case "TableDoesNotExist":
486
- return "P2021";
487
- case "ColumnNotFound":
488
- return "P2022";
489
- case "InvalidIsolationLevel":
490
- case "InconsistentColumnData":
491
- return "P2023";
492
- case "MissingFullTextSearchIndex":
493
- return "P2030";
494
- case "TransactionWriteConflict":
495
- return "P2034";
496
- case "GenericJs":
497
- return "P2036";
498
- case "TooManyConnections":
499
- return "P2037";
500
- case "postgres":
501
- case "sqlite":
502
- case "mysql":
503
- case "mssql":
504
- return;
505
- default:
506
- assertNever(err.cause, `Unknown error: ${err.cause}`);
507
- }
508
- }
509
- function renderErrorMessage(err) {
510
- switch (err.cause.kind) {
511
- case "AuthenticationFailed": {
512
- const user = err.cause.user ?? "(not available)";
513
- return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
514
- }
515
- case "DatabaseNotReachable": {
516
- const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
517
- return `Can't reach database server${address ? ` at ${address}` : ""}`;
518
- }
519
- case "DatabaseDoesNotExist": {
520
- const db = err.cause.db ?? "(not available)";
521
- return `Database \`${db}\` does not exist on the database server`;
522
- }
523
- case "SocketTimeout":
524
- return `Operation has timed out`;
525
- case "DatabaseAlreadyExists": {
526
- const db = err.cause.db ?? "(not available)";
527
- return `Database \`${db}\` already exists on the database server`;
528
- }
529
- case "DatabaseAccessDenied": {
530
- const db = err.cause.db ?? "(not available)";
531
- return `User was denied access on the database \`${db}\``;
532
- }
533
- case "TlsConnectionError": {
534
- return `Error opening a TLS connection: ${err.cause.reason}`;
535
- }
536
- case "ConnectionClosed": {
537
- return "Server has closed the connection.";
538
- }
539
- case "TransactionAlreadyClosed":
540
- return err.cause.cause;
541
- case "LengthMismatch": {
542
- const column = err.cause.column ?? "(not available)";
543
- return `The provided value for the column is too long for the column's type. Column: ${column}`;
544
- }
545
- case "UniqueConstraintViolation":
546
- return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
547
- case "ForeignKeyConstraintViolation":
548
- return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
549
- case "UnsupportedNativeDataType":
550
- 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\`.`;
551
- case "NullConstraintViolation":
552
- return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
553
- case "ValueOutOfRange":
554
- return `Value out of range for the type: ${err.cause.cause}`;
555
- case "TableDoesNotExist": {
556
- const table = err.cause.table ?? "(not available)";
557
- return `The table \`${table}\` does not exist in the current database.`;
558
- }
559
- case "ColumnNotFound": {
560
- const column = err.cause.column ?? "(not available)";
561
- return `The column \`${column}\` does not exist in the current database.`;
562
- }
563
- case "InvalidIsolationLevel":
564
- return `Invalid isolation level \`${err.cause.level}\``;
565
- case "InconsistentColumnData":
566
- return `Inconsistent column data: ${err.cause.cause}`;
567
- case "MissingFullTextSearchIndex":
568
- return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
569
- case "TransactionWriteConflict":
570
- return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
571
- case "GenericJs":
572
- return `Error in external connector (id ${err.cause.id})`;
573
- case "TooManyConnections":
574
- return `Too many database connections opened: ${err.cause.cause}`;
575
- case "sqlite":
576
- case "postgres":
577
- case "mysql":
578
- case "mssql":
579
- return;
580
- default:
581
- assertNever(err.cause, `Unknown error: ${err.cause}`);
582
- }
583
- }
584
- function renderConstraint(constraint) {
585
- if (constraint && "fields" in constraint) {
586
- return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
587
- } else if (constraint && "index" in constraint) {
588
- return `constraint: \`${constraint.index}\``;
589
- } else if (constraint && "foreignKey" in constraint) {
590
- return `foreign key`;
591
- }
592
- return "(not available)";
702
+ attributes: {
703
+ "db.query.text": query.sql,
704
+ "db.system.name": providerToOtelSystem(provider)
705
+ }
706
+ },
707
+ async () => {
708
+ const timestamp = /* @__PURE__ */ new Date();
709
+ const startInstant = performance.now();
710
+ const result = await execute();
711
+ const endInstant = performance.now();
712
+ onQuery?.({
713
+ timestamp,
714
+ duration: endInstant - startInstant,
715
+ query: query.sql,
716
+ params: query.args
717
+ });
718
+ return result;
719
+ }
720
+ );
593
721
  }
594
722
 
595
723
  // src/interpreter/generators.ts
@@ -693,7 +821,98 @@ var ProductGenerator = class {
693
821
  }
694
822
  };
695
823
 
696
- // src/QueryPlan.ts
824
+ // src/interpreter/in-memory-processing.ts
825
+ function processRecords(value, ops) {
826
+ if (value == null) {
827
+ return value;
828
+ }
829
+ if (typeof value === "string") {
830
+ return processRecords(JSON.parse(value), ops);
831
+ }
832
+ if (Array.isArray(value)) {
833
+ return processManyRecords(value, ops);
834
+ }
835
+ return processOneRecord(value, ops);
836
+ }
837
+ function processOneRecord(record, ops) {
838
+ if (ops.pagination) {
839
+ const { skip, take, cursor } = ops.pagination;
840
+ if (skip !== null && skip > 0) {
841
+ return null;
842
+ }
843
+ if (take === 0) {
844
+ return null;
845
+ }
846
+ if (cursor !== null && !doKeysMatch(record, cursor)) {
847
+ return null;
848
+ }
849
+ }
850
+ return processNestedRecords(record, ops.nested);
851
+ }
852
+ function processNestedRecords(record, opsMap) {
853
+ for (const [key, ops] of Object.entries(opsMap)) {
854
+ record[key] = processRecords(record[key], ops);
855
+ }
856
+ return record;
857
+ }
858
+ function processManyRecords(records, ops) {
859
+ if (ops.distinct !== null) {
860
+ const fields = ops.linkingFields !== null ? [...ops.distinct, ...ops.linkingFields] : ops.distinct;
861
+ records = distinctBy(records, fields);
862
+ }
863
+ if (ops.pagination) {
864
+ records = paginate(records, ops.pagination, ops.linkingFields);
865
+ }
866
+ if (ops.reverse) {
867
+ records.reverse();
868
+ }
869
+ if (Object.keys(ops.nested).length === 0) {
870
+ return records;
871
+ }
872
+ return records.map((record) => processNestedRecords(record, ops.nested));
873
+ }
874
+ function distinctBy(records, fields) {
875
+ const seen = /* @__PURE__ */ new Set();
876
+ const result = [];
877
+ for (const record of records) {
878
+ const key = getRecordKey(record, fields);
879
+ if (!seen.has(key)) {
880
+ seen.add(key);
881
+ result.push(record);
882
+ }
883
+ }
884
+ return result;
885
+ }
886
+ function paginate(records, pagination, linkingFields) {
887
+ if (linkingFields === null) {
888
+ return paginateSingleList(records, pagination);
889
+ }
890
+ const groupedByParent = /* @__PURE__ */ new Map();
891
+ for (const record of records) {
892
+ const parentKey = getRecordKey(record, linkingFields);
893
+ if (!groupedByParent.has(parentKey)) {
894
+ groupedByParent.set(parentKey, []);
895
+ }
896
+ groupedByParent.get(parentKey).push(record);
897
+ }
898
+ const groupList = Array.from(groupedByParent.entries());
899
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
900
+ return groupList.flatMap(([, elems]) => paginateSingleList(elems, pagination));
901
+ }
902
+ function paginateSingleList(list, { cursor, skip, take }) {
903
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
904
+ if (cursorIndex === -1) {
905
+ return [];
906
+ }
907
+ const start = cursorIndex + (skip ?? 0);
908
+ const end = take !== null ? start + take : list.length;
909
+ return list.slice(start, end);
910
+ }
911
+ function getRecordKey(record, fields) {
912
+ return JSON.stringify(fields.map((field) => record[field]));
913
+ }
914
+
915
+ // src/query-plan.ts
697
916
  function isPrismaValuePlaceholder(value) {
698
917
  return typeof value === "object" && value !== null && value["prisma__type"] === "param";
699
918
  }
@@ -707,18 +926,22 @@ function isPrismaValueBigInt(value) {
707
926
  return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
708
927
  }
709
928
 
710
- // src/interpreter/renderQuery.ts
711
- function renderQuery(dbQuery, scope, generators) {
929
+ // src/interpreter/render-query.ts
930
+ function renderQuery(dbQuery, scope, generators, maxChunkSize) {
712
931
  const queryType = dbQuery.type;
932
+ const params = evaluateParams(dbQuery.params, scope, generators);
713
933
  switch (queryType) {
714
934
  case "rawSql":
715
- return renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators));
716
- case "templateSql":
717
- return renderTemplateSql(
718
- dbQuery.fragments,
719
- dbQuery.placeholderFormat,
720
- evaluateParams(dbQuery.params, scope, generators)
721
- );
935
+ return [renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators))];
936
+ case "templateSql": {
937
+ const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, params, maxChunkSize) : [params];
938
+ return chunks.map((params2) => {
939
+ if (maxChunkSize !== void 0 && params2.length > maxChunkSize) {
940
+ throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
941
+ }
942
+ return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params2);
943
+ });
944
+ }
722
945
  default:
723
946
  assertNever(queryType, `Invalid query type`);
724
947
  }
@@ -756,61 +979,36 @@ function evaluateParam(param, scope, generators) {
756
979
  return value;
757
980
  }
758
981
  function renderTemplateSql(fragments, placeholderFormat, params) {
759
- let paramIndex = 0;
760
- let placeholderNumber = 1;
982
+ let sql = "";
983
+ const ctx = { placeholderNumber: 1 };
761
984
  const flattenedParams = [];
762
- const sql = fragments.map((fragment) => {
763
- const fragmentType = fragment.type;
764
- switch (fragmentType) {
765
- case "parameter":
766
- if (paramIndex >= params.length) {
767
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
768
- }
769
- flattenedParams.push(params[paramIndex++]);
770
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
771
- case "stringChunk":
772
- return fragment.chunk;
773
- case "parameterTuple": {
774
- if (paramIndex >= params.length) {
775
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
776
- }
777
- const paramValue = params[paramIndex++];
778
- const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
779
- const placeholders = paramArray.length == 0 ? "NULL" : paramArray.map((value) => {
780
- flattenedParams.push(value);
781
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
782
- }).join(",");
783
- return `(${placeholders})`;
784
- }
785
- case "parameterTupleList": {
786
- if (paramIndex >= params.length) {
787
- throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
788
- }
789
- const paramValue = params[paramIndex++];
790
- if (!Array.isArray(paramValue)) {
791
- throw new Error(`Malformed query template. Tuple list expected.`);
792
- }
793
- if (paramValue.length === 0) {
794
- throw new Error(`Malformed query template. Tuple list cannot be empty.`);
795
- }
796
- const tupleList = paramValue.map((tuple) => {
797
- if (!Array.isArray(tuple)) {
798
- throw new Error(`Malformed query template. Tuple expected.`);
799
- }
800
- const elements = tuple.map((value) => {
801
- flattenedParams.push(value);
802
- return formatPlaceholder(placeholderFormat, placeholderNumber++);
803
- }).join(fragment.itemSeparator);
804
- return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
805
- }).join(fragment.groupSeparator);
806
- return tupleList;
807
- }
808
- default:
809
- assertNever(fragmentType, "Invalid fragment type");
810
- }
811
- }).join("");
985
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
986
+ flattenedParams.push(...flattenedFragmentParams(fragment));
987
+ sql += renderFragment(fragment, placeholderFormat, ctx);
988
+ }
812
989
  return renderRawSql(sql, flattenedParams);
813
990
  }
991
+ function renderFragment(fragment, placeholderFormat, ctx) {
992
+ const fragmentType = fragment.type;
993
+ switch (fragmentType) {
994
+ case "parameter":
995
+ return formatPlaceholder(placeholderFormat, ctx.placeholderNumber++);
996
+ case "stringChunk":
997
+ return fragment.chunk;
998
+ case "parameterTuple": {
999
+ const placeholders = fragment.value.length == 0 ? "NULL" : fragment.value.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(",");
1000
+ return `(${placeholders})`;
1001
+ }
1002
+ case "parameterTupleList": {
1003
+ return fragment.value.map((tuple) => {
1004
+ const elements = tuple.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(fragment.itemSeparator);
1005
+ return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
1006
+ }).join(fragment.groupSeparator);
1007
+ }
1008
+ default:
1009
+ assertNever(fragmentType, "Invalid fragment type");
1010
+ }
1011
+ }
814
1012
  function formatPlaceholder(placeholderFormat, placeholderNumber) {
815
1013
  return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
816
1014
  }
@@ -843,8 +1041,145 @@ function toArgType(value) {
843
1041
  function doesRequireEvaluation(param) {
844
1042
  return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
845
1043
  }
1044
+ function* pairFragmentsWithParams(fragments, params) {
1045
+ let index = 0;
1046
+ for (const fragment of fragments) {
1047
+ switch (fragment.type) {
1048
+ case "parameter": {
1049
+ if (index >= params.length) {
1050
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
1051
+ }
1052
+ yield { ...fragment, value: params[index++] };
1053
+ break;
1054
+ }
1055
+ case "stringChunk": {
1056
+ yield fragment;
1057
+ break;
1058
+ }
1059
+ case "parameterTuple": {
1060
+ if (index >= params.length) {
1061
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
1062
+ }
1063
+ const value = params[index++];
1064
+ yield { ...fragment, value: Array.isArray(value) ? value : [value] };
1065
+ break;
1066
+ }
1067
+ case "parameterTupleList": {
1068
+ if (index >= params.length) {
1069
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
1070
+ }
1071
+ const value = params[index++];
1072
+ if (!Array.isArray(value)) {
1073
+ throw new Error(`Malformed query template. Tuple list expected.`);
1074
+ }
1075
+ if (value.length === 0) {
1076
+ throw new Error(`Malformed query template. Tuple list cannot be empty.`);
1077
+ }
1078
+ for (const tuple of value) {
1079
+ if (!Array.isArray(tuple)) {
1080
+ throw new Error(`Malformed query template. Tuple expected.`);
1081
+ }
1082
+ }
1083
+ yield { ...fragment, value };
1084
+ break;
1085
+ }
1086
+ }
1087
+ }
1088
+ }
1089
+ function* flattenedFragmentParams(fragment) {
1090
+ switch (fragment.type) {
1091
+ case "parameter":
1092
+ yield fragment.value;
1093
+ break;
1094
+ case "stringChunk":
1095
+ break;
1096
+ case "parameterTuple":
1097
+ yield* fragment.value;
1098
+ break;
1099
+ case "parameterTupleList":
1100
+ for (const tuple of fragment.value) {
1101
+ yield* tuple;
1102
+ }
1103
+ break;
1104
+ }
1105
+ }
1106
+ function chunkParams(fragments, params, maxChunkSize) {
1107
+ let totalParamCount = 0;
1108
+ let maxParamsPerFragment = 0;
1109
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
1110
+ let paramSize = 0;
1111
+ for (const _ of flattenedFragmentParams(fragment)) {
1112
+ void _;
1113
+ paramSize++;
1114
+ }
1115
+ maxParamsPerFragment = Math.max(maxParamsPerFragment, paramSize);
1116
+ totalParamCount += paramSize;
1117
+ }
1118
+ let chunkedParams = [[]];
1119
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
1120
+ switch (fragment.type) {
1121
+ case "parameter": {
1122
+ for (const params2 of chunkedParams) {
1123
+ params2.push(fragment.value);
1124
+ }
1125
+ break;
1126
+ }
1127
+ case "stringChunk": {
1128
+ break;
1129
+ }
1130
+ case "parameterTuple": {
1131
+ const thisParamCount = fragment.value.length;
1132
+ let chunks = [];
1133
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1134
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1135
+ thisParamCount === maxParamsPerFragment && // Do we need chunking to fit the parameters?
1136
+ totalParamCount > maxChunkSize && // Would chunking enable us to fit the parameters?
1137
+ totalParamCount - thisParamCount < maxChunkSize) {
1138
+ const availableSize = maxChunkSize - (totalParamCount - thisParamCount);
1139
+ chunks = chunkArray(fragment.value, availableSize);
1140
+ } else {
1141
+ chunks = [fragment.value];
1142
+ }
1143
+ chunkedParams = chunkedParams.flatMap((params2) => chunks.map((chunk) => [...params2, chunk]));
1144
+ break;
1145
+ }
1146
+ case "parameterTupleList": {
1147
+ const thisParamCount = fragment.value.reduce((acc, tuple) => acc + tuple.length, 0);
1148
+ const completeChunks = [];
1149
+ let currentChunk = [];
1150
+ let currentChunkParamCount = 0;
1151
+ for (const tuple of fragment.value) {
1152
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1153
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1154
+ thisParamCount === maxParamsPerFragment && // Is there anything in the current chunk?
1155
+ currentChunk.length > 0 && // Will adding this tuple exceed the max chunk size?
1156
+ totalParamCount - thisParamCount + currentChunkParamCount + tuple.length > maxChunkSize) {
1157
+ completeChunks.push(currentChunk);
1158
+ currentChunk = [];
1159
+ currentChunkParamCount = 0;
1160
+ }
1161
+ currentChunk.push(tuple);
1162
+ currentChunkParamCount += tuple.length;
1163
+ }
1164
+ if (currentChunk.length > 0) {
1165
+ completeChunks.push(currentChunk);
1166
+ }
1167
+ chunkedParams = chunkedParams.flatMap((params2) => completeChunks.map((chunk) => [...params2, chunk]));
1168
+ break;
1169
+ }
1170
+ }
1171
+ }
1172
+ return chunkedParams;
1173
+ }
1174
+ function chunkArray(array, chunkSize) {
1175
+ const result = [];
1176
+ for (let i = 0; i < array.length; i += chunkSize) {
1177
+ result.push(array.slice(i, i + chunkSize));
1178
+ }
1179
+ return result;
1180
+ }
846
1181
 
847
- // src/interpreter/serializeSql.ts
1182
+ // src/interpreter/serialize-sql.ts
848
1183
  var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
849
1184
  function serializeSql(resultSet) {
850
1185
  const mappers = resultSet.columnTypes.map((type) => {
@@ -875,29 +1210,90 @@ function serializeSql(resultSet) {
875
1210
  );
876
1211
  }
877
1212
  function serializeRawSql(resultSet) {
878
- const types = resultSet.columnTypes.map((type) => serializeColumnType(type));
879
- const mappers = types.map((type) => {
880
- switch (type) {
881
- case "bytes":
882
- return (value) => Array.isArray(value) ? new Uint8Array(value) : value;
883
- case "int":
884
- return (value) => value === null ? null : typeof value === "number" ? value : parseInt(`${value}`, 10);
885
- case "bigint":
886
- return (value) => value === null ? null : typeof value === "bigint" ? value : BigInt(`${value}`);
887
- case "json":
888
- return (value) => typeof value === "string" ? JSON.parse(value) : value;
889
- case "bool":
890
- return (value) => typeof value === "string" ? value === "true" || value === "1" : typeof value === "number" ? value === 1 : value;
891
- default:
892
- return (value) => value;
893
- }
894
- });
895
1213
  return {
896
1214
  columns: resultSet.columnNames,
897
1215
  types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
898
- rows: resultSet.rows.map((row) => row.map((value, index) => mappers[index](value)))
1216
+ rows: resultSet.rows.map(
1217
+ (row) => row.map((value, index) => serializeRawValue(value, resultSet.columnTypes[index]))
1218
+ )
899
1219
  };
900
1220
  }
1221
+ function serializeRawValue(value, type) {
1222
+ if (value === null) {
1223
+ return null;
1224
+ }
1225
+ switch (type) {
1226
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
1227
+ switch (typeof value) {
1228
+ case "number":
1229
+ return Math.trunc(value);
1230
+ case "string":
1231
+ return Math.trunc(Number(value));
1232
+ default:
1233
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32`);
1234
+ }
1235
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int32Array:
1236
+ if (!Array.isArray(value)) {
1237
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32Array`);
1238
+ }
1239
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int32));
1240
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int64:
1241
+ switch (typeof value) {
1242
+ case "number":
1243
+ return BigInt(Math.trunc(value));
1244
+ case "string":
1245
+ return value;
1246
+ default:
1247
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64`);
1248
+ }
1249
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int64Array:
1250
+ if (!Array.isArray(value)) {
1251
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64Array`);
1252
+ }
1253
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int64));
1254
+ case import_driver_adapter_utils2.ColumnTypeEnum.Json:
1255
+ switch (typeof value) {
1256
+ case "string":
1257
+ return JSON.parse(value);
1258
+ default:
1259
+ throw new Error(`Cannot serialize value of type ${typeof value} as Json`);
1260
+ }
1261
+ case import_driver_adapter_utils2.ColumnTypeEnum.JsonArray:
1262
+ if (!Array.isArray(value)) {
1263
+ throw new Error(`Cannot serialize value of type ${typeof value} as JsonArray`);
1264
+ }
1265
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Json));
1266
+ case import_driver_adapter_utils2.ColumnTypeEnum.Bytes:
1267
+ if (Array.isArray(value)) {
1268
+ return new Uint8Array(value);
1269
+ } else {
1270
+ throw new Error(`Cannot serialize value of type ${typeof value} as Bytes`);
1271
+ }
1272
+ case import_driver_adapter_utils2.ColumnTypeEnum.BytesArray:
1273
+ if (!Array.isArray(value)) {
1274
+ throw new Error(`Cannot serialize value of type ${typeof value} as BytesArray`);
1275
+ }
1276
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Bytes));
1277
+ case import_driver_adapter_utils2.ColumnTypeEnum.Boolean:
1278
+ switch (typeof value) {
1279
+ case "boolean":
1280
+ return value;
1281
+ case "string":
1282
+ return value === "true" || value === "1";
1283
+ case "number":
1284
+ return value === 1;
1285
+ default:
1286
+ throw new Error(`Cannot serialize value of type ${typeof value} as Boolean`);
1287
+ }
1288
+ case import_driver_adapter_utils2.ColumnTypeEnum.BooleanArray:
1289
+ if (!Array.isArray(value)) {
1290
+ throw new Error(`Cannot serialize value of type ${typeof value} as BooleanArray`);
1291
+ }
1292
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Boolean));
1293
+ default:
1294
+ return value;
1295
+ }
1296
+ }
901
1297
  function serializeColumnType(columnType) {
902
1298
  switch (columnType) {
903
1299
  case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
@@ -1042,7 +1438,7 @@ function getErrorCode2(error) {
1042
1438
  }
1043
1439
  }
1044
1440
 
1045
- // src/interpreter/QueryInterpreter.ts
1441
+ // src/interpreter/query-interpreter.ts
1046
1442
  var QueryInterpreter = class _QueryInterpreter {
1047
1443
  #transactionManager;
1048
1444
  #placeholderValues;
@@ -1052,6 +1448,7 @@ var QueryInterpreter = class _QueryInterpreter {
1052
1448
  #serializer;
1053
1449
  #rawSerializer;
1054
1450
  #provider;
1451
+ #connectioInfo;
1055
1452
  constructor({
1056
1453
  transactionManager,
1057
1454
  placeholderValues,
@@ -1059,7 +1456,8 @@ var QueryInterpreter = class _QueryInterpreter {
1059
1456
  tracingHelper,
1060
1457
  serializer,
1061
1458
  rawSerializer,
1062
- provider
1459
+ provider,
1460
+ connectionInfo
1063
1461
  }) {
1064
1462
  this.#transactionManager = transactionManager;
1065
1463
  this.#placeholderValues = placeholderValues;
@@ -1068,6 +1466,7 @@ var QueryInterpreter = class _QueryInterpreter {
1068
1466
  this.#serializer = serializer;
1069
1467
  this.#rawSerializer = rawSerializer ?? serializer;
1070
1468
  this.#provider = provider;
1469
+ this.#connectioInfo = connectionInfo;
1071
1470
  }
1072
1471
  static forSql(options) {
1073
1472
  return new _QueryInterpreter({
@@ -1077,7 +1476,8 @@ var QueryInterpreter = class _QueryInterpreter {
1077
1476
  tracingHelper: options.tracingHelper,
1078
1477
  serializer: serializeSql,
1079
1478
  rawSerializer: serializeRawSql,
1080
- provider: options.provider
1479
+ provider: options.provider,
1480
+ connectionInfo: options.connectionInfo
1081
1481
  });
1082
1482
  }
1083
1483
  async run(queryPlan, queryable) {
@@ -1138,21 +1538,41 @@ var QueryInterpreter = class _QueryInterpreter {
1138
1538
  };
1139
1539
  }
1140
1540
  case "execute": {
1141
- const query = renderQuery(node.args, scope, generators);
1142
- return this.#withQuerySpanAndEvent(query, queryable, async () => {
1143
- return { value: await queryable.executeRaw(query) };
1144
- });
1541
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1542
+ let sum = 0;
1543
+ for (const query of queries) {
1544
+ sum += await this.#withQuerySpanAndEvent(
1545
+ query,
1546
+ queryable,
1547
+ () => queryable.executeRaw(query).catch(
1548
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1549
+ )
1550
+ );
1551
+ }
1552
+ return { value: sum };
1145
1553
  }
1146
1554
  case "query": {
1147
- const query = renderQuery(node.args, scope, generators);
1148
- return this.#withQuerySpanAndEvent(query, queryable, async () => {
1149
- const result = await queryable.queryRaw(query);
1150
- if (node.args.type === "rawSql") {
1151
- return { value: this.#rawSerializer(result), lastInsertId: result.lastInsertId };
1555
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1556
+ let results;
1557
+ for (const query of queries) {
1558
+ const result = await this.#withQuerySpanAndEvent(
1559
+ query,
1560
+ queryable,
1561
+ () => queryable.queryRaw(query).catch(
1562
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1563
+ )
1564
+ );
1565
+ if (results === void 0) {
1566
+ results = result;
1152
1567
  } else {
1153
- return { value: this.#serializer(result), lastInsertId: result.lastInsertId };
1568
+ results.rows.push(...result.rows);
1569
+ results.lastInsertId = result.lastInsertId;
1154
1570
  }
1155
- });
1571
+ }
1572
+ return {
1573
+ value: node.args.type === "rawSql" ? this.#rawSerializer(results) : this.#serializer(results),
1574
+ lastInsertId: results?.lastInsertId
1575
+ };
1156
1576
  }
1157
1577
  case "reverse": {
1158
1578
  const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
@@ -1231,43 +1651,12 @@ var QueryInterpreter = class _QueryInterpreter {
1231
1651
  case "diff": {
1232
1652
  const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
1233
1653
  const { value: to } = await this.interpretNode(node.args.to, queryable, scope, generators);
1234
- const toSet = new Set(asList(to));
1235
- return { value: asList(from).filter((item) => !toSet.has(item)) };
1236
- }
1237
- case "distinctBy": {
1238
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
1239
- const seen = /* @__PURE__ */ new Set();
1240
- const result = [];
1241
- for (const item of asList(value)) {
1242
- const key = getRecordKey(item, node.args.fields);
1243
- if (!seen.has(key)) {
1244
- seen.add(key);
1245
- result.push(item);
1246
- }
1247
- }
1248
- return { value: result, lastInsertId };
1654
+ const toSet = new Set(asList(to).map((item) => JSON.stringify(item)));
1655
+ return { value: asList(from).filter((item) => !toSet.has(JSON.stringify(item))) };
1249
1656
  }
1250
- case "paginate": {
1657
+ case "process": {
1251
1658
  const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
1252
- const list = asList(value);
1253
- const linkingFields = node.args.pagination.linkingFields;
1254
- if (linkingFields !== null) {
1255
- const groupedByParent = /* @__PURE__ */ new Map();
1256
- for (const item of list) {
1257
- const parentKey = getRecordKey(item, linkingFields);
1258
- if (!groupedByParent.has(parentKey)) {
1259
- groupedByParent.set(parentKey, []);
1260
- }
1261
- groupedByParent.get(parentKey).push(item);
1262
- }
1263
- const groupList = Array.from(groupedByParent.entries());
1264
- groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
1265
- return {
1266
- value: groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination)),
1267
- lastInsertId
1268
- };
1269
- }
1270
- return { value: paginate(list, node.args.pagination), lastInsertId };
1659
+ return { value: processRecords(value, node.args.operations), lastInsertId };
1271
1660
  }
1272
1661
  case "initializeRecord": {
1273
1662
  const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
@@ -1289,6 +1678,34 @@ var QueryInterpreter = class _QueryInterpreter {
1289
1678
  assertNever(node, `Unexpected node type: ${node.type}`);
1290
1679
  }
1291
1680
  }
1681
+ #maxChunkSize() {
1682
+ if (this.#connectioInfo?.maxBindValues !== void 0) {
1683
+ return this.#connectioInfo.maxBindValues;
1684
+ }
1685
+ return this.#providerMaxChunkSize();
1686
+ }
1687
+ #providerMaxChunkSize() {
1688
+ if (this.#provider === void 0) {
1689
+ return void 0;
1690
+ }
1691
+ switch (this.#provider) {
1692
+ case "cockroachdb":
1693
+ case "postgres":
1694
+ case "postgresql":
1695
+ case "prisma+postgres":
1696
+ return 32766;
1697
+ case "mysql":
1698
+ return 65535;
1699
+ case "sqlite":
1700
+ return 999;
1701
+ case "sqlserver":
1702
+ return 2098;
1703
+ case "mongodb":
1704
+ return void 0;
1705
+ default:
1706
+ assertNever(this.#provider, `Unexpected provider: ${this.#provider}`);
1707
+ }
1708
+ }
1292
1709
  #withQuerySpanAndEvent(query, queryable, execute) {
1293
1710
  return withQuerySpanAndEvent({
1294
1711
  query,
@@ -1366,18 +1783,6 @@ function attachChildrenToParents(parentRecords, children) {
1366
1783
  }
1367
1784
  return parentRecords;
1368
1785
  }
1369
- function paginate(list, { cursor, skip, take }) {
1370
- const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
1371
- if (cursorIndex === -1) {
1372
- return [];
1373
- }
1374
- const start = cursorIndex + (skip ?? 0);
1375
- const end = take !== null ? start + take : list.length;
1376
- return list.slice(start, end);
1377
- }
1378
- function getRecordKey(record, fields) {
1379
- return JSON.stringify(fields.map((field) => record[field]));
1380
- }
1381
1786
  function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
1382
1787
  switch (initializer.type) {
1383
1788
  case "value":
@@ -1411,54 +1816,36 @@ function evalFieldOperation(op, value, scope, generators) {
1411
1816
  }
1412
1817
  }
1413
1818
 
1414
- // src/json-protocol.ts
1415
- var import_decimal3 = require("decimal.js");
1416
- function normalizeJsonProtocolValues(result) {
1417
- if (result === null) {
1418
- return result;
1419
- }
1420
- if (Array.isArray(result)) {
1421
- return result.map(normalizeJsonProtocolValues);
1422
- }
1423
- if (typeof result === "object") {
1424
- if (isTaggedValue(result)) {
1425
- return normalizeTaggedValue(result);
1426
- }
1427
- if (result.constructor !== null && result.constructor.name !== "Object") {
1428
- return result;
1819
+ // src/raw-json-protocol.ts
1820
+ var import_decimal4 = __toESM(require("decimal.js"));
1821
+ function normalizeRawJsonProtocolResponse(response) {
1822
+ for (let i = 0; i < response.rows.length; i++) {
1823
+ const row = response.rows[i];
1824
+ for (let j = 0; j < row.length; j++) {
1825
+ row[j] = normalizeValue(response.types[j], row[j]);
1429
1826
  }
1430
- return mapObjectValues(result, normalizeJsonProtocolValues);
1431
1827
  }
1432
- return result;
1433
- }
1434
- function isTaggedValue(value) {
1435
- return value !== null && typeof value == "object" && typeof value["$type"] === "string";
1828
+ return response;
1436
1829
  }
1437
- function normalizeTaggedValue({ $type, value }) {
1438
- switch ($type) {
1439
- case "BigInt":
1440
- return { $type, value: String(value) };
1441
- case "Bytes":
1442
- return { $type, value };
1443
- case "DateTime":
1444
- return { $type, value: new Date(value).toISOString() };
1445
- case "Decimal":
1446
- return { $type, value: String(new import_decimal3.Decimal(value)) };
1447
- case "Json":
1448
- return { $type, value: JSON.stringify(JSON.parse(value)) };
1449
- default:
1450
- assertNever(value, "Unknown tagged value");
1830
+ function normalizeValue(type, value) {
1831
+ if (value === null) {
1832
+ return value;
1451
1833
  }
1452
- }
1453
- function mapObjectValues(object, mapper) {
1454
- const result = {};
1455
- for (const key of Object.keys(object)) {
1456
- result[key] = mapper(object[key], key);
1834
+ switch (type) {
1835
+ case "bigint":
1836
+ return String(BigInt(value));
1837
+ case "decimal":
1838
+ return String(new import_decimal4.default(value));
1839
+ case "bigint-array":
1840
+ return value.map((v) => normalizeValue("bigint", v));
1841
+ case "decimal-array":
1842
+ return value.map((v) => normalizeValue("decimal", v));
1843
+ default:
1844
+ return value;
1457
1845
  }
1458
- return result;
1459
1846
  }
1460
1847
 
1461
- // src/transactionManager/TransactionManager.ts
1848
+ // src/transaction-manager/transaction-manager.ts
1462
1849
  var import_debug = require("@prisma/debug");
1463
1850
 
1464
1851
  // src/crypto.ts
@@ -1470,7 +1857,7 @@ async function randomUUID() {
1470
1857
  return crypto.randomUUID();
1471
1858
  }
1472
1859
 
1473
- // src/transactionManager/TransactionManagerErrors.ts
1860
+ // src/transaction-manager/transaction-manager-error.ts
1474
1861
  var TransactionManagerError = class extends UserFacingError {
1475
1862
  name = "TransactionManagerError";
1476
1863
  constructor(message, meta) {
@@ -1507,7 +1894,7 @@ var TransactionStartTimeoutError = class extends TransactionManagerError {
1507
1894
  var TransactionExecutionTimeoutError = class extends TransactionManagerError {
1508
1895
  constructor(operation, { timeout, timeTaken }) {
1509
1896
  super(
1510
- `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`,
1897
+ `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.`,
1511
1898
  { operation, timeout, timeTaken }
1512
1899
  );
1513
1900
  }
@@ -1523,7 +1910,7 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
1523
1910
  }
1524
1911
  };
1525
1912
 
1526
- // src/transactionManager/TransactionManager.ts
1913
+ // src/transaction-manager/transaction-manager.ts
1527
1914
  var MAX_CLOSED_TRANSACTIONS = 100;
1528
1915
  var debug = (0, import_debug.Debug)("prisma:client:transactionManager");
1529
1916
  var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
@@ -1578,7 +1965,7 @@ var TransactionManager = class {
1578
1965
  this.transactions.set(transaction.id, transaction);
1579
1966
  let hasTimedOut = false;
1580
1967
  const startTimer = setTimeout(() => hasTimedOut = true, validatedOptions.maxWait);
1581
- transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
1968
+ transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel).catch(rethrowAsUserFacing);
1582
1969
  clearTimeout(startTimer);
1583
1970
  switch (transaction.status) {
1584
1971
  case "waiting":
@@ -1726,6 +2113,8 @@ var TransactionManager = class {
1726
2113
  TransactionManager,
1727
2114
  TransactionManagerError,
1728
2115
  UserFacingError,
2116
+ convertCompactedRows,
2117
+ deserializeJsonResponse,
1729
2118
  doKeysMatch,
1730
2119
  isDeepStrictEqual,
1731
2120
  isPrismaValueBigInt,
@@ -1734,5 +2123,6 @@ var TransactionManager = class {
1734
2123
  isPrismaValuePlaceholder,
1735
2124
  noopTracingHelper,
1736
2125
  normalizeJsonProtocolValues,
2126
+ normalizeRawJsonProtocolResponse,
1737
2127
  safeJsonStringify
1738
2128
  });