@prisma/client-engine-runtime 6.14.0-dev.3 → 6.14.0-dev.30

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
@@ -269,8 +269,10 @@ function mapValue(value, columnName, resultType, enums) {
269
269
  return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
270
270
  }
271
271
  case "Object": {
272
- const jsonValue = typeof value === "string" ? value : safeJsonStringify(value);
273
- return { $type: "Json", value: jsonValue };
272
+ return { $type: "Json", value: safeJsonStringify(value) };
273
+ }
274
+ case "Json": {
275
+ return { $type: "Json", value: `${value}` };
274
276
  }
275
277
  case "Bytes": {
276
278
  if (typeof value === "string" && value.startsWith("\\x")) {
@@ -291,7 +293,7 @@ function mapValue(value, columnName, resultType, enums) {
291
293
  }
292
294
  const enumValue = enumDef[`${value}`];
293
295
  if (enumValue === void 0) {
294
- throw new DataMapperError(`Unknown enum value '${value}' for enum '${resultType.inner}'`);
296
+ throw new DataMapperError(`Value '${value}' not found in enum '${resultType.inner}'`);
295
297
  }
296
298
  return enumValue;
297
299
  }
@@ -401,6 +403,16 @@ function rethrowAsUserFacing(error) {
401
403
  }
402
404
  throw new UserFacingError(message, code, { driverAdapterError: error });
403
405
  }
406
+ function rethrowAsUserFacingRawError(error) {
407
+ if (!isDriverAdapterError(error)) {
408
+ throw error;
409
+ }
410
+ throw new UserFacingError(
411
+ `Raw query failed. Code: ${error.cause.originalCode ?? "N/A"}. Message: ${error.cause.originalMessage ?? renderErrorMessage(error)}`,
412
+ "P2010",
413
+ { driverAdapterError: error }
414
+ );
415
+ }
404
416
  function getErrorCode(err) {
405
417
  switch (err.cause.kind) {
406
418
  case "AuthenticationFailed":
@@ -644,6 +656,97 @@ var ProductGenerator = class {
644
656
  }
645
657
  };
646
658
 
659
+ // src/interpreter/in-memory-processing.ts
660
+ function processRecords(value, ops) {
661
+ if (value == null) {
662
+ return value;
663
+ }
664
+ if (typeof value === "string") {
665
+ return processRecords(JSON.parse(value), ops);
666
+ }
667
+ if (Array.isArray(value)) {
668
+ return processManyRecords(value, ops);
669
+ }
670
+ return processOneRecord(value, ops);
671
+ }
672
+ function processOneRecord(record, ops) {
673
+ if (ops.pagination) {
674
+ const { skip, take, cursor } = ops.pagination;
675
+ if (skip !== null && skip > 0) {
676
+ return null;
677
+ }
678
+ if (take === 0) {
679
+ return null;
680
+ }
681
+ if (cursor !== null && !doKeysMatch(record, cursor)) {
682
+ return null;
683
+ }
684
+ }
685
+ return processNestedRecords(record, ops.nested);
686
+ }
687
+ function processNestedRecords(record, opsMap) {
688
+ for (const [key, ops] of Object.entries(opsMap)) {
689
+ record[key] = processRecords(record[key], ops);
690
+ }
691
+ return record;
692
+ }
693
+ function processManyRecords(records, ops) {
694
+ if (ops.distinct !== null) {
695
+ const fields = ops.linkingFields !== null ? [...ops.distinct, ...ops.linkingFields] : ops.distinct;
696
+ records = distinctBy(records, fields);
697
+ }
698
+ if (ops.pagination) {
699
+ records = paginate(records, ops.pagination, ops.linkingFields);
700
+ }
701
+ if (ops.reverse) {
702
+ records.reverse();
703
+ }
704
+ if (Object.keys(ops.nested).length === 0) {
705
+ return records;
706
+ }
707
+ return records.map((record) => processNestedRecords(record, ops.nested));
708
+ }
709
+ function distinctBy(records, fields) {
710
+ const seen = /* @__PURE__ */ new Set();
711
+ const result = [];
712
+ for (const record of records) {
713
+ const key = getRecordKey(record, fields);
714
+ if (!seen.has(key)) {
715
+ seen.add(key);
716
+ result.push(record);
717
+ }
718
+ }
719
+ return result;
720
+ }
721
+ function paginate(records, pagination, linkingFields) {
722
+ if (linkingFields === null) {
723
+ return paginateSingleList(records, pagination);
724
+ }
725
+ const groupedByParent = /* @__PURE__ */ new Map();
726
+ for (const record of records) {
727
+ const parentKey = getRecordKey(record, linkingFields);
728
+ if (!groupedByParent.has(parentKey)) {
729
+ groupedByParent.set(parentKey, []);
730
+ }
731
+ groupedByParent.get(parentKey).push(record);
732
+ }
733
+ const groupList = Array.from(groupedByParent.entries());
734
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
735
+ return groupList.flatMap(([, elems]) => paginateSingleList(elems, pagination));
736
+ }
737
+ function paginateSingleList(list, { cursor, skip, take }) {
738
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
739
+ if (cursorIndex === -1) {
740
+ return [];
741
+ }
742
+ const start = cursorIndex + (skip ?? 0);
743
+ const end = take !== null ? start + take : list.length;
744
+ return list.slice(start, end);
745
+ }
746
+ function getRecordKey(record, fields) {
747
+ return JSON.stringify(fields.map((field) => record[field]));
748
+ }
749
+
647
750
  // src/QueryPlan.ts
648
751
  function isPrismaValuePlaceholder(value) {
649
752
  return typeof value === "object" && value !== null && value["prisma__type"] === "param";
@@ -659,17 +762,21 @@ function isPrismaValueBigInt(value) {
659
762
  }
660
763
 
661
764
  // src/interpreter/renderQuery.ts
662
- function renderQuery(dbQuery, scope, generators) {
765
+ function renderQuery(dbQuery, scope, generators, maxChunkSize) {
663
766
  const queryType = dbQuery.type;
767
+ const params = evaluateParams(dbQuery.params, scope, generators);
664
768
  switch (queryType) {
665
769
  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
- );
770
+ return [renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators))];
771
+ case "templateSql": {
772
+ const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, params, maxChunkSize) : [params];
773
+ return chunks.map((params2) => {
774
+ if (maxChunkSize !== void 0 && params2.length > maxChunkSize) {
775
+ throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
776
+ }
777
+ return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params2);
778
+ });
779
+ }
673
780
  default:
