@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.js CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
44
44
  noopTracingHelper: () => noopTracingHelper,
45
45
  normalizeJsonProtocolValues: () => normalizeJsonProtocolValues,
46
+ normalizeRawJsonProtocolResponse: () => normalizeRawJsonProtocolResponse,
46
47
  safeJsonStringify: () => safeJsonStringify
47
48
  });
48
49
  module.exports = __toCommonJS(index_exports);
@@ -318,8 +319,10 @@ function mapValue(value, columnName, resultType, enums) {
318
319
  return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
319
320
  }
320
321
  case "Object": {
321
- const jsonValue = typeof value === "string" ? value : safeJsonStringify(value);
322
- return { $type: "Json", value: jsonValue };
322
+ return { $type: "Json", value: safeJsonStringify(value) };
323
+ }
324
+ case "Json": {
325
+ return { $type: "Json", value: `${value}` };
323
326
  }
324
327
  case "Bytes": {
325
328
  if (typeof value === "string" && value.startsWith("\\x")) {
@@ -340,7 +343,7 @@ function mapValue(value, columnName, resultType, enums) {
340
343
  }
341
344
  const enumValue = enumDef[`${value}`];
342
345
  if (enumValue === void 0) {
343
- throw new DataMapperError(`Unknown enum value '${value}' for enum '${resultType.inner}'`);
346
+ throw new DataMapperError(`Value '${value}' not found in enum '${resultType.inner}'`);
344
347
  }
345
348
  return enumValue;
346
349
  }
@@ -450,6 +453,16 @@ function rethrowAsUserFacing(error) {
450
453
  }
451
454
  throw new UserFacingError(message, code, { driverAdapterError: error });
452
455
  }