674
781
  assertNever(queryType, `Invalid query type`);
675
782
  }
@@ -707,61 +814,36 @@ function evaluateParam(param, scope, generators) {
707
814
  return value;
708
815
  }
709
816
  function renderTemplateSql(fragments, placeholderFormat, params) {
710
- let paramIndex = 0;
711
- let placeholderNumber = 1;
817
+ let sql = "";
818
+ const ctx = { placeholderNumber: 1 };
712
819
  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("");
820
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
821
+ flattenedParams.push(...flattenedFragmentParams(fragment));
822
+ sql += renderFragment(fragment, placeholderFormat, ctx);
823
+ }
763
824
  return renderRawSql(sql, flattenedParams);
764
825
  }
826
+ function renderFragment(fragment, placeholderFormat, ctx) {
827
+ const fragmentType = fragment.type;
828
+ switch (fragmentType) {
829
+ case "parameter":
830
+ return formatPlaceholder(placeholderFormat, ctx.placeholderNumber++);
831
+ case "stringChunk":
832
+ return fragment.chunk;
833
+ case "parameterTuple": {
834
+ const placeholders = fragment.value.length == 0 ? "NULL" : fragment.value.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(",");
835
+ return `(${placeholders})`;
836
+ }
837
+ case "parameterTupleList": {
838
+ return fragment.value.map((tuple) => {
839
+ const elements = tuple.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(fragment.itemSeparator);
840
+ return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
841
+ }).join(fragment.groupSeparator);
842
+ }
843
+ default:
844
+ assertNever(fragmentType, "Invalid fragment type");
845
+ }
846
+ }
765
847
  function formatPlaceholder(placeholderFormat, placeholderNumber) {
766
848
  return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
767
849
  }
@@ -794,6 +876,143 @@ function toArgType(value) {
794
876
  function doesRequireEvaluation(param) {
795
877
  return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
796
878
  }
879
+ function* pairFragmentsWithParams(fragments, params) {
880
+ let index = 0;
881
+ for (const fragment of fragments) {
882
+ switch (fragment.type) {
883
+ case "parameter": {
884
+ if (index >= params.length) {
885
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
886
+ }
887
+ yield { ...fragment, value: params[index++] };
888
+ break;
889
+ }
890
+ case "stringChunk": {
891
+ yield fragment;
892
+ break;
893
+ }
894
+ case "parameterTuple": {
895
+ if (index >= params.length) {
896
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
897
+ }
898
+ const value = params[index++];
899
+ yield { ...fragment, value: Array.isArray(value) ? value : [value] };
900
+ break;
901
+ }
902
+ case "parameterTupleList": {
903
+ if (index >= params.length) {
904
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
905
+ }
906
+ const value = params[index++];
907
+ if (!Array.isArray(value)) {
908
+ throw new Error(`Malformed query template. Tuple list expected.`);
909
+ }
910
+ if (value.length === 0) {
911
+ throw new Error(`Malformed query template. Tuple list cannot be empty.`);
912
+ }
913
+ for (const tuple of value) {
914
+ if (!Array.isArray(tuple)) {
915
+ throw new Error(`Malformed query template. Tuple expected.`);
916
+ }
917
+ }
918
+ yield { ...fragment, value };
919
+ break;
920
+ }
921
+ }
922
+ }
923
+ }
924
+ function* flattenedFragmentParams(fragment) {
925
+ switch (fragment.type) {
926
+ case "parameter":
927
+ yield fragment.value;
928
+ break;
929
+ case "stringChunk":
930
+ break;
931
+ case "parameterTuple":
932
+ yield* fragment.value;
933
+ break;
934
+ case "parameterTupleList":
935
+ for (const tuple of fragment.value) {
936
+ yield* tuple;
937
+ }
938
+ break;
939
+ }
940
+ }
941
+ function chunkParams(fragments, params, maxChunkSize) {
942
+ let totalParamCount = 0;
943
+ let maxParamsPerFragment = 0;
944
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
945
+ let paramSize = 0;
946
+ for (const _ of flattenedFragmentParams(fragment)) {
947
+ void _;
948
+ paramSize++;
949
+ }
950
+ maxParamsPerFragment = Math.max(maxParamsPerFragment, paramSize);
951
+ totalParamCount += paramSize;
952
+ }
953
+ let chunkedParams = [[]];
954
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
955
+ switch (fragment.type) {
956
+ case "parameter": {
957
+ for (const params2 of chunkedParams) {
958
+ params2.push(fragment.value);
959
+ }
960
+ break;
961
+ }
962
+ case "stringChunk": {
963
+ break;
964
+ }
965
+ case "parameterTuple": {
966
+ const thisParamCount = fragment.value.length;
967
+ let chunks = [];
968
+ if (maxChunkSize && // Have we split the parameters into chunks already?
969
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
970
+ thisParamCount === maxParamsPerFragment && // Do we need chunking to fit the parameters?
971
+ totalParamCount > maxChunkSize && // Would chunking enable us to fit the parameters?
972
+ totalParamCount - thisParamCount < maxChunkSize) {
973
+ const availableSize = maxChunkSize - (totalParamCount - thisParamCount);
974
+ chunks = chunkArray(fragment.value, availableSize);
975
+ } else {
976
+ chunks = [fragment.value];
977
+ }
978
+ chunkedParams = chunkedParams.flatMap((params2) => chunks.map((chunk) => [...params2, chunk]));
979
+ break;
980
+ }
981
+ case "parameterTupleList": {
982
+ const thisParamCount = fragment.value.reduce((acc, tuple) => acc + tuple.length, 0);
983
+ const completeChunks = [];
984
+ let currentChunk = [];
985
+ let currentChunkParamCount = 0;
986
+ for (const tuple of fragment.value) {
987
+ if (maxChunkSize && // Have we split the parameters into chunks already?
988
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
989
+ thisParamCount === maxParamsPerFragment && // Is there anything in the current chunk?
990
+ currentChunk.length > 0 && // Will adding this tuple exceed the max chunk size?
991
+ totalParamCount - thisParamCount + currentChunkParamCount + tuple.length > maxChunkSize) {
992
+ completeChunks.push(currentChunk);
993
+ currentChunk = [];
994
+ currentChunkParamCount = 0;
995
+ }
996
+ currentChunk.push(tuple);
997
+ currentChunkParamCount += tuple.length;
998
+ }
999
+ if (currentChunk.length > 0) {
1000
+ completeChunks.push(currentChunk);
1001
+ }
1002
+ chunkedParams = chunkedParams.flatMap((params2) => completeChunks.map((chunk) => [...params2, chunk]));
1003
+ break;
1004
+ }
1005
+ }
1006
+ }
1007
+ return chunkedParams;
1008
+ }
1009
+ function chunkArray(array, chunkSize) {
1010
+ const result = [];
1011
+ for (let i = 0; i < array.length; i += chunkSize) {
1012
+ result.push(array.slice(i, i + chunkSize));
1013
+ }
1014
+ return result;
1015
+ }
797
1016
 