456
+ function rethrowAsUserFacingRawError(error) {
457
+ if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
458
+ throw error;
459
+ }
460
+ throw new UserFacingError(
461
+ `Raw query failed. Code: ${error.cause.originalCode ?? "N/A"}. Message: ${error.cause.originalMessage ?? renderErrorMessage(error)}`,
462
+ "P2010",
463
+ { driverAdapterError: error }
464
+ );
465
+ }
453
466
  function getErrorCode(err) {
454
467
  switch (err.cause.kind) {
455
468
  case "AuthenticationFailed":
@@ -693,6 +706,97 @@ var ProductGenerator = class {
693
706
  }
694
707
  };
695
708
 
709
+ // src/interpreter/in-memory-processing.ts
710
+ function processRecords(value, ops) {
711
+ if (value == null) {
712
+ return value;
713
+ }
714
+ if (typeof value === "string") {
715
+ return processRecords(JSON.parse(value), ops);
716
+ }
717
+ if (Array.isArray(value)) {
718
+ return processManyRecords(value, ops);
719
+ }
720
+ return processOneRecord(value, ops);
721
+ }
722
+ function processOneRecord(record, ops) {
723
+ if (ops.pagination) {
724
+ const { skip, take, cursor } = ops.pagination;
725
+ if (skip !== null && skip > 0) {
726
+ return null;
727
+ }
728
+ if (take === 0) {
729
+ return null;
730
+ }
731
+ if (cursor !== null && !doKeysMatch(record, cursor)) {
732
+ return null;
733
+ }
734
+ }
735
+ return processNestedRecords(record, ops.nested);
736
+ }
737
+ function processNestedRecords(record, opsMap) {
738
+ for (const [key, ops] of Object.entries(opsMap)) {
739
+ record[key] = processRecords(record[key], ops);
740
+ }
741
+ return record;
742
+ }
743
+ function processManyRecords(records, ops) {
744
+ if (ops.distinct !== null) {
745
+ const fields = ops.linkingFields !== null ? [...ops.distinct, ...ops.linkingFields] : ops.distinct;
746
+ records = distinctBy(records, fields);
747
+ }
748
+ if (ops.pagination) {
749
+ records = paginate(records, ops.pagination, ops.linkingFields);
750
+ }
751
+ if (ops.reverse) {
752
+ records.reverse();
753
+ }
754
+ if (Object.keys(ops.nested).length === 0) {
755
+ return records;
756
+ }
757
+ return records.map((record) => processNestedRecords(record, ops.nested));
758
+ }
759
+ function distinctBy(records, fields) {
760
+ const seen = /* @__PURE__ */ new Set();
761
+ const result = [];
762
+ for (const record of records) {
763
+ const key = getRecordKey(record, fields);
764
+ if (!seen.has(key)) {
765
+ seen.add(key);
766
+ result.push(record);
767
+ }
768
+ }
769
+ return result;
770
+ }
771
+ function paginate(records, pagination, linkingFields) {
772
+ if (linkingFields === null) {
773
+ return paginateSingleList(records, pagination);
774
+ }
775
+ const groupedByParent = /* @__PURE__ */ new Map();
776
+ for (const record of records) {
777
+ const parentKey = getRecordKey(record, linkingFields);
778
+ if (!groupedByParent.has(parentKey)) {
779
+ groupedByParent.set(parentKey, []);
780
+ }
781
+ groupedByParent.get(parentKey).push(record);
782
+ }
783
+ const groupList = Array.from(groupedByParent.entries());
784
+ groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
785
+ return groupList.flatMap(([, elems]) => paginateSingleList(elems, pagination));
786
+ }
787
+ function paginateSingleList(list, { cursor, skip, take }) {
788
+ const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
789
+ if (cursorIndex === -1) {
790
+ return [];
791
+ }
792
+ const start = cursorIndex + (skip ?? 0);
793
+ const end = take !== null ? start + take : list.length;
794
+ return list.slice(start, end);
795
+ }
796
+ function getRecordKey(record, fields) {
797
+ return JSON.stringify(fields.map((field) => record[field]));
798
+ }
799
+
696
800
  // src/QueryPlan.ts
697
801
  function isPrismaValuePlaceholder(value) {
698
802
  return typeof value === "object" && value !== null && value["prisma__type"] === "param";
@@ -708,17 +812,21 @@ function isPrismaValueBigInt(value) {
708
812
  }
709
813
 
710
814
  // src/interpreter/renderQuery.ts
711
- function renderQuery(dbQuery, scope, generators) {
815
+ function renderQuery(dbQuery, scope, generators, maxChunkSize) {
712
816
  const queryType = dbQuery.type;
817
+ const params = evaluateParams(dbQuery.params, scope, generators);
713
818
  switch (queryType) {
714
819
  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
- );
820
+ return [renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators))];
821
+ case "templateSql": {
822
+ const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, params, maxChunkSize) : [params];
823
+ return chunks.map((params2) => {
824
+ if (maxChunkSize !== void 0 && params2.length > maxChunkSize) {
825
+ throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
826
+ }
827
+ return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params2);
828
+ });
829
+ }
722
830
  default:
723
831
  assertNever(queryType, `Invalid query type`);
724
832
  }
@@ -756,61 +864,36 @@ function evaluateParam(param, scope, generators) {
756
864
  return value;
757
865
  }
758
866
  function renderTemplateSql(fragments, placeholderFormat, params) {
759
- let paramIndex = 0;
760
- let placeholderNumber = 1;
867
+ let sql = "";
868
+ const ctx = { placeholderNumber: 1 };
761
869
  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("");
870
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
871
+ flattenedParams.push(...flattenedFragmentParams(fragment));
872
+ sql += renderFragment(fragment, placeholderFormat, ctx);
873
+ }
812
874
  return renderRawSql(sql, flattenedParams);
813
875
  }
876
+ function renderFragment(fragment, placeholderFormat, ctx) {
877
+ const fragmentType = fragment.type;
878
+ switch (fragmentType) {
879
+ case "parameter":
880
+ return formatPlaceholder(placeholderFormat, ctx.placeholderNumber++);
881
+ case "stringChunk":
882
+ return fragment.chunk;
883
+ case "parameterTuple": {
884
+ const placeholders = fragment.value.length == 0 ? "NULL" : fragment.value.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(",");
885
+ return `(${placeholders})`;
886
+ }
887
+ case "parameterTupleList": {
888
+ return fragment.value.map((tuple) => {
889
+ const elements = tuple.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(fragment.itemSeparator);
890
+ return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
891
+ }).join(fragment.groupSeparator);
892
+ }
893
+ default:
894
+ assertNever(fragmentType, "Invalid fragment type");
895
+ }
896
+ }
814
897
  function formatPlaceholder(placeholderFormat, placeholderNumber) {
815
898
  return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
816
899
  }