798
1017
  // src/interpreter/serializeSql.ts
799
1018
  import { ColumnTypeEnum } from "@prisma/driver-adapter-utils";
@@ -826,29 +1045,90 @@ function serializeSql(resultSet) {
826
1045
  );
827
1046
  }
828
1047
  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
1048
  return {
847
1049
  columns: resultSet.columnNames,
848
1050
  types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
849
- rows: resultSet.rows.map((row) => row.map((value, index) => mappers[index](value)))
1051
+ rows: resultSet.rows.map(
1052
+ (row) => row.map((value, index) => serializeRawValue(value, resultSet.columnTypes[index]))
1053
+ )
850
1054
  };
851
1055
  }
1056
+ function serializeRawValue(value, type) {
1057
+ if (value === null) {
1058
+ return null;
1059
+ }
1060
+ switch (type) {
1061
+ case ColumnTypeEnum.Int32:
1062
+ switch (typeof value) {
1063
+ case "number":
1064
+ return Math.trunc(value);
1065
+ case "string":
1066
+ return Math.trunc(Number(value));
1067
+ default:
1068
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32`);
1069
+ }
1070
+ case ColumnTypeEnum.Int32Array:
1071
+ if (!Array.isArray(value)) {
1072
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32Array`);
1073
+ }
1074
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Int32));
1075
+ case ColumnTypeEnum.Int64:
1076
+ switch (typeof value) {
1077
+ case "number":
1078
+ return BigInt(Math.trunc(value));
1079
+ case "string":
1080
+ return value;
1081
+ default:
1082
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64`);
1083
+ }
1084
+ case ColumnTypeEnum.Int64Array:
1085
+ if (!Array.isArray(value)) {
1086
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64Array`);
1087
+ }
1088
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Int64));
1089
+ case ColumnTypeEnum.Json:
1090
+ switch (typeof value) {
1091
+ case "string":
1092
+ return JSON.parse(value);
1093
+ default:
1094
+ throw new Error(`Cannot serialize value of type ${typeof value} as Json`);
1095
+ }
1096
+ case ColumnTypeEnum.JsonArray:
1097
+ if (!Array.isArray(value)) {
1098
+ throw new Error(`Cannot serialize value of type ${typeof value} as JsonArray`);
1099
+ }
1100
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Json));
1101
+ case ColumnTypeEnum.Bytes:
1102
+ if (Array.isArray(value)) {
1103
+ return new Uint8Array(value);
1104
+ } else {
1105
+ throw new Error(`Cannot serialize value of type ${typeof value} as Bytes`);
1106
+ }
1107
+ case ColumnTypeEnum.BytesArray:
1108
+ if (!Array.isArray(value)) {
1109
+ throw new Error(`Cannot serialize value of type ${typeof value} as BytesArray`);
1110
+ }
1111
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Bytes));
1112
+ case ColumnTypeEnum.Boolean:
1113
+ switch (typeof value) {
1114
+ case "boolean":
1115
+ return value;
1116
+ case "string":
1117
+ return value === "true" || value === "1";
1118
+ case "number":
1119
+ return value === 1;
1120
+ default:
1121
+ throw new Error(`Cannot serialize value of type ${typeof value} as Boolean`);
1122
+ }
1123
+ case ColumnTypeEnum.BooleanArray:
1124
+ if (!Array.isArray(value)) {
1125
+ throw new Error(`Cannot serialize value of type ${typeof value} as BooleanArray`);
1126
+ }
1127
+ return value.map((v) => serializeRawValue(v, ColumnTypeEnum.Boolean));
1128
+ default:
1129
+ return value;
1130
+ }
1131
+ }
852
1132
  function serializeColumnType(columnType) {
853
1133
  switch (columnType) {
854
1134
  case ColumnTypeEnum.Int32:
@@ -1003,6 +1283,7 @@ var QueryInterpreter = class _QueryInterpreter {
1003
1283
  #serializer;
1004
1284
  #rawSerializer;
1005
1285
  #provider;
1286
+ #connectioInfo;
1006
1287
  constructor({
1007
1288
  transactionManager,
1008
1289
  placeholderValues,
@@ -1010,7 +1291,8 @@ var QueryInterpreter = class _QueryInterpreter {
1010
1291
  tracingHelper,
1011
1292
  serializer,
1012
1293
  rawSerializer,
1013
- provider
1294
+ provider,
1295
+ connectionInfo
1014
1296
  }) {
1015
1297
  this.#transactionManager = transactionManager;
1016
1298
  this.#placeholderValues = placeholderValues;
@@ -1019,6 +1301,7 @@ var QueryInterpreter = class _QueryInterpreter {
1019
1301
  this.#serializer = serializer;
1020
1302
  this.#rawSerializer = rawSerializer ?? serializer;
1021
1303
  this.#provider = provider;
1304
+ this.#connectioInfo = connectionInfo;
1022
1305
  }
1023
1306
  static forSql(options) {
1024
1307
  return new _QueryInterpreter({
@@ -1028,7 +1311,8 @@ var QueryInterpreter = class _QueryInterpreter {
1028
1311
  tracingHelper: options.tracingHelper,
1029
1312
  serializer: serializeSql,
1030
1313
  rawSerializer: serializeRawSql,
1031
- provider: options.provider
1314
+ provider: options.provider,
1315
+ connectionInfo: options.connectionInfo
1032
1316
  });
1033
1317
  }
1034
1318
  async run(queryPlan, queryable) {
@@ -1089,21 +1373,41 @@ var QueryInterpreter = class _QueryInterpreter {
1089
1373
  };
1090
1374
  }
1091
1375
  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
- });
1376
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1377
+ let sum = 0;
1378
+ for (const query of queries) {
1379
+ sum += await this.#withQuerySpanAndEvent(
1380
+ query,
1381
+ queryable,
1382
+ () => queryable.executeRaw(query).catch(
1383
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1384
+ )
1385
+ );
1386
+ }
1387
+ return { value: sum };
1096
1388
  }
1097
1389
  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 };
1390
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1391
+ let results;
1392
+ for (const query of queries) {
1393
+ const result = await this.#withQuerySpanAndEvent(
1394
+ query,
1395
+ queryable,
1396
+ () => queryable.queryRaw(query).catch(
1397
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1398
+ )
1399
+ );
1400
+ if (results === void 0) {
1401
+ results = result;
1103
1402
  } else {
1104
- return { value: this.#serializer(result), lastInsertId: result.lastInsertId };
1403
+ results.rows.push(...result.rows);
1404
+ results.lastInsertId = result.lastInsertId;
1105
1405
  }
1106
- });
1406
+ }
1407
+ return {
1408
+ value: node.args.type === "rawSql" ? this.#rawSerializer(results) : this.#serializer(results),
1409
+ lastInsertId: results?.lastInsertId
1410
+ };
1107
1411
  }
1108
1412
  case "reverse": {
1109
1413
  const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
@@ -1182,43 +1486,12 @@ var QueryInterpreter = class _QueryInterpreter {
1182
1486
  case "diff": {
1183
1487
  const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
1184
1488
  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)) };
1489
+ const toSet = new Set(asList(to).map((item) => JSON.stringify(item)));
1490
+ return { value: asList(from).filter((item) => !toSet.has(JSON.stringify(item))) };
1187
1491
  }
1188
- case "distinctBy": {
1492
+ case "process": {
1189
1493
  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 };
1200
- }
1201
- case "paginate": {
1202
- 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 };
1494
+ return { value: processRecords(value, node.args.operations), lastInsertId };
1222
1495
  }
1223
1496
  case "initializeRecord": {
1224
1497
  const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
@@ -1240,6 +1513,34 @@ var QueryInterpreter = class _QueryInterpreter {
1240
1513
  assertNever(node, `Unexpected node type: ${node.type}`);
1241
1514
  }
1242
1515
  }
1516
+ #maxChunkSize() {
1517
+ if (this.#connectioInfo?.maxBindValues !== void 0) {
1518
+ return this.#connectioInfo.maxBindValues;
1519
+ }
1520
+ return this.#providerMaxChunkSize();
1521
+ }
1522
+ #providerMaxChunkSize() {
1523
+ if (this.#provider === void 0) {
1524
+ return void 0;
1525
+ }
1526
+ switch (this.#provider) {
1527
+ case "cockroachdb":
1528
+ case "postgres":
1529
+ case "postgresql":
1530
+ case "prisma+postgres":
1531
+ return 32766;
1532
+ case "mysql":
1533
+ return 65535;
1534
+ case "sqlite":
1535
+ return 999;
1536
+ case "sqlserver":
1537
+ return 2098;
1538
+ case "mongodb":
1539
+ return void 0;
1540
+ default:
1541
+ assertNever(this.#provider, `Unexpected provider: ${this.#provider}`);
1542
+ }
1543
+ }
1243
1544
  #withQuerySpanAndEvent(query, queryable, execute) {