@@ -843,6 +926,143 @@ function toArgType(value) {
843
926
  function doesRequireEvaluation(param) {
844
927
  return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
845
928
  }
929
+ function* pairFragmentsWithParams(fragments, params) {
930
+ let index = 0;
931
+ for (const fragment of fragments) {
932
+ switch (fragment.type) {
933
+ case "parameter": {
934
+ if (index >= params.length) {
935
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
936
+ }
937
+ yield { ...fragment, value: params[index++] };
938
+ break;
939
+ }
940
+ case "stringChunk": {
941
+ yield fragment;
942
+ break;
943
+ }
944
+ case "parameterTuple": {
945
+ if (index >= params.length) {
946
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
947
+ }
948
+ const value = params[index++];
949
+ yield { ...fragment, value: Array.isArray(value) ? value : [value] };
950
+ break;
951
+ }
952
+ case "parameterTupleList": {
953
+ if (index >= params.length) {
954
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
955
+ }
956
+ const value = params[index++];
957
+ if (!Array.isArray(value)) {
958
+ throw new Error(`Malformed query template. Tuple list expected.`);
959
+ }
960
+ if (value.length === 0) {
961
+ throw new Error(`Malformed query template. Tuple list cannot be empty.`);
962
+ }
963
+ for (const tuple of value) {
964
+ if (!Array.isArray(tuple)) {
965
+ throw new Error(`Malformed query template. Tuple expected.`);
966
+ }
967
+ }
968
+ yield { ...fragment, value };
969
+ break;
970
+ }
971
+ }
972
+ }
973
+ }
974
+ function* flattenedFragmentParams(fragment) {
975
+ switch (fragment.type) {
976
+ case "parameter":
977
+ yield fragment.value;
978
+ break;
979
+ case "stringChunk":
980
+ break;
981
+ case "parameterTuple":
982
+ yield* fragment.value;
983
+ break;
984
+ case "parameterTupleList":
985
+ for (const tuple of fragment.value) {
986
+ yield* tuple;
987
+ }
988
+ break;
989
+ }
990
+ }
991
+ function chunkParams(fragments, params, maxChunkSize) {
992
+ let totalParamCount = 0;
993
+ let maxParamsPerFragment = 0;
994
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
995
+ let paramSize = 0;
996
+ for (const _ of flattenedFragmentParams(fragment)) {
997
+ void _;
998
+ paramSize++;
999
+ }
1000
+ maxParamsPerFragment = Math.max(maxParamsPerFragment, paramSize);
1001
+ totalParamCount += paramSize;
1002
+ }
1003
+ let chunkedParams = [[]];
1004
+ for (const fragment of pairFragmentsWithParams(fragments, params)) {
1005
+ switch (fragment.type) {
1006
+ case "parameter": {
1007
+ for (const params2 of chunkedParams) {
1008
+ params2.push(fragment.value);
1009
+ }
1010
+ break;
1011
+ }
1012
+ case "stringChunk": {
1013
+ break;
1014
+ }
1015
+ case "parameterTuple": {
1016
+ const thisParamCount = fragment.value.length;
1017
+ let chunks = [];
1018
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1019
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1020
+ thisParamCount === maxParamsPerFragment && // Do we need chunking to fit the parameters?
1021
+ totalParamCount > maxChunkSize && // Would chunking enable us to fit the parameters?
1022
+ totalParamCount - thisParamCount < maxChunkSize) {
1023
+ const availableSize = maxChunkSize - (totalParamCount - thisParamCount);
1024
+ chunks = chunkArray(fragment.value, availableSize);
1025
+ } else {
1026
+ chunks = [fragment.value];
1027
+ }
1028
+ chunkedParams = chunkedParams.flatMap((params2) => chunks.map((chunk) => [...params2, chunk]));
1029
+ break;
1030
+ }
1031
+ case "parameterTupleList": {
1032
+ const thisParamCount = fragment.value.reduce((acc, tuple) => acc + tuple.length, 0);
1033
+ const completeChunks = [];
1034
+ let currentChunk = [];
1035
+ let currentChunkParamCount = 0;
1036
+ for (const tuple of fragment.value) {
1037
+ if (maxChunkSize && // Have we split the parameters into chunks already?
1038
+ chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
1039
+ thisParamCount === maxParamsPerFragment && // Is there anything in the current chunk?
1040
+ currentChunk.length > 0 && // Will adding this tuple exceed the max chunk size?
1041
+ totalParamCount - thisParamCount + currentChunkParamCount + tuple.length > maxChunkSize) {
1042
+ completeChunks.push(currentChunk);
1043
+ currentChunk = [];
1044
+ currentChunkParamCount = 0;
1045
+ }
1046
+ currentChunk.push(tuple);
1047
+ currentChunkParamCount += tuple.length;
1048
+ }
1049
+ if (currentChunk.length > 0) {
1050
+ completeChunks.push(currentChunk);
1051
+ }
1052
+ chunkedParams = chunkedParams.flatMap((params2) => completeChunks.map((chunk) => [...params2, chunk]));
1053
+ break;
1054
+ }
1055
+ }
1056
+ }
1057
+ return chunkedParams;
1058
+ }
1059
+ function chunkArray(array, chunkSize) {
1060
+ const result = [];
1061
+ for (let i = 0; i < array.length; i += chunkSize) {
1062
+ result.push(array.slice(i, i + chunkSize));
1063
+ }
1064
+ return result;
1065
+ }
846
1066
 