1244
1545
  return withQuerySpanAndEvent({
1245
1546
  query,
@@ -1317,18 +1618,6 @@ function attachChildrenToParents(parentRecords, children) {
1317
1618
  }
1318
1619
  return parentRecords;
1319
1620
  }
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
1621
  function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
1333
1622
  switch (initializer.type) {
1334
1623
  case "value":
@@ -1409,6 +1698,35 @@ function mapObjectValues(object, mapper) {
1409
1698
  return result;
1410
1699
  }
1411
1700
 
1701
+ // src/raw-json-protocol.ts
1702
+ import Decimal4 from "decimal.js";
1703
+ function normalizeRawJsonProtocolResponse(response) {
1704
+ for (let i = 0; i < response.rows.length; i++) {
1705
+ const row = response.rows[i];
1706
+ for (let j = 0; j < row.length; j++) {
1707
+ row[j] = normalizeValue(response.types[j], row[j]);
1708
+ }
1709
+ }
1710
+ return response;
1711
+ }
1712
+ function normalizeValue(type, value) {
1713
+ if (value === null) {
1714
+ return value;
1715
+ }
1716
+ switch (type) {
1717
+ case "bigint":
1718
+ return String(BigInt(value));
1719
+ case "decimal":
1720
+ return String(new Decimal4(value));
1721
+ case "bigint-array":
1722
+ return value.map((v) => normalizeValue("bigint", v));
1723
+ case "decimal-array":
1724
+ return value.map((v) => normalizeValue("decimal", v));
1725
+ default:
1726
+ return value;
1727
+ }
1728
+ }
1729
+
1412
1730
  // src/transactionManager/TransactionManager.ts
1413
1731
  import { Debug } from "@prisma/debug";
1414
1732
 
@@ -1684,5 +2002,6 @@ export {
1684
2002
  isPrismaValuePlaceholder,
1685
2003
  noopTracingHelper,
1686
2004
  normalizeJsonProtocolValues,
2005
+ normalizeRawJsonProtocolResponse,
1687
2006
  safeJsonStringify
1688
2007
  };