847
1067
  // src/interpreter/serializeSql.ts
848
1068
  var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
@@ -875,29 +1095,90 @@ function serializeSql(resultSet) {
875
1095
  );
876
1096
  }
877
1097
  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
1098
  return {
896
1099
  columns: resultSet.columnNames,
897
1100
  types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
898
- rows: resultSet.rows.map((row) => row.map((value, index) => mappers[index](value)))
1101
+ rows: resultSet.rows.map(
1102
+ (row) => row.map((value, index) => serializeRawValue(value, resultSet.columnTypes[index]))
1103
+ )
899
1104
  };
900
1105
  }
1106
+ function serializeRawValue(value, type) {
1107
+ if (value === null) {
1108
+ return null;
1109
+ }
1110
+ switch (type) {
1111
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
1112
+ switch (typeof value) {
1113
+ case "number":
1114
+ return Math.trunc(value);
1115
+ case "string":
1116
+ return Math.trunc(Number(value));
1117
+ default:
1118
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32`);
1119
+ }
1120
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int32Array:
1121
+ if (!Array.isArray(value)) {
1122
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int32Array`);
1123
+ }
1124
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int32));
1125
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int64:
1126
+ switch (typeof value) {
1127
+ case "number":
1128
+ return BigInt(Math.trunc(value));
1129
+ case "string":
1130
+ return value;
1131
+ default:
1132
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64`);
1133
+ }
1134
+ case import_driver_adapter_utils2.ColumnTypeEnum.Int64Array:
1135
+ if (!Array.isArray(value)) {
1136
+ throw new Error(`Cannot serialize value of type ${typeof value} as Int64Array`);
1137
+ }
1138
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int64));
1139
+ case import_driver_adapter_utils2.ColumnTypeEnum.Json:
1140
+ switch (typeof value) {
1141
+ case "string":
1142
+ return JSON.parse(value);
1143
+ default:
1144
+ throw new Error(`Cannot serialize value of type ${typeof value} as Json`);
1145
+ }
1146
+ case import_driver_adapter_utils2.ColumnTypeEnum.JsonArray:
1147
+ if (!Array.isArray(value)) {
1148
+ throw new Error(`Cannot serialize value of type ${typeof value} as JsonArray`);
1149
+ }
1150
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Json));
1151
+ case import_driver_adapter_utils2.ColumnTypeEnum.Bytes:
1152
+ if (Array.isArray(value)) {
1153
+ return new Uint8Array(value);
1154
+ } else {
1155
+ throw new Error(`Cannot serialize value of type ${typeof value} as Bytes`);
1156
+ }
1157
+ case import_driver_adapter_utils2.ColumnTypeEnum.BytesArray:
1158
+ if (!Array.isArray(value)) {
1159
+ throw new Error(`Cannot serialize value of type ${typeof value} as BytesArray`);
1160
+ }
1161
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Bytes));
1162
+ case import_driver_adapter_utils2.ColumnTypeEnum.Boolean:
1163
+ switch (typeof value) {
1164
+ case "boolean":
1165
+ return value;
1166
+ case "string":
1167
+ return value === "true" || value === "1";
1168
+ case "number":
1169
+ return value === 1;
1170
+ default:
1171
+ throw new Error(`Cannot serialize value of type ${typeof value} as Boolean`);
1172
+ }
1173
+ case import_driver_adapter_utils2.ColumnTypeEnum.BooleanArray:
1174
+ if (!Array.isArray(value)) {
1175
+ throw new Error(`Cannot serialize value of type ${typeof value} as BooleanArray`);
1176
+ }
1177
+ return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Boolean));
1178
+ default:
1179
+ return value;
1180
+ }
1181
+ }
901
1182
  function serializeColumnType(columnType) {
902
1183
  switch (columnType) {
903
1184
  case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
@@ -1052,6 +1333,7 @@ var QueryInterpreter = class _QueryInterpreter {
1052
1333
  #serializer;
1053
1334
  #rawSerializer;
1054
1335
  #provider;
1336
+ #connectioInfo;
1055
1337
  constructor({
1056
1338
  transactionManager,
1057
1339
  placeholderValues,
@@ -1059,7 +1341,8 @@ var QueryInterpreter = class _QueryInterpreter {
1059
1341
  tracingHelper,
1060
1342
  serializer,
1061
1343
  rawSerializer,
1062
- provider
1344
+ provider,
1345
+ connectionInfo
1063
1346
  }) {
1064
1347
  this.#transactionManager = transactionManager;
1065
1348
  this.#placeholderValues = placeholderValues;
@@ -1068,6 +1351,7 @@ var QueryInterpreter = class _QueryInterpreter {
1068
1351
  this.#serializer = serializer;
1069
1352
  this.#rawSerializer = rawSerializer ?? serializer;
1070
1353
  this.#provider = provider;
1354
+ this.#connectioInfo = connectionInfo;
1071
1355
  }
1072
1356
  static forSql(options) {
1073
1357
  return new _QueryInterpreter({
@@ -1077,7 +1361,8 @@ var QueryInterpreter = class _QueryInterpreter {
1077
1361
  tracingHelper: options.tracingHelper,
1078
1362
  serializer: serializeSql,
1079
1363
  rawSerializer: serializeRawSql,
1080
- provider: options.provider
1364
+ provider: options.provider,
1365
+ connectionInfo: options.connectionInfo
1081
1366
  });
1082
1367
  }
1083
1368
  async run(queryPlan, queryable) {
@@ -1138,21 +1423,41 @@ var QueryInterpreter = class _QueryInterpreter {
1138
1423
  };
1139
1424
  }
1140
1425
  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
- });
1426
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1427
+ let sum = 0;
1428
+ for (const query of queries) {
1429
+ sum += await this.#withQuerySpanAndEvent(
1430
+ query,
1431
+ queryable,
1432
+ () => queryable.executeRaw(query).catch(
1433
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1434
+ )
1435
+ );
1436
+ }
1437
+ return { value: sum };
1145
1438
  }
1146
1439
  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 };
1440
+ const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
1441
+ let results;
1442
+ for (const query of queries) {
1443
+ const result = await this.#withQuerySpanAndEvent(
1444
+ query,
1445
+ queryable,
1446
+ () => queryable.queryRaw(query).catch(
1447
+ (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
1448
+ )
1449
+ );
1450
+ if (results === void 0) {
1451
+ results = result;
1152
1452
  } else {
1153
- return { value: this.#serializer(result), lastInsertId: result.lastInsertId };
1453
+ results.rows.push(...result.rows);
1454
+ results.lastInsertId = result.lastInsertId;
1154
1455
  }
1155
- });
1456
+ }
1457
+ return {
1458
+ value: node.args.type === "rawSql" ? this.#rawSerializer(results) : this.#serializer(results),
1459
+ lastInsertId: results?.lastInsertId
1460
+ };
1156
1461
  }
1157
1462
  case "reverse": {
1158
1463
  const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
@@ -1231,43 +1536,12 @@ var QueryInterpreter = class _QueryInterpreter {
1231
1536
  case "diff": {
1232
1537
  const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
1233
1538
  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)) };
1539
+ const toSet = new Set(asList(to).map((item) => JSON.stringify(item)));
1540
+ return { value: asList(from).filter((item) => !toSet.has(JSON.stringify(item))) };
1236
1541
  }
1237
- case "distinctBy": {
1542
+ case "process": {
1238
1543
  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 };
1249
- }
1250
- case "paginate": {
1251
- 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 };
1544
+ return { value: processRecords(value, node.args.operations), lastInsertId };
1271
1545
  }
1272
1546
  case "initializeRecord": {
1273
1547
  const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
@@ -1289,6 +1563,34 @@ var QueryInterpreter = class _QueryInterpreter {
1289
1563
  assertNever(node, `Unexpected node type: ${node.type}`);
1290
1564
  }
1291
1565
  }
1566
+ #maxChunkSize() {
1567
+ if (this.#connectioInfo?.maxBindValues !== void 0) {
1568
+ return this.#connectioInfo.maxBindValues;
1569
+ }
1570
+ return this.#providerMaxChunkSize();
1571
+ }
1572
+ #providerMaxChunkSize() {
1573
+ if (this.#provider === void 0) {
1574
+ return void 0;
1575
+ }
1576
+ switch (this.#provider) {
1577
+ case "cockroachdb":
1578
+ case "postgres":
1579
+ case "postgresql":
1580
+ case "prisma+postgres":
1581
+ return 32766;
1582
+ case "mysql":
1583
+ return 65535;
1584
+ case "sqlite":
1585
+ return 999;
1586
+ case "sqlserver":
1587
+ return 2098;
1588
+ case "mongodb":
1589
+ return void 0;
1590
+ default:
1591
+ assertNever(this.#provider, `Unexpected provider: ${this.#provider}`);
1592
+ }
1593
+ }
1292
1594
  #withQuerySpanAndEvent(query, queryable, execute) {
1293
1595
  return withQuerySpanAndEvent({
1294
1596
  query,
@@ -1366,18 +1668,6 @@ function attachChildrenToParents(parentRecords, children) {
1366
1668
  }
1367
1669
  return parentRecords;
1368
1670
  }
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
1671
  function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
1382
1672
  switch (initializer.type) {
1383
1673
  case "value":
@@ -1458,6 +1748,35 @@ function mapObjectValues(object, mapper) {
1458
1748
  return result;
1459
1749
  }
1460
1750
 
1751
+ // src/raw-json-protocol.ts
1752
+ var import_decimal4 = __toESM(require("decimal.js"));
1753
+ function normalizeRawJsonProtocolResponse(response) {
1754
+ for (let i = 0; i < response.rows.length; i++) {
1755
+ const row = response.rows[i];
1756
+ for (let j = 0; j < row.length; j++) {
1757
+ row[j] = normalizeValue(response.types[j], row[j]);
1758
+ }
1759
+ }
1760
+ return response;
1761
+ }
1762
+ function normalizeValue(type, value) {
1763
+ if (value === null) {
1764
+ return value;
1765
+ }
1766
+ switch (type) {
1767
+ case "bigint":
1768
+ return String(BigInt(value));
1769
+ case "decimal":
1770
+ return String(new import_decimal4.default(value));
1771
+ case "bigint-array":
1772
+ return value.map((v) => normalizeValue("bigint", v));
1773
+ case "decimal-array":
1774
+ return value.map((v) => normalizeValue("decimal", v));
1775
+ default:
1776
+ return value;
1777
+ }
1778
+ }
1779
+
1461
1780
  // src/transactionManager/TransactionManager.ts
1462
1781
  var import_debug = require("@prisma/debug");
1463
1782
 
@@ -1734,5 +2053,6 @@ var TransactionManager = class {
1734
2053
  isPrismaValuePlaceholder,
1735
2054
  noopTracingHelper,
1736
2055
  normalizeJsonProtocolValues,
2056
+ normalizeRawJsonProtocolResponse,
1737
2057
  safeJsonStringify
1738
2058
  });