prisma-sql 1.66.1 → 1.68.0

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
@@ -3,7 +3,6 @@ import { convertDMMFToModels, isDynamicParameter, extractDynamicName } from '@de
3
3
  var __defProp = Object.defineProperty;
4
4
  var __defProps = Object.defineProperties;
5
5
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
6
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
8
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -23,13 +22,6 @@ var __spreadValues = (a, b) => {
23
22
  return a;
24
23
  };
25
24
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
- var __esm = (fn, res) => function __init() {
27
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
28
- };
29
- var __export = (target, all) => {
30
- for (var name in all)
31
- __defProp(target, name, { get: all[name], enumerable: true });
32
- };
33
25
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
34
26
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
35
27
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
@@ -64,6 +56,7 @@ var __async = (__this, __arguments, generator) => {
64
56
  };
65
57
 
66
58
  // src/utils/normalize-value.ts
59
+ var MAX_DEPTH = 20;
67
60
  function normalizeValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
68
61
  if (depth > MAX_DEPTH) {
69
62
  throw new Error(`Max normalization depth exceeded (${MAX_DEPTH} levels)`);
@@ -117,14 +110,9 @@ function normalizeObjectValue(value, seen, depth) {
117
110
  seen.delete(obj);
118
111
  return out;
119
112
  }
120
- var MAX_DEPTH;
121
- var init_normalize_value = __esm({
122
- "src/utils/normalize-value.ts"() {
123
- MAX_DEPTH = 20;
124
- }
125
- });
126
113
 
127
114
  // src/sql-builder-dialect.ts
115
+ var globalDialect = "postgres";
128
116
  function setGlobalDialect(dialect) {
129
117
  if (dialect !== "postgres" && dialect !== "sqlite") {
130
118
  throw new Error(
@@ -303,175 +291,164 @@ function prepareArrayParam(value, dialect) {
303
291
  }
304
292
  return JSON.stringify(value.map((v) => normalizeValue(v)));
305
293
  }
306
- var globalDialect;
307
- var init_sql_builder_dialect = __esm({
308
- "src/sql-builder-dialect.ts"() {
309
- init_normalize_value();
310
- globalDialect = "postgres";
311
- }
312
- });
313
294
 
314
295
  // src/builder/shared/constants.ts
315
- var IS_PRODUCTION, SQL_SEPARATORS, ALIAS_FORBIDDEN_KEYWORDS, SQL_KEYWORDS, SQL_RESERVED_WORDS, DEFAULT_WHERE_CLAUSE, SPECIAL_FIELDS, SQL_TEMPLATES, SCHEMA_PREFIXES, Ops, LogicalOps, RelationFilters, Modes, Wildcards, REGEX_CACHE, LIMITS, AGGREGATE_PREFIXES;
316
- var init_constants = __esm({
317
- "src/builder/shared/constants.ts"() {
318
- IS_PRODUCTION = process.env.NODE_ENV === "production";
319
- SQL_SEPARATORS = Object.freeze({
320
- FIELD_LIST: ", ",
321
- CONDITION_AND: " AND ",
322
- CONDITION_OR: " OR ",
323
- ORDER_BY: ", "
324
- });
325
- ALIAS_FORBIDDEN_KEYWORDS = /* @__PURE__ */ new Set([
326
- "select",
327
- "from",
328
- "where",
329
- "having",
330
- "order",
331
- "group",
332
- "limit",
333
- "offset",
334
- "join",
335
- "inner",
336
- "left",
337
- "right",
338
- "outer",
339
- "cross",
340
- "full",
341
- "and",
342
- "or",
343
- "not",
344
- "by",
345
- "as",
346
- "on",
347
- "union",
348
- "intersect",
349
- "except",
350
- "case",
351
- "when",
352
- "then",
353
- "else",
354
- "end"
355
- ]);
356
- SQL_KEYWORDS = /* @__PURE__ */ new Set([
357
- ...ALIAS_FORBIDDEN_KEYWORDS,
358
- "user",
359
- "users",
360
- "table",
361
- "column",
362
- "index",
363
- "values",
364
- "in",
365
- "like",
366
- "between",
367
- "is",
368
- "exists",
369
- "null",
370
- "true",
371
- "false",
372
- "all",
373
- "any",
374
- "some",
375
- "update",
376
- "insert",
377
- "delete",
378
- "create",
379
- "drop",
380
- "alter",
381
- "truncate",
382
- "grant",
383
- "revoke",
384
- "exec",
385
- "execute"
386
- ]);
387
- SQL_RESERVED_WORDS = SQL_KEYWORDS;
388
- DEFAULT_WHERE_CLAUSE = "1=1";
389
- SPECIAL_FIELDS = Object.freeze({
390
- ID: "id"
391
- });
392
- SQL_TEMPLATES = Object.freeze({
393
- PUBLIC_SCHEMA: "public",
394
- WHERE: "WHERE",
395
- SELECT: "SELECT",
396
- FROM: "FROM",
397
- ORDER_BY: "ORDER BY",
398
- GROUP_BY: "GROUP BY",
399
- HAVING: "HAVING",
400
- LIMIT: "LIMIT",
401
- OFFSET: "OFFSET",
402
- COUNT_ALL: "COUNT(*)",
403
- AS: "AS",
404
- DISTINCT_ON: "DISTINCT ON",
405
- IS_NULL: "IS NULL",
406
- IS_NOT_NULL: "IS NOT NULL",
407
- LIKE: "LIKE",
408
- AND: "AND",
409
- OR: "OR",
410
- NOT: "NOT"
411
- });
412
- SCHEMA_PREFIXES = Object.freeze({
413
- INTERNAL: "@",
414
- COMMENT: "//"
415
- });
416
- Ops = Object.freeze({
417
- EQUALS: "equals",
418
- NOT: "not",
419
- GT: "gt",
420
- GTE: "gte",
421
- LT: "lt",
422
- LTE: "lte",
423
- IN: "in",
424
- NOT_IN: "notIn",
425
- CONTAINS: "contains",
426
- STARTS_WITH: "startsWith",
427
- ENDS_WITH: "endsWith",
428
- HAS: "has",
429
- HAS_SOME: "hasSome",
430
- HAS_EVERY: "hasEvery",
431
- IS_EMPTY: "isEmpty",
432
- PATH: "path",
433
- STRING_CONTAINS: "string_contains",
434
- STRING_STARTS_WITH: "string_starts_with",
435
- STRING_ENDS_WITH: "string_ends_with"
436
- });
437
- LogicalOps = Object.freeze({
438
- AND: "AND",
439
- OR: "OR",
440
- NOT: "NOT"
441
- });
442
- RelationFilters = Object.freeze({
443
- SOME: "some",
444
- EVERY: "every",
445
- NONE: "none"
446
- });
447
- Modes = Object.freeze({
448
- INSENSITIVE: "insensitive",
449
- DEFAULT: "default"
450
- });
451
- Wildcards = Object.freeze({
452
- [Ops.CONTAINS]: (v) => `%${v}%`,
453
- [Ops.STARTS_WITH]: (v) => `${v}%`,
454
- [Ops.ENDS_WITH]: (v) => `%${v}`
455
- });
456
- REGEX_CACHE = {
457
- PARAM_PLACEHOLDER: /\$(\d+)/g,
458
- VALID_IDENTIFIER: /^[a-z_][a-z0-9_]*$/
459
- };
460
- LIMITS = Object.freeze({
461
- MAX_QUERY_DEPTH: 50,
462
- MAX_ARRAY_SIZE: 1e4,
463
- MAX_STRING_LENGTH: 1e4,
464
- MAX_HAVING_DEPTH: 50
465
- });
466
- AGGREGATE_PREFIXES = /* @__PURE__ */ new Set([
467
- "_count",
468
- "_sum",
469
- "_avg",
470
- "_min",
471
- "_max"
472
- ]);
473
- }
296
+ var IS_PRODUCTION = process.env.NODE_ENV === "production";
297
+ var SQL_SEPARATORS = Object.freeze({
298
+ FIELD_LIST: ", ",
299
+ CONDITION_AND: " AND ",
300
+ CONDITION_OR: " OR ",
301
+ ORDER_BY: ", "
302
+ });
303
+ var ALIAS_FORBIDDEN_KEYWORDS = /* @__PURE__ */ new Set([
304
+ "select",
305
+ "from",
306
+ "where",
307
+ "having",
308
+ "order",
309
+ "group",
310
+ "limit",
311
+ "offset",
312
+ "join",
313
+ "inner",
314
+ "left",
315
+ "right",
316
+ "outer",
317
+ "cross",
318
+ "full",
319
+ "and",
320
+ "or",
321
+ "not",
322
+ "by",
323
+ "as",
324
+ "on",
325
+ "union",
326
+ "intersect",
327
+ "except",
328
+ "case",
329
+ "when",
330
+ "then",
331
+ "else",
332
+ "end"
333
+ ]);
334
+ var SQL_KEYWORDS = /* @__PURE__ */ new Set([
335
+ ...ALIAS_FORBIDDEN_KEYWORDS,
336
+ "user",
337
+ "users",
338
+ "table",
339
+ "column",
340
+ "index",
341
+ "values",
342
+ "in",
343
+ "like",
344
+ "between",
345
+ "is",
346
+ "exists",
347
+ "null",
348
+ "true",
349
+ "false",
350
+ "all",
351
+ "any",
352
+ "some",
353
+ "update",
354
+ "insert",
355
+ "delete",
356
+ "create",
357
+ "drop",
358
+ "alter",
359
+ "truncate",
360
+ "grant",
361
+ "revoke",
362
+ "exec",
363
+ "execute"
364
+ ]);
365
+ var SQL_RESERVED_WORDS = SQL_KEYWORDS;
366
+ var DEFAULT_WHERE_CLAUSE = "1=1";
367
+ var SPECIAL_FIELDS = Object.freeze({
368
+ ID: "id"
369
+ });
370
+ var SQL_TEMPLATES = Object.freeze({
371
+ PUBLIC_SCHEMA: "public",
372
+ WHERE: "WHERE",
373
+ SELECT: "SELECT",
374
+ FROM: "FROM",
375
+ ORDER_BY: "ORDER BY",
376
+ GROUP_BY: "GROUP BY",
377
+ HAVING: "HAVING",
378
+ LIMIT: "LIMIT",
379
+ OFFSET: "OFFSET",
380
+ COUNT_ALL: "COUNT(*)",
381
+ AS: "AS",
382
+ DISTINCT_ON: "DISTINCT ON",
383
+ IS_NULL: "IS NULL",
384
+ IS_NOT_NULL: "IS NOT NULL",
385
+ LIKE: "LIKE",
386
+ AND: "AND",
387
+ OR: "OR",
388
+ NOT: "NOT"
389
+ });
390
+ var SCHEMA_PREFIXES = Object.freeze({
391
+ INTERNAL: "@",
392
+ COMMENT: "//"
393
+ });
394
+ var Ops = Object.freeze({
395
+ EQUALS: "equals",
396
+ NOT: "not",
397
+ GT: "gt",
398
+ GTE: "gte",
399
+ LT: "lt",
400
+ LTE: "lte",
401
+ IN: "in",
402
+ NOT_IN: "notIn",
403
+ CONTAINS: "contains",
404
+ STARTS_WITH: "startsWith",
405
+ ENDS_WITH: "endsWith",
406
+ HAS: "has",
407
+ HAS_SOME: "hasSome",
408
+ HAS_EVERY: "hasEvery",
409
+ IS_EMPTY: "isEmpty",
410
+ PATH: "path",
411
+ STRING_CONTAINS: "string_contains",
412
+ STRING_STARTS_WITH: "string_starts_with",
413
+ STRING_ENDS_WITH: "string_ends_with"
414
+ });
415
+ var LogicalOps = Object.freeze({
416
+ AND: "AND",
417
+ OR: "OR",
418
+ NOT: "NOT"
419
+ });
420
+ var RelationFilters = Object.freeze({
421
+ SOME: "some",
422
+ EVERY: "every",
423
+ NONE: "none"
474
424
  });
425
+ var Modes = Object.freeze({
426
+ INSENSITIVE: "insensitive",
427
+ DEFAULT: "default"
428
+ });
429
+ var Wildcards = Object.freeze({
430
+ [Ops.CONTAINS]: (v) => `%${v}%`,
431
+ [Ops.STARTS_WITH]: (v) => `${v}%`,
432
+ [Ops.ENDS_WITH]: (v) => `%${v}`
433
+ });
434
+ var REGEX_CACHE = {
435
+ VALID_IDENTIFIER: /^[a-z_][a-z0-9_]*$/
436
+ };
437
+ var LIMITS = Object.freeze({
438
+ MAX_QUERY_DEPTH: 50,
439
+ MAX_ARRAY_SIZE: 1e4,
440
+ MAX_STRING_LENGTH: 1e4,
441
+ MAX_HAVING_DEPTH: 50
442
+ });
443
+ var AGGREGATE_PREFIXES = /* @__PURE__ */ new Set([
444
+ "_count",
445
+ "_sum",
446
+ "_avg",
447
+ "_min",
448
+ "_max"
449
+ ]);
450
+ var _a;
451
+ var DEBUG_PARAMS = typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.DEBUG_PARAMS) === "1";
475
452
 
476
453
  // src/builder/shared/validators/type-guards.ts
477
454
  function isNotNullish(value) {
@@ -515,12 +492,16 @@ function hasRequiredKeywords(sql) {
515
492
  const hasFrom = upper.includes("FROM");
516
493
  return hasSelect && hasFrom && upper.indexOf("SELECT") < upper.indexOf("FROM");
517
494
  }
518
- var init_type_guards = __esm({
519
- "src/builder/shared/validators/type-guards.ts"() {
520
- }
521
- });
522
495
 
523
496
  // src/builder/shared/errors.ts
497
+ var SqlBuilderError = class extends Error {
498
+ constructor(message, code, context) {
499
+ super(message);
500
+ this.name = "SqlBuilderError";
501
+ this.code = code;
502
+ this.context = context;
503
+ }
504
+ };
524
505
  function createError(message, ctx, code = "VALIDATION_ERROR") {
525
506
  const parts = [message];
526
507
  if (isNonEmptyArray(ctx.path)) {
@@ -534,20 +515,6 @@ function createError(message, ctx, code = "VALIDATION_ERROR") {
534
515
  }
535
516
  return new SqlBuilderError(parts.join("\n"), code, ctx);
536
517
  }
537
- var SqlBuilderError;
538
- var init_errors = __esm({
539
- "src/builder/shared/errors.ts"() {
540
- init_type_guards();
541
- SqlBuilderError = class extends Error {
542
- constructor(message, code, context) {
543
- super(message);
544
- this.name = "SqlBuilderError";
545
- this.code = code;
546
- this.context = context;
547
- }
548
- };
549
- }
550
- });
551
518
 
552
519
  // src/builder/shared/validators/sql-validators.ts
553
520
  function isValidWhereClause(clause) {
@@ -582,6 +549,7 @@ function parseDollarNumber(sql, start) {
582
549
  if (!hasDigit || num <= 0) return { next: i, num: 0 };
583
550
  return { next: i, num };
584
551
  }
552
+ var MAX_PARAMS = 32767;
585
553
  function scanDollarPlaceholders(sql, markUpTo) {
586
554
  if (markUpTo > MAX_PARAMS) {
587
555
  throw new Error(`Parameter count ${markUpTo} exceeds maximum ${MAX_PARAMS}`);
@@ -688,16 +656,10 @@ function needsQuoting(identifier) {
688
656
  if (SQL_KEYWORDS.has(identifier.toLowerCase())) return true;
689
657
  return false;
690
658
  }
691
- var MAX_PARAMS;
692
- var init_sql_validators = __esm({
693
- "src/builder/shared/validators/sql-validators.ts"() {
694
- init_constants();
695
- init_type_guards();
696
- MAX_PARAMS = 32767;
697
- }
698
- });
699
659
 
700
660
  // src/builder/shared/sql-utils.ts
661
+ var COL_EXPR_CACHE = /* @__PURE__ */ new WeakMap();
662
+ var COL_WITH_ALIAS_CACHE = /* @__PURE__ */ new WeakMap();
701
663
  function containsControlChars(s) {
702
664
  for (let i = 0; i < s.length; i++) {
703
665
  const code = s.charCodeAt(i);
@@ -723,6 +685,7 @@ function isIdentCharCode(c) {
723
685
  function isIdentStartCharCode(c) {
724
686
  return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
725
687
  }
688
+ var MAX_PARSE_ITERATIONS = 1e4;
726
689
  function parseQuotedPart(input, start) {
727
690
  const n = input.length;
728
691
  let i = start + 1;
@@ -1022,25 +985,14 @@ function normalizeKeyList(input) {
1022
985
  const s = String(input).trim();
1023
986
  return s.length > 0 ? [s] : [];
1024
987
  }
1025
- var COL_EXPR_CACHE, COL_WITH_ALIAS_CACHE, MAX_PARSE_ITERATIONS;
1026
- var init_sql_utils = __esm({
1027
- "src/builder/shared/sql-utils.ts"() {
1028
- init_sql_validators();
1029
- init_type_guards();
1030
- init_model_field_cache();
1031
- init_constants();
1032
- COL_EXPR_CACHE = /* @__PURE__ */ new WeakMap();
1033
- COL_WITH_ALIAS_CACHE = /* @__PURE__ */ new WeakMap();
1034
- MAX_PARSE_ITERATIONS = 1e4;
1035
- }
1036
- });
1037
988
 
1038
989
  // src/builder/shared/model-field-cache.ts
990
+ var FIELD_INDICES_CACHE = /* @__PURE__ */ new WeakMap();
1039
991
  function normalizeField(field) {
1040
992
  return field;
1041
993
  }
1042
994
  function getFieldIndices(model) {
1043
- var _a;
995
+ var _a3;
1044
996
  let cached = FIELD_INDICES_CACHE.get(model);
1045
997
  if (cached) return cached;
1046
998
  const scalarFields = /* @__PURE__ */ new Map();
@@ -1059,7 +1011,7 @@ function getFieldIndices(model) {
1059
1011
  } else {
1060
1012
  scalarFields.set(field.name, field);
1061
1013
  scalarNames.push(field.name);
1062
- const fieldType = String((_a = field.type) != null ? _a : "").toLowerCase();
1014
+ const fieldType = String((_a3 = field.type) != null ? _a3 : "").toLowerCase();
1063
1015
  if (fieldType === "json") {
1064
1016
  jsonFields.add(field.name);
1065
1017
  }
@@ -1124,13 +1076,6 @@ function maybeParseJson(value, jsonSet, fieldName) {
1124
1076
  return value;
1125
1077
  }
1126
1078
  }
1127
- var FIELD_INDICES_CACHE;
1128
- var init_model_field_cache = __esm({
1129
- "src/builder/shared/model-field-cache.ts"() {
1130
- init_sql_utils();
1131
- FIELD_INDICES_CACHE = /* @__PURE__ */ new WeakMap();
1132
- }
1133
- });
1134
1079
 
1135
1080
  // src/builder/joins.ts
1136
1081
  function isRelationField(fieldName, model) {
@@ -1189,23 +1134,14 @@ function joinCondition(field, parentModel, childModel, parentAlias, childAlias)
1189
1134
  function getModelByName(schemas, name) {
1190
1135
  return schemas.find((m) => m.name === name);
1191
1136
  }
1192
- var init_joins = __esm({
1193
- "src/builder/joins.ts"() {
1194
- init_constants();
1195
- init_errors();
1196
- init_model_field_cache();
1197
- init_sql_utils();
1198
- init_type_guards();
1199
- }
1200
- });
1201
1137
  function normalizeIntLike(name, v, opts = {}) {
1202
- var _a, _b;
1138
+ var _a3, _b;
1203
1139
  if (!isNotNullish(v)) return void 0;
1204
1140
  if (isDynamicParameter(v)) return v;
1205
1141
  if (typeof v !== "number" || !Number.isFinite(v) || !Number.isInteger(v)) {
1206
1142
  throw new Error(`${name} must be an integer`);
1207
1143
  }
1208
- const min = (_a = opts.min) != null ? _a : 0;
1144
+ const min = (_a3 = opts.min) != null ? _a3 : 0;
1209
1145
  const allowZero = (_b = opts.allowZero) != null ? _b : true;
1210
1146
  if (!allowZero && v === 0) {
1211
1147
  throw new Error(`${name} must be > 0`);
@@ -1218,11 +1154,6 @@ function normalizeIntLike(name, v, opts = {}) {
1218
1154
  }
1219
1155
  return v;
1220
1156
  }
1221
- var init_int_like = __esm({
1222
- "src/builder/shared/int-like.ts"() {
1223
- init_type_guards();
1224
- }
1225
- });
1226
1157
  function scopeName(scope, dynamicName) {
1227
1158
  const s = String(scope).trim();
1228
1159
  const dn = String(dynamicName).trim();
@@ -1232,16 +1163,79 @@ function scopeName(scope, dynamicName) {
1232
1163
  function addAutoScoped(params, value, scope) {
1233
1164
  if (isDynamicParameter(value)) {
1234
1165
  const dn = extractDynamicName(value);
1166
+ if (DEBUG_PARAMS) {
1167
+ console.log(`[PARAM] ${scope} = ${JSON.stringify(value)}`);
1168
+ }
1235
1169
  return params.add(void 0, scopeName(scope, dn));
1236
1170
  }
1237
1171
  return params.add(value);
1238
1172
  }
1239
- var init_dynamic_params = __esm({
1240
- "src/builder/shared/dynamic-params.ts"() {
1241
- }
1242
- });
1243
1173
 
1244
1174
  // src/builder/shared/order-by-utils.ts
1175
+ var flipNulls = (v) => {
1176
+ const s = String(v).toLowerCase();
1177
+ if (s === "first") return "last";
1178
+ if (s === "last") return "first";
1179
+ return v;
1180
+ };
1181
+ var flipSortString = (v) => {
1182
+ if (typeof v !== "string") return v;
1183
+ const s = v.toLowerCase();
1184
+ if (s === "asc") return "desc";
1185
+ if (s === "desc") return "asc";
1186
+ return v;
1187
+ };
1188
+ var getNextSort = (sortRaw) => {
1189
+ if (typeof sortRaw !== "string") return sortRaw;
1190
+ const s = sortRaw.toLowerCase();
1191
+ if (s === "asc") return "desc";
1192
+ if (s === "desc") return "asc";
1193
+ return sortRaw;
1194
+ };
1195
+ var flipObjectSort = (obj) => {
1196
+ const out = __spreadValues({}, obj);
1197
+ const hasSort = Object.prototype.hasOwnProperty.call(obj, "sort");
1198
+ const hasDirection = Object.prototype.hasOwnProperty.call(obj, "direction");
1199
+ if (hasSort) {
1200
+ out.sort = getNextSort(obj.sort);
1201
+ } else if (hasDirection) {
1202
+ out.direction = getNextSort(obj.direction);
1203
+ } else {
1204
+ out.sort = getNextSort(obj.sort);
1205
+ }
1206
+ if (typeof obj.nulls === "string") {
1207
+ out.nulls = flipNulls(obj.nulls);
1208
+ }
1209
+ return out;
1210
+ };
1211
+ var flipValue = (v) => {
1212
+ if (typeof v === "string") return flipSortString(v);
1213
+ if (isPlainObject(v)) return flipObjectSort(v);
1214
+ return v;
1215
+ };
1216
+ var assertSingleFieldObject = (item) => {
1217
+ if (!isPlainObject(item)) {
1218
+ throw new Error("orderBy array entries must be objects");
1219
+ }
1220
+ const entries = Object.entries(item);
1221
+ if (entries.length !== 1) {
1222
+ throw new Error("orderBy array entries must have exactly one field");
1223
+ }
1224
+ return entries[0];
1225
+ };
1226
+ var flipOrderByArray = (orderBy) => {
1227
+ return orderBy.map((item) => {
1228
+ const [k, v] = assertSingleFieldObject(item);
1229
+ return { [k]: flipValue(v) };
1230
+ });
1231
+ };
1232
+ var flipOrderByObject = (orderBy) => {
1233
+ const out = {};
1234
+ for (const [k, v] of Object.entries(orderBy)) {
1235
+ out[k] = flipValue(v);
1236
+ }
1237
+ return out;
1238
+ };
1245
1239
  function reverseOrderByInput(orderBy) {
1246
1240
  if (!isNotNullish(orderBy)) return orderBy;
1247
1241
  if (Array.isArray(orderBy)) {
@@ -1252,6 +1246,14 @@ function reverseOrderByInput(orderBy) {
1252
1246
  }
1253
1247
  throw new Error("orderBy must be an object or array of objects");
1254
1248
  }
1249
+ var normalizePairs = (pairs, parseValue) => {
1250
+ return pairs.map(([field, rawValue]) => {
1251
+ const parsed = parseValue(rawValue, field);
1252
+ return {
1253
+ [field]: parsed.nulls !== void 0 ? { direction: parsed.direction, nulls: parsed.nulls } : parsed.direction
1254
+ };
1255
+ });
1256
+ };
1255
1257
  function normalizeOrderByInput(orderBy, parseValue) {
1256
1258
  if (!isNotNullish(orderBy)) return [];
1257
1259
  if (Array.isArray(orderBy)) {
@@ -1287,85 +1289,6 @@ function normalizeAndValidateOrderBy(orderBy, model, parseValue) {
1287
1289
  }
1288
1290
  return entries;
1289
1291
  }
1290
- var flipNulls, flipSortString, getNextSort, flipObjectSort, flipValue, assertSingleFieldObject, flipOrderByArray, flipOrderByObject, normalizePairs;
1291
- var init_order_by_utils = __esm({
1292
- "src/builder/shared/order-by-utils.ts"() {
1293
- init_type_guards();
1294
- init_model_field_cache();
1295
- flipNulls = (v) => {
1296
- const s = String(v).toLowerCase();
1297
- if (s === "first") return "last";
1298
- if (s === "last") return "first";
1299
- return v;
1300
- };
1301
- flipSortString = (v) => {
1302
- if (typeof v !== "string") return v;
1303
- const s = v.toLowerCase();
1304
- if (s === "asc") return "desc";
1305
- if (s === "desc") return "asc";
1306
- return v;
1307
- };
1308
- getNextSort = (sortRaw) => {
1309
- if (typeof sortRaw !== "string") return sortRaw;
1310
- const s = sortRaw.toLowerCase();
1311
- if (s === "asc") return "desc";
1312
- if (s === "desc") return "asc";
1313
- return sortRaw;
1314
- };
1315
- flipObjectSort = (obj) => {
1316
- const out = __spreadValues({}, obj);
1317
- const hasSort = Object.prototype.hasOwnProperty.call(obj, "sort");
1318
- const hasDirection = Object.prototype.hasOwnProperty.call(obj, "direction");
1319
- if (hasSort) {
1320
- out.sort = getNextSort(obj.sort);
1321
- } else if (hasDirection) {
1322
- out.direction = getNextSort(obj.direction);
1323
- } else {
1324
- out.sort = getNextSort(obj.sort);
1325
- }
1326
- if (typeof obj.nulls === "string") {
1327
- out.nulls = flipNulls(obj.nulls);
1328
- }
1329
- return out;
1330
- };
1331
- flipValue = (v) => {
1332
- if (typeof v === "string") return flipSortString(v);
1333
- if (isPlainObject(v)) return flipObjectSort(v);
1334
- return v;
1335
- };
1336
- assertSingleFieldObject = (item) => {
1337
- if (!isPlainObject(item)) {
1338
- throw new Error("orderBy array entries must be objects");
1339
- }
1340
- const entries = Object.entries(item);
1341
- if (entries.length !== 1) {
1342
- throw new Error("orderBy array entries must have exactly one field");
1343
- }
1344
- return entries[0];
1345
- };
1346
- flipOrderByArray = (orderBy) => {
1347
- return orderBy.map((item) => {
1348
- const [k, v] = assertSingleFieldObject(item);
1349
- return { [k]: flipValue(v) };
1350
- });
1351
- };
1352
- flipOrderByObject = (orderBy) => {
1353
- const out = {};
1354
- for (const [k, v] of Object.entries(orderBy)) {
1355
- out[k] = flipValue(v);
1356
- }
1357
- return out;
1358
- };
1359
- normalizePairs = (pairs, parseValue) => {
1360
- return pairs.map(([field, rawValue]) => {
1361
- const parsed = parseValue(rawValue, field);
1362
- return {
1363
- [field]: parsed.nulls !== void 0 ? { direction: parsed.direction, nulls: parsed.nulls } : parsed.direction
1364
- };
1365
- });
1366
- };
1367
- }
1368
- });
1369
1292
 
1370
1293
  // src/builder/shared/order-by-determinism.ts
1371
1294
  function findTiebreakerField(model) {
@@ -1398,15 +1321,9 @@ function ensureDeterministicOrderByInput(args) {
1398
1321
  if (hasTiebreaker(orderBy, parseValue, tiebreaker)) return orderBy;
1399
1322
  return addTiebreaker(orderBy, tiebreaker);
1400
1323
  }
1401
- var init_order_by_determinism = __esm({
1402
- "src/builder/shared/order-by-determinism.ts"() {
1403
- init_model_field_cache();
1404
- init_type_guards();
1405
- init_order_by_utils();
1406
- }
1407
- });
1408
1324
 
1409
1325
  // src/builder/shared/primary-key-utils.ts
1326
+ var FIELD_BY_NAME_CACHE = /* @__PURE__ */ new WeakMap();
1410
1327
  function normalizeField2(field) {
1411
1328
  return field;
1412
1329
  }
@@ -1442,13 +1359,6 @@ function getFieldByName(model, fieldName) {
1442
1359
  }
1443
1360
  return cache.get(fieldName);
1444
1361
  }
1445
- var FIELD_BY_NAME_CACHE;
1446
- var init_primary_key_utils = __esm({
1447
- "src/builder/shared/primary-key-utils.ts"() {
1448
- init_model_field_cache();
1449
- FIELD_BY_NAME_CACHE = /* @__PURE__ */ new WeakMap();
1450
- }
1451
- });
1452
1362
 
1453
1363
  // src/builder/shared/validators/field-assertions.ts
1454
1364
  function assertFieldExists(fieldName, model, context, path = []) {
@@ -1496,12 +1406,10 @@ function assertNumericField(model, fieldName, context) {
1496
1406
  }
1497
1407
  return field;
1498
1408
  }
1499
- var init_field_assertions = __esm({
1500
- "src/builder/shared/validators/field-assertions.ts"() {
1501
- init_errors();
1502
- init_primary_key_utils();
1503
- }
1504
- });
1409
+
1410
+ // src/builder/pagination.ts
1411
+ var MAX_LIMIT_OFFSET = 2147483647;
1412
+ var ORDER_BY_ALLOWED_KEYS = /* @__PURE__ */ new Set(["sort", "nulls"]);
1505
1413
  function parseDirectionRaw(raw, errorLabel) {
1506
1414
  const s = String(raw).toLowerCase();
1507
1415
  if (s === "asc" || s === "desc") return s;
@@ -1550,6 +1458,7 @@ function normalizeNonNegativeInt(name, v) {
1550
1458
  throw new Error(`${name} normalization returned undefined`);
1551
1459
  return result;
1552
1460
  }
1461
+ var MIN_NEGATIVE_TAKE = -1e4;
1553
1462
  function normalizeIntAllowNegative(name, v) {
1554
1463
  if (isDynamicParameter(v)) return v;
1555
1464
  const result = normalizeIntLike(name, v, {
@@ -1697,7 +1606,7 @@ function assertCursorAndOrderFieldsScalar(model, cursor, orderEntries) {
1697
1606
  }
1698
1607
  }
1699
1608
  function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect, model) {
1700
- var _a;
1609
+ var _a3;
1701
1610
  assertSafeTableRef(tableName);
1702
1611
  assertSafeAlias(alias);
1703
1612
  const d = dialect != null ? dialect : getGlobalDialect();
@@ -1712,6 +1621,33 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
1712
1621
  }
1713
1622
  if (cursorEntries.length === 0)
1714
1623
  throw new Error("cursor must have at least one field with defined value");
1624
+ const orderEntries = normalizeAndValidateOrderBy(
1625
+ orderBy,
1626
+ model,
1627
+ parseOrderByValue
1628
+ );
1629
+ if (cursorEntries.length === 1 && orderEntries.length === 0) {
1630
+ const [field, value] = cursorEntries[0];
1631
+ const ph = addAutoScoped(params, value, `cursor.${field}`);
1632
+ const c = col(alias, field, model);
1633
+ return {
1634
+ cte: "",
1635
+ condition: `${c} >= ${ph}`
1636
+ };
1637
+ }
1638
+ if (cursorEntries.length === 1 && orderEntries.length === 1) {
1639
+ const [cursorField, cursorValue] = cursorEntries[0];
1640
+ const orderEntry = orderEntries[0];
1641
+ if (orderEntry.field === cursorField) {
1642
+ const ph = addAutoScoped(params, cursorValue, `cursor.${cursorField}`);
1643
+ const c = col(alias, cursorField, model);
1644
+ const op = orderEntry.direction === "asc" ? ">=" : "<=";
1645
+ return {
1646
+ cte: "",
1647
+ condition: `${c} ${op} ${ph}`
1648
+ };
1649
+ }
1650
+ }
1715
1651
  const { cteName, srcAlias } = buildCursorNames(alias);
1716
1652
  assertSafeAlias(cteName);
1717
1653
  assertSafeAlias(srcAlias);
@@ -1720,49 +1656,52 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
1720
1656
  model,
1721
1657
  parseValue: parseOrderByValue
1722
1658
  });
1723
- let orderEntries = normalizeAndValidateOrderBy(
1659
+ let finalOrderEntries = normalizeAndValidateOrderBy(
1724
1660
  orderBy,
1725
1661
  model,
1726
1662
  parseOrderByValue
1727
1663
  );
1728
- if (orderEntries.length === 0) {
1729
- orderEntries = cursorEntries.map(([field]) => ({
1664
+ if (finalOrderEntries.length === 0) {
1665
+ finalOrderEntries = cursorEntries.map(([field]) => ({
1730
1666
  field,
1731
1667
  direction: "asc"
1732
1668
  }));
1733
1669
  } else {
1734
- orderEntries = ensureCursorFieldsInOrder(orderEntries, cursorEntries);
1670
+ finalOrderEntries = ensureCursorFieldsInOrder(
1671
+ finalOrderEntries,
1672
+ cursorEntries
1673
+ );
1735
1674
  }
1736
- assertCursorAndOrderFieldsScalar(model, cursor, orderEntries);
1675
+ assertCursorAndOrderFieldsScalar(model, cursor, finalOrderEntries);
1737
1676
  const { whereSql: cursorWhereSql } = buildCursorFilterParts(
1738
1677
  cursor,
1739
1678
  srcAlias,
1740
1679
  params,
1741
1680
  model
1742
1681
  );
1743
- const cursorOrderBy = orderEntries.map(
1682
+ const cursorOrderBy = finalOrderEntries.map(
1744
1683
  (e) => srcAlias + "." + quoteColumn(model, e.field) + " " + e.direction.toUpperCase()
1745
1684
  ).join(", ");
1746
1685
  const selectList = buildCursorCteSelectList(
1747
1686
  cursorEntries,
1748
- orderEntries,
1687
+ finalOrderEntries,
1749
1688
  model
1750
1689
  );
1751
1690
  const cte = cteName + " AS (\n SELECT " + selectList + " FROM " + tableName + " " + srcAlias + "\n WHERE " + cursorWhereSql + "\n ORDER BY " + cursorOrderBy + "\n LIMIT 1\n )";
1752
1691
  const existsExpr = "EXISTS (SELECT 1 FROM " + cteName + ")";
1753
1692
  const orClauses = [];
1754
- for (let level = 0; level < orderEntries.length; level++) {
1693
+ for (let level = 0; level < finalOrderEntries.length; level++) {
1755
1694
  const andParts = [];
1756
1695
  for (let i = 0; i < level; i++) {
1757
- const e2 = orderEntries[i];
1696
+ const e2 = finalOrderEntries[i];
1758
1697
  const c2 = col(alias, e2.field, model);
1759
1698
  const cursorField2 = cteName + "." + quoteColumn(model, e2.field);
1760
1699
  andParts.push(buildCursorEqualityExpr(c2, cursorField2));
1761
1700
  }
1762
- const e = orderEntries[level];
1701
+ const e = finalOrderEntries[level];
1763
1702
  const c = col(alias, e.field, model);
1764
1703
  const cursorField = cteName + "." + quoteColumn(model, e.field);
1765
- const nulls = (_a = e.nulls) != null ? _a : defaultNullsFor(d, e.direction);
1704
+ const nulls = (_a3 = e.nulls) != null ? _a3 : defaultNullsFor(d, e.direction);
1766
1705
  andParts.push(buildCursorInequalityExpr(c, e.direction, nulls, cursorField));
1767
1706
  orClauses.push("(" + andParts.join(SQL_SEPARATORS.CONDITION_AND) + ")");
1768
1707
  }
@@ -1835,23 +1774,6 @@ function getPaginationParams(method, args) {
1835
1774
  }
1836
1775
  return {};
1837
1776
  }
1838
- var MAX_LIMIT_OFFSET, ORDER_BY_ALLOWED_KEYS, MIN_NEGATIVE_TAKE;
1839
- var init_pagination = __esm({
1840
- "src/builder/pagination.ts"() {
1841
- init_constants();
1842
- init_sql_utils();
1843
- init_sql_builder_dialect();
1844
- init_type_guards();
1845
- init_int_like();
1846
- init_dynamic_params();
1847
- init_order_by_utils();
1848
- init_order_by_determinism();
1849
- init_field_assertions();
1850
- MAX_LIMIT_OFFSET = 2147483647;
1851
- ORDER_BY_ALLOWED_KEYS = /* @__PURE__ */ new Set(["sort", "nulls"]);
1852
- MIN_NEGATIVE_TAKE = -1e4;
1853
- }
1854
- });
1855
1777
 
1856
1778
  // src/builder/shared/null-comparison.ts
1857
1779
  function buildNullComparison(expr, op, allowNull = false) {
@@ -1869,12 +1791,6 @@ function tryBuildNullComparison(expr, op, val, context) {
1869
1791
  }
1870
1792
  return clause;
1871
1793
  }
1872
- var init_null_comparison = __esm({
1873
- "src/builder/shared/null-comparison.ts"() {
1874
- init_constants();
1875
- init_errors();
1876
- }
1877
- });
1878
1794
  function buildInCondition(expr, op, val, params, dialect, context) {
1879
1795
  if (isDynamicParameter(val)) {
1880
1796
  const ph2 = params.addAuto(val);
@@ -1898,12 +1814,9 @@ function buildInCondition(expr, op, val, params, dialect, context) {
1898
1814
  const ph = params.add(paramValue);
1899
1815
  return op === "in" ? inArray(expr, ph, dialect) : notInArray(expr, ph, dialect);
1900
1816
  }
1901
- var init_in_operator_builder = __esm({
1902
- "src/builder/shared/in-operator-builder.ts"() {
1903
- init_sql_builder_dialect();
1904
- init_errors();
1905
- }
1906
- });
1817
+
1818
+ // src/builder/where/operators-scalar.ts
1819
+ var MAX_NOT_DEPTH = 50;
1907
1820
  function buildNotComposite(expr, val, params, dialect, buildOp, separator) {
1908
1821
  const entries = Object.entries(val).filter(
1909
1822
  ([k, v]) => k !== "mode" && v !== void 0
@@ -2079,18 +1992,6 @@ function handleComparisonOperator(expr, op, val, params) {
2079
1992
  const placeholder = params.addAuto(val);
2080
1993
  return `${expr} ${sqlOp} ${placeholder}`;
2081
1994
  }
2082
- var MAX_NOT_DEPTH;
2083
- var init_operators_scalar = __esm({
2084
- "src/builder/where/operators-scalar.ts"() {
2085
- init_sql_builder_dialect();
2086
- init_constants();
2087
- init_errors();
2088
- init_type_guards();
2089
- init_null_comparison();
2090
- init_in_operator_builder();
2091
- MAX_NOT_DEPTH = 50;
2092
- }
2093
- });
2094
1995
  function buildArrayParam(val, params, dialect) {
2095
1996
  if (isDynamicParameter(val)) {
2096
1997
  return params.addAuto(val);
@@ -2222,17 +2123,11 @@ function handleArrayIsEmpty(expr, val, dialect) {
2222
2123
  }
2223
2124
  return val === true ? arrayIsEmpty(expr, dialect) : arrayIsNotEmpty(expr, dialect);
2224
2125
  }
2225
- var init_operators_array = __esm({
2226
- "src/builder/where/operators-array.ts"() {
2227
- init_sql_builder_dialect();
2228
- init_constants();
2229
- init_errors();
2230
- init_type_guards();
2231
- init_null_comparison();
2232
- }
2233
- });
2234
2126
 
2235
2127
  // src/builder/where/operators-json.ts
2128
+ var SAFE_JSON_PATH_SEGMENT = /^[a-zA-Z_]\w*$/;
2129
+ var MAX_PATH_SEGMENT_LENGTH = 255;
2130
+ var MAX_PATH_SEGMENTS = 100;
2236
2131
  function sanitizeForError(s) {
2237
2132
  let result = "";
2238
2133
  for (let i = 0; i < s.length; i++) {
@@ -2349,20 +2244,19 @@ function handleJsonWildcard(expr, op, val, params, wildcards, dialect) {
2349
2244
  const jsonText = jsonToText(expr, dialect);
2350
2245
  return caseInsensitiveLike(jsonText, placeholder, dialect);
2351
2246
  }
2352
- var SAFE_JSON_PATH_SEGMENT, MAX_PATH_SEGMENT_LENGTH, MAX_PATH_SEGMENTS;
2353
- var init_operators_json = __esm({
2354
- "src/builder/where/operators-json.ts"() {
2355
- init_sql_builder_dialect();
2356
- init_constants();
2357
- init_errors();
2358
- init_type_guards();
2359
- SAFE_JSON_PATH_SEGMENT = /^[a-zA-Z_]\w*$/;
2360
- MAX_PATH_SEGMENT_LENGTH = 255;
2361
- MAX_PATH_SEGMENTS = 100;
2362
- }
2363
- });
2364
2247
 
2365
2248
  // src/builder/where/relations.ts
2249
+ var NO_JOINS = [];
2250
+ var SCHEMA_MAP_CACHE = /* @__PURE__ */ new WeakMap();
2251
+ function getSchemaByName(schemas) {
2252
+ let map = SCHEMA_MAP_CACHE.get(schemas);
2253
+ if (!map) {
2254
+ map = /* @__PURE__ */ new Map();
2255
+ for (const m of schemas) map.set(m.name, m);
2256
+ SCHEMA_MAP_CACHE.set(schemas, map);
2257
+ }
2258
+ return map;
2259
+ }
2366
2260
  function isListRelation(fieldType) {
2367
2261
  return typeof fieldType === "string" && fieldType.endsWith("[]");
2368
2262
  }
@@ -2393,21 +2287,6 @@ function buildToOneNotExistsMatch(relTable, relAlias, join, sub) {
2393
2287
  const joins = sub.joins.length > 0 ? ` ${sub.joins.join(" ")}` : "";
2394
2288
  return `${SQL_TEMPLATES.NOT} EXISTS (${SQL_TEMPLATES.SELECT} 1 ${SQL_TEMPLATES.FROM} ${relTable} ${relAlias}${joins} ${SQL_TEMPLATES.WHERE} ${join} ${SQL_TEMPLATES.AND} ${sub.clause})`;
2395
2289
  }
2396
- function tryOptimizeNoneFilter(noneValue, ctx, relModel, relTable, relAlias, join, sub) {
2397
- const isEmptyFilter = isPlainObject(noneValue) && Object.keys(noneValue).length === 0;
2398
- const canOptimize = !ctx.isSubquery && isEmptyFilter && sub.clause === DEFAULT_WHERE_CLAUSE && sub.joins.length === 0;
2399
- if (!canOptimize) return null;
2400
- const checkField = relModel.fields.find(
2401
- (f) => !f.isRelation && f.isRequired && f.name !== "id"
2402
- ) || relModel.fields.find((f) => !f.isRelation && f.name === "id");
2403
- if (!checkField) return null;
2404
- const leftJoinSql = `LEFT JOIN ${relTable} ${relAlias} ON ${join}`;
2405
- const whereClause = `${relAlias}.${quoteColumn(relModel, checkField.name)} IS NULL`;
2406
- return {
2407
- clause: whereClause,
2408
- joins: [leftJoinSql]
2409
- };
2410
- }
2411
2290
  function processRelationFilter(key, wrap, args) {
2412
2291
  const { value, fieldName, ctx, relAlias, relModel, whereBuilder } = args;
2413
2292
  const raw = value[key];
@@ -2427,7 +2306,6 @@ function buildListRelationFilters(args) {
2427
2306
  fieldName,
2428
2307
  value,
2429
2308
  ctx,
2430
- whereBuilder,
2431
2309
  relModel,
2432
2310
  relTable,
2433
2311
  relAlias,
@@ -2435,23 +2313,17 @@ function buildListRelationFilters(args) {
2435
2313
  } = args;
2436
2314
  const noneValue = value[RelationFilters.NONE];
2437
2315
  if (noneValue !== void 0 && noneValue !== null) {
2438
- const sub = whereBuilder.build(noneValue, __spreadProps(__spreadValues({}, ctx), {
2439
- alias: relAlias,
2440
- model: relModel,
2441
- path: [...ctx.path, fieldName, RelationFilters.NONE],
2442
- isSubquery: true,
2443
- depth: ctx.depth + 1
2444
- }));
2445
- const optimized = tryOptimizeNoneFilter(
2446
- noneValue,
2447
- ctx,
2448
- relModel,
2449
- relTable,
2450
- relAlias,
2451
- join,
2452
- sub
2453
- );
2454
- if (optimized) return optimized;
2316
+ const isEmptyFilter = isPlainObject(noneValue) && Object.keys(noneValue).length === 0;
2317
+ if (isEmptyFilter && !ctx.isSubquery) {
2318
+ const checkField = relModel.fields.find(
2319
+ (f) => !f.isRelation && f.isRequired && f.name !== "id"
2320
+ ) || relModel.fields.find((f) => !f.isRelation && f.name === "id");
2321
+ if (checkField) {
2322
+ const leftJoinSql = `LEFT JOIN ${relTable} ${relAlias} ON ${join}`;
2323
+ const whereClause = `${relAlias}.${quoteColumn(relModel, checkField.name)} IS NULL`;
2324
+ return { clause: whereClause, joins: [leftJoinSql] };
2325
+ }
2326
+ }
2455
2327
  }
2456
2328
  const filters = [
2457
2329
  {
@@ -2584,7 +2456,8 @@ function buildRelation(fieldName, value, ctx, whereBuilder) {
2584
2456
  modelName: ctx.model.name
2585
2457
  });
2586
2458
  }
2587
- const relModel = ctx.schemaModels.find((m) => m.name === field.relatedModel);
2459
+ const schemaMap = getSchemaByName(ctx.schemaModels);
2460
+ const relModel = schemaMap.get(field.relatedModel);
2588
2461
  if (!isNotNullish(relModel)) {
2589
2462
  throw createError(
2590
2463
  `Related model '${field.relatedModel}' not found in schema. Available models: ${ctx.schemaModels.map((m) => m.name).join(", ")}`,
@@ -2623,18 +2496,6 @@ function buildTopLevelRelation(fieldName, value, ctx, whereBuilder) {
2623
2496
  function buildNestedRelation(fieldName, value, ctx, whereBuilder) {
2624
2497
  return buildTopLevelRelation(fieldName, value, ctx, whereBuilder);
2625
2498
  }
2626
- var NO_JOINS;
2627
- var init_relations = __esm({
2628
- "src/builder/where/relations.ts"() {
2629
- init_joins();
2630
- init_constants();
2631
- init_errors();
2632
- init_sql_utils();
2633
- init_type_guards();
2634
- init_primary_key_utils();
2635
- NO_JOINS = [];
2636
- }
2637
- });
2638
2499
 
2639
2500
  // src/builder/shared/array-utils.ts
2640
2501
  function deduplicatePreserveOrder(items) {
@@ -2649,12 +2510,28 @@ function deduplicatePreserveOrder(items) {
2649
2510
  }
2650
2511
  return out;
2651
2512
  }
2652
- var init_array_utils = __esm({
2653
- "src/builder/shared/array-utils.ts"() {
2654
- }
2655
- });
2656
2513
 
2657
2514
  // src/builder/where/builder.ts
2515
+ var MAX_QUERY_DEPTH = 50;
2516
+ var EMPTY_JOINS = [];
2517
+ var JSON_OPS = /* @__PURE__ */ new Set([
2518
+ Ops.PATH,
2519
+ Ops.STRING_CONTAINS,
2520
+ Ops.STRING_STARTS_WITH,
2521
+ Ops.STRING_ENDS_WITH
2522
+ ]);
2523
+ var WhereBuilder = class {
2524
+ build(where, ctx) {
2525
+ if (!isPlainObject(where)) {
2526
+ throw createError("where must be an object", {
2527
+ path: ctx.path,
2528
+ modelName: ctx.model.name
2529
+ });
2530
+ }
2531
+ return buildWhereInternal(where, ctx, this);
2532
+ }
2533
+ };
2534
+ var whereBuilderInstance = new WhereBuilder();
2658
2535
  function createResult(clause, joins = EMPTY_JOINS) {
2659
2536
  return { clause, joins };
2660
2537
  }
@@ -2718,16 +2595,9 @@ function buildWhereInternal(where, ctx, builder) {
2718
2595
  { path: ctx.path, modelName: ctx.model.name }
2719
2596
  );
2720
2597
  }
2721
- if (ctx.seenObjects.has(where)) {
2722
- throw createError("Circular reference detected in WHERE clause", {
2723
- path: ctx.path,
2724
- modelName: ctx.model.name
2725
- });
2726
- }
2727
2598
  if (!isPlainObject(where) || Object.keys(where).length === 0) {
2728
2599
  return createResult(DEFAULT_WHERE_CLAUSE, EMPTY_JOINS);
2729
2600
  }
2730
- ctx.seenObjects.add(where);
2731
2601
  if (isSimpleWhere(where)) {
2732
2602
  const key = Object.keys(where)[0];
2733
2603
  const value = where[key];
@@ -2861,45 +2731,9 @@ function buildOperator(expr, op, val, ctx, mode, fieldType) {
2861
2731
  dialect: ctx.dialect
2862
2732
  });
2863
2733
  }
2864
- var MAX_QUERY_DEPTH, EMPTY_JOINS, JSON_OPS, WhereBuilder, whereBuilderInstance;
2865
- var init_builder = __esm({
2866
- "src/builder/where/builder.ts"() {
2867
- init_joins();
2868
- init_operators_scalar();
2869
- init_operators_array();
2870
- init_operators_json();
2871
- init_relations();
2872
- init_constants();
2873
- init_errors();
2874
- init_sql_utils();
2875
- init_field_assertions();
2876
- init_sql_validators();
2877
- init_type_guards();
2878
- init_array_utils();
2879
- MAX_QUERY_DEPTH = 50;
2880
- EMPTY_JOINS = [];
2881
- JSON_OPS = /* @__PURE__ */ new Set([
2882
- Ops.PATH,
2883
- Ops.STRING_CONTAINS,
2884
- Ops.STRING_STARTS_WITH,
2885
- Ops.STRING_ENDS_WITH
2886
- ]);
2887
- WhereBuilder = class {
2888
- build(where, ctx) {
2889
- if (!isPlainObject(where)) {
2890
- throw createError("where must be an object", {
2891
- path: ctx.path,
2892
- modelName: ctx.model.name
2893
- });
2894
- }
2895
- return buildWhereInternal(where, ctx, this);
2896
- }
2897
- };
2898
- whereBuilderInstance = new WhereBuilder();
2899
- }
2900
- });
2901
2734
 
2902
2735
  // src/builder/shared/alias-generator.ts
2736
+ var SAFE_IDENTIFIER_CACHE = /* @__PURE__ */ new Map();
2903
2737
  function toSafeSqlIdentifier(input) {
2904
2738
  const cached = SAFE_IDENTIFIER_CACHE.get(input);
2905
2739
  if (cached !== void 0) return cached;
@@ -2953,13 +2787,9 @@ function createAliasGenerator(maxAliases = 1e4) {
2953
2787
  }
2954
2788
  };
2955
2789
  }
2956
- var SAFE_IDENTIFIER_CACHE;
2957
- var init_alias_generator = __esm({
2958
- "src/builder/shared/alias-generator.ts"() {
2959
- init_constants();
2960
- SAFE_IDENTIFIER_CACHE = /* @__PURE__ */ new Map();
2961
- }
2962
- });
2790
+ var MAX_PARAM_INDEX = Number.MAX_SAFE_INTEGER - 1e3;
2791
+ var _a2;
2792
+ var IS_PRODUCTION2 = typeof process !== "undefined" && ((_a2 = process.env) == null ? void 0 : _a2.NODE_ENV) === "production";
2963
2793
  function assertSameLength(params, mappings) {
2964
2794
  if (params.length !== mappings.length) {
2965
2795
  throw new Error(
@@ -3019,6 +2849,11 @@ function validateMappings(mappings) {
3019
2849
  }
3020
2850
  }
3021
2851
  function validateState(params, mappings, index) {
2852
+ if (IS_PRODUCTION2) {
2853
+ assertSameLength(params, mappings);
2854
+ assertValidNextIndex(index);
2855
+ return;
2856
+ }
3022
2857
  assertSameLength(params, mappings);
3023
2858
  assertValidNextIndex(index);
3024
2859
  if (mappings.length === 0) return;
@@ -3041,6 +2876,10 @@ function assertCanAddParam(currentIndex) {
3041
2876
  );
3042
2877
  }
3043
2878
  }
2879
+ var POSTGRES_POSITION_CACHE = new Array(500);
2880
+ for (let i = 0; i < 500; i++) {
2881
+ POSTGRES_POSITION_CACHE[i] = `$${i + 1}`;
2882
+ }
3044
2883
  function formatPositionPostgres(position) {
3045
2884
  if (position <= 500) return POSTGRES_POSITION_CACHE[position - 1];
3046
2885
  return `$${position}`;
@@ -3154,17 +2993,6 @@ function createParamStoreFrom(existingParams, existingMappings, nextIndex, diale
3154
2993
  cachedIndex
3155
2994
  );
3156
2995
  }
3157
- var MAX_PARAM_INDEX, POSTGRES_POSITION_CACHE;
3158
- var init_param_store = __esm({
3159
- "src/builder/shared/param-store.ts"() {
3160
- init_normalize_value();
3161
- MAX_PARAM_INDEX = Number.MAX_SAFE_INTEGER - 1e3;
3162
- POSTGRES_POSITION_CACHE = new Array(500);
3163
- for (let i = 0; i < 500; i++) {
3164
- POSTGRES_POSITION_CACHE[i] = `$${i + 1}`;
3165
- }
3166
- }
3167
- });
3168
2996
 
3169
2997
  // src/builder/shared/state.ts
3170
2998
  function toPublicResult(clause, joins, params) {
@@ -3177,18 +3005,13 @@ function toPublicResult(clause, joins, params) {
3177
3005
  nextParamIndex: snapshot.index
3178
3006
  });
3179
3007
  }
3180
- var init_state = __esm({
3181
- "src/builder/shared/state.ts"() {
3182
- init_constants();
3183
- }
3184
- });
3185
3008
 
3186
3009
  // src/builder/where.ts
3187
3010
  function buildWhereClause(where, options) {
3188
- var _a, _b, _c, _d, _e;
3011
+ var _a3, _b, _c, _d, _e;
3189
3012
  assertSafeAlias(options.alias);
3190
3013
  const dialect = options.dialect || getGlobalDialect();
3191
- const params = (_a = options.params) != null ? _a : createParamStore();
3014
+ const params = (_a3 = options.params) != null ? _a3 : createParamStore(1, dialect);
3192
3015
  const ctx = {
3193
3016
  alias: options.alias,
3194
3017
  model: options.model,
@@ -3205,21 +3028,13 @@ function buildWhereClause(where, options) {
3205
3028
  const publicResult = toPublicResult(result.clause, result.joins, params);
3206
3029
  return publicResult;
3207
3030
  }
3208
- var init_where = __esm({
3209
- "src/builder/where.ts"() {
3210
- init_sql_builder_dialect();
3211
- init_builder();
3212
- init_alias_generator();
3213
- init_param_store();
3214
- init_state();
3215
- init_sql_utils();
3216
- }
3217
- });
3218
3031
 
3219
3032
  // src/builder/select/fields.ts
3033
+ var DEFAULT_SELECT_CACHE = /* @__PURE__ */ new WeakMap();
3220
3034
  function toSelectEntries(select) {
3221
3035
  const out = [];
3222
3036
  for (const [k, v] of Object.entries(select)) {
3037
+ if (k === "_count") continue;
3223
3038
  if (v !== false && v !== void 0) out.push([k, v]);
3224
3039
  }
3225
3040
  return out;
@@ -3255,8 +3070,8 @@ function buildDefaultScalarFields(model, alias) {
3255
3070
  return out;
3256
3071
  }
3257
3072
  function getDefaultSelectCached(model, alias) {
3258
- var _a;
3259
- return (_a = DEFAULT_SELECT_CACHE.get(model)) == null ? void 0 : _a.get(alias);
3073
+ var _a3;
3074
+ return (_a3 = DEFAULT_SELECT_CACHE.get(model)) == null ? void 0 : _a3.get(alias);
3260
3075
  }
3261
3076
  function cacheDefaultSelect(model, alias, sql) {
3262
3077
  let cache = DEFAULT_SELECT_CACHE.get(model);
@@ -3341,7 +3156,7 @@ function buildRelationSelect(relArgs, relModel, relAlias) {
3341
3156
  const scalarNames = getScalarFieldSet(relModel);
3342
3157
  const relationNames = getRelationFieldSet(relModel);
3343
3158
  const entries = toSelectEntries(sel);
3344
- validateFieldKeys(entries, scalarNames, relationNames, false);
3159
+ validateFieldKeys(entries, scalarNames, relationNames, true);
3345
3160
  return buildSelectedScalarParts(
3346
3161
  entries,
3347
3162
  scalarNames,
@@ -3351,19 +3166,10 @@ function buildRelationSelect(relArgs, relModel, relAlias) {
3351
3166
  }
3352
3167
  return buildAllScalarParts(relModel, relAlias).join(SQL_SEPARATORS.FIELD_LIST);
3353
3168
  }
3354
- var DEFAULT_SELECT_CACHE;
3355
- var init_fields = __esm({
3356
- "src/builder/select/fields.ts"() {
3357
- init_constants();
3358
- init_model_field_cache();
3359
- init_sql_utils();
3360
- init_type_guards();
3361
- DEFAULT_SELECT_CACHE = /* @__PURE__ */ new WeakMap();
3362
- }
3363
- });
3364
3169
 
3365
3170
  // src/builder/shared/relation-key-utils.ts
3366
- function resolveRelationKeys(field, context = "include") {
3171
+ var RELATION_KEYS_CACHE = /* @__PURE__ */ new WeakMap();
3172
+ function computeRelationKeys(field, context) {
3367
3173
  const fkFields = normalizeKeyList(field.foreignKey);
3368
3174
  if (fkFields.length === 0) {
3369
3175
  throw new Error(
@@ -3381,11 +3187,13 @@ function resolveRelationKeys(field, context = "include") {
3381
3187
  const parentKeys = field.isForeignKeyLocal ? fkFields : refFields;
3382
3188
  return { childKeys, parentKeys };
3383
3189
  }
3384
- var init_relation_key_utils = __esm({
3385
- "src/builder/shared/relation-key-utils.ts"() {
3386
- init_sql_utils();
3387
- }
3388
- });
3190
+ function resolveRelationKeys(field, context = "include") {
3191
+ let cached = RELATION_KEYS_CACHE.get(field);
3192
+ if (cached) return cached;
3193
+ cached = computeRelationKeys(field, context);
3194
+ RELATION_KEYS_CACHE.set(field, cached);
3195
+ return cached;
3196
+ }
3389
3197
 
3390
3198
  // src/builder/shared/relation-extraction-utils.ts
3391
3199
  function extractRelationEntries(args, model) {
@@ -3410,12 +3218,23 @@ function extractRelationEntries(args, model) {
3410
3218
  }
3411
3219
  return entries;
3412
3220
  }
3413
- var init_relation_extraction_utils = __esm({
3414
- "src/builder/shared/relation-extraction-utils.ts"() {
3415
- init_model_field_cache();
3416
- init_type_guards();
3417
- }
3418
- });
3221
+
3222
+ // src/builder/select/includes.ts
3223
+ var MAX_INCLUDE_DEPTH = 5;
3224
+ var MAX_INCLUDES_PER_LEVEL = 10;
3225
+ var MAX_TOTAL_SUBQUERIES = 100;
3226
+ var FIELD_BY_NAME_CACHE2 = /* @__PURE__ */ new WeakMap();
3227
+ function getFieldMap(model) {
3228
+ let map = FIELD_BY_NAME_CACHE2.get(model);
3229
+ if (!map) {
3230
+ map = /* @__PURE__ */ new Map();
3231
+ for (const f of model.fields) {
3232
+ map.set(f.name, f);
3233
+ }
3234
+ FIELD_BY_NAME_CACHE2.set(model, map);
3235
+ }
3236
+ return map;
3237
+ }
3419
3238
  function buildIncludeScope(includePath) {
3420
3239
  if (includePath.length === 0) return "include";
3421
3240
  let scope = "include";
@@ -3435,7 +3254,8 @@ function getRelationTableReference(relModel, dialect) {
3435
3254
  );
3436
3255
  }
3437
3256
  function resolveRelationOrThrow(model, schemaByName, relName) {
3438
- const field = model.fields.find((f) => f.name === relName);
3257
+ const fieldMap = getFieldMap(model);
3258
+ const field = fieldMap.get(relName);
3439
3259
  if (!isNotNullish(field)) {
3440
3260
  throw new Error(
3441
3261
  `Unknown relation '${relName}' on model ${model.name}. Available relation fields: ${model.fields.filter((f) => f.isRelation).map((f) => f.name).join(", ")}`
@@ -3552,11 +3372,22 @@ function finalizeOrderByForInclude(args) {
3552
3372
  }
3553
3373
  function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
3554
3374
  let relSelect = buildRelationSelect(relArgs, relModel, relAlias);
3555
- const nestedIncludes = isPlainObject(relArgs) ? buildIncludeSqlInternal(relArgs, __spreadProps(__spreadValues({}, ctx), {
3556
- model: relModel,
3557
- parentAlias: relAlias,
3558
- depth: ctx.depth + 1
3559
- })) : [];
3375
+ let nestedIncludes = [];
3376
+ if (isPlainObject(relArgs)) {
3377
+ const prevModel = ctx.model;
3378
+ const prevParentAlias = ctx.parentAlias;
3379
+ const prevDepth = ctx.depth;
3380
+ ctx.model = relModel;
3381
+ ctx.parentAlias = relAlias;
3382
+ ctx.depth = prevDepth + 1;
3383
+ try {
3384
+ nestedIncludes = buildIncludeSqlInternal(relArgs, ctx);
3385
+ } finally {
3386
+ ctx.model = prevModel;
3387
+ ctx.parentAlias = prevParentAlias;
3388
+ ctx.depth = prevDepth;
3389
+ }
3390
+ }
3560
3391
  if (isNonEmptyArray(nestedIncludes)) {
3561
3392
  const emptyJson = ctx.dialect === "postgres" ? `'[]'::json` : `json('[]')`;
3562
3393
  const nestedSelects = nestedIncludes.map(
@@ -3700,9 +3531,9 @@ function hasNestedRelationInArgs(relArgs, relModel) {
3700
3531
  if (checkSource(relArgs.select)) return true;
3701
3532
  return false;
3702
3533
  }
3703
- function canUseJoinInclude(dialect, isList2, takeVal, skipVal, depth, outerHasLimit, hasNestedIncludes2) {
3534
+ function canUseJoinInclude(dialect, isList, takeVal, skipVal, depth, outerHasLimit, hasNestedIncludes2) {
3704
3535
  if (dialect !== "postgres") return false;
3705
- if (!isList2) return false;
3536
+ if (!isList) return false;
3706
3537
  if (depth > 0) return false;
3707
3538
  if (outerHasLimit) return false;
3708
3539
  if (hasNestedIncludes2) return false;
@@ -3797,7 +3628,7 @@ function buildJoinBasedPaginated(args) {
3797
3628
  function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3798
3629
  const relTable = getRelationTableReference(relModel, ctx.dialect);
3799
3630
  const relAlias = ctx.aliasGen.next(relName);
3800
- const isList2 = typeof field.type === "string" && field.type.endsWith("[]");
3631
+ const isList = typeof field.type === "string" && field.type.endsWith("[]");
3801
3632
  const joinPredicate = joinCondition(
3802
3633
  field,
3803
3634
  ctx.model,
@@ -3814,7 +3645,7 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3814
3645
  );
3815
3646
  const whereParts = buildWhereParts(whereInput, relModel, relAlias, ctx);
3816
3647
  const paginationConfig = extractRelationPaginationConfig(relArgs);
3817
- if (!isList2 && typeof paginationConfig.takeVal === "number" && paginationConfig.takeVal < 0) {
3648
+ if (!isList && typeof paginationConfig.takeVal === "number" && paginationConfig.takeVal < 0) {
3818
3649
  throw new Error("Negative take is only supported for list relations");
3819
3650
  }
3820
3651
  const adjusted = maybeReverseNegativeTake(
@@ -3835,7 +3666,7 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3835
3666
  ctx.dialect,
3836
3667
  relModel
3837
3668
  );
3838
- if (!isList2) {
3669
+ if (!isList) {
3839
3670
  const sql = buildOneToOneIncludeSql({
3840
3671
  relTable,
3841
3672
  relAlias,
@@ -3855,7 +3686,7 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3855
3686
  const nestedIncludes = hasNestedRelationInArgs(relArgs, relModel);
3856
3687
  if (canUseJoinInclude(
3857
3688
  ctx.dialect,
3858
- isList2,
3689
+ isList,
3859
3690
  adjusted.takeVal,
3860
3691
  paginationConfig.skipVal,
3861
3692
  depth,
@@ -3953,16 +3784,22 @@ function buildIncludeSqlInternal(args, ctx) {
3953
3784
  `Circular include detected: ${Array.from(ctx.visitSet).join(" -> ")} -> ${relationPath}. Relation '${relationPath}' creates an infinite loop.`
3954
3785
  );
3955
3786
  }
3956
- const nextIncludePath = [...ctx.includePath, relName];
3957
- const nextVisitSet = new Set(ctx.visitSet);
3958
- nextVisitSet.add(relationPath);
3959
- includes.push(
3960
- buildSingleInclude(relName, relArgs, resolved.field, resolved.relModel, __spreadProps(__spreadValues({}, ctx), {
3961
- includePath: nextIncludePath,
3962
- visitSet: nextVisitSet,
3963
- depth
3964
- }))
3965
- );
3787
+ ctx.includePath.push(relName);
3788
+ ctx.visitSet.add(relationPath);
3789
+ try {
3790
+ includes.push(
3791
+ buildSingleInclude(
3792
+ relName,
3793
+ relArgs,
3794
+ resolved.field,
3795
+ resolved.relModel,
3796
+ ctx
3797
+ )
3798
+ );
3799
+ } finally {
3800
+ ctx.includePath.pop();
3801
+ ctx.visitSet.delete(relationPath);
3802
+ }
3966
3803
  }
3967
3804
  return includes;
3968
3805
  }
@@ -4100,30 +3937,6 @@ function buildRelationCountSql(countSelect, model, schemas, parentAlias, _params
4100
3937
  }
4101
3938
  return { joins, jsonPairs: pairs.join(SQL_SEPARATORS.FIELD_LIST) };
4102
3939
  }
4103
- var MAX_INCLUDE_DEPTH, MAX_INCLUDES_PER_LEVEL, MAX_TOTAL_SUBQUERIES;
4104
- var init_includes = __esm({
4105
- "src/builder/select/includes.ts"() {
4106
- init_joins();
4107
- init_pagination();
4108
- init_where();
4109
- init_sql_builder_dialect();
4110
- init_fields();
4111
- init_alias_generator();
4112
- init_constants();
4113
- init_sql_utils();
4114
- init_sql_validators();
4115
- init_type_guards();
4116
- init_order_by_utils();
4117
- init_dynamic_params();
4118
- init_model_field_cache();
4119
- init_order_by_determinism();
4120
- init_relation_key_utils();
4121
- init_relation_extraction_utils();
4122
- MAX_INCLUDE_DEPTH = 5;
4123
- MAX_INCLUDES_PER_LEVEL = 10;
4124
- MAX_TOTAL_SUBQUERIES = 100;
4125
- }
4126
- });
4127
3940
 
4128
3941
  // src/builder/shared/string-builder.ts
4129
3942
  function joinNonEmpty(parts, sep) {
@@ -4136,10 +3949,6 @@ function joinNonEmpty(parts, sep) {
4136
3949
  }
4137
3950
  return result;
4138
3951
  }
4139
- var init_string_builder = __esm({
4140
- "src/builder/shared/string-builder.ts"() {
4141
- }
4142
- });
4143
3952
 
4144
3953
  // src/builder/shared/relation-utils.ts
4145
3954
  function hasChildPagination(relArgs) {
@@ -4201,12 +4010,6 @@ function extractNestedIncludeSpec(relArgs, relModel) {
4201
4010
  }
4202
4011
  return out;
4203
4012
  }
4204
- var init_relation_utils = __esm({
4205
- "src/builder/shared/relation-utils.ts"() {
4206
- init_model_field_cache();
4207
- init_type_guards();
4208
- }
4209
- });
4210
4013
 
4211
4014
  // src/builder/select/flat-join.ts
4212
4015
  function createAliasCounter() {
@@ -4280,10 +4083,19 @@ function canUseNestedFlatJoin(relArgs, depth) {
4280
4083
  }
4281
4084
  return true;
4282
4085
  }
4283
- function canUseFlatJoinForAll(includeSpec) {
4284
- for (const value of Object.values(includeSpec)) {
4086
+ function canUseFlatJoinForAll(includeSpec, parentModel, schemas) {
4087
+ const modelMap = new Map(schemas.map((m) => [m.name, m]));
4088
+ for (const [relName, value] of Object.entries(includeSpec)) {
4285
4089
  if (value === false) continue;
4090
+ const field = parentModel.fields.find((f) => f.name === relName);
4091
+ if (!field || !field.isRelation) continue;
4286
4092
  if (!canUseNestedFlatJoin(value, 0)) return false;
4093
+ const relModel = modelMap.get(field.relatedModel);
4094
+ if (!relModel) continue;
4095
+ const nestedSpec = extractNestedIncludeSpec(value, relModel);
4096
+ if (Object.keys(nestedSpec).length > 0) {
4097
+ if (!canUseFlatJoinForAll(nestedSpec, relModel, schemas)) return false;
4098
+ }
4287
4099
  }
4288
4100
  return true;
4289
4101
  }
@@ -4380,7 +4192,7 @@ function buildFlatJoinSql(spec) {
4380
4192
  if (Object.keys(includeSpec).length === 0) {
4381
4193
  return { sql: "", requiresReduction: false, includeSpec: {} };
4382
4194
  }
4383
- if (!canUseFlatJoinForAll(includeSpec)) {
4195
+ if (!canUseFlatJoinForAll(includeSpec, model, schemas)) {
4384
4196
  return { sql: "", requiresReduction: false, includeSpec: {} };
4385
4197
  }
4386
4198
  const baseJoins = whereJoins.length > 0 ? whereJoins.join(" ") : "";
@@ -4426,48 +4238,247 @@ function buildFlatJoinSql(spec) {
4426
4238
  `.trim();
4427
4239
  return { sql, requiresReduction: true, includeSpec };
4428
4240
  }
4429
- var init_flat_join = __esm({
4430
- "src/builder/select/flat-join.ts"() {
4431
- init_constants();
4432
- init_sql_utils();
4433
- init_joins();
4434
- init_model_field_cache();
4435
- init_assembly();
4436
- init_type_guards();
4437
- init_primary_key_utils();
4438
- init_relation_extraction_utils();
4439
- init_relation_utils();
4241
+
4242
+ // src/builder/select/array-agg.ts
4243
+ function canUseArrayAggForAll(includeSpec, parentModel, schemas) {
4244
+ const modelMap = new Map(schemas.map((m) => [m.name, m]));
4245
+ for (const [relName, value] of Object.entries(includeSpec)) {
4246
+ if (value === false) continue;
4247
+ const field = parentModel.fields.find((f) => f.name === relName);
4248
+ if (!field || !field.isRelation) continue;
4249
+ if (isPlainObject(value) && hasChildPagination(value)) return false;
4250
+ const relModel = modelMap.get(field.relatedModel);
4251
+ if (!relModel) continue;
4252
+ const nestedSpec = extractNestedIncludeSpec(value, relModel);
4253
+ if (Object.keys(nestedSpec).length > 0) return false;
4440
4254
  }
4441
- });
4442
- function buildWhereSql(conditions) {
4443
- if (!isNonEmptyArray(conditions)) return "";
4444
- return " " + SQL_TEMPLATES.WHERE + " " + conditions.join(SQL_SEPARATORS.CONDITION_AND);
4255
+ return true;
4445
4256
  }
4446
- function buildJoinsSql(...joinGroups) {
4447
- const all = [];
4448
- for (const g of joinGroups) {
4449
- if (isNonEmptyArray(g)) {
4450
- for (const j of g) all.push(j);
4451
- }
4257
+ function getRelationModel2(parentModel, relationName, schemas) {
4258
+ const field = parentModel.fields.find((f) => f.name === relationName);
4259
+ if (!(field == null ? void 0 : field.isRelation) || !field.relatedModel) {
4260
+ throw new Error(`Invalid relation ${relationName} on ${parentModel.name}`);
4452
4261
  }
4453
- return all.length > 0 ? " " + all.join(" ") : "";
4262
+ const relModel = schemas.find((m) => m.name === field.relatedModel);
4263
+ if (!relModel) {
4264
+ throw new Error(`Related model ${field.relatedModel} not found`);
4265
+ }
4266
+ return relModel;
4454
4267
  }
4455
- function buildSelectList(baseSelect, extraCols) {
4456
- const base = baseSelect.trim();
4457
- const extra = extraCols.trim();
4458
- if (!base) return extra;
4459
- if (!extra) return base;
4460
- return base + SQL_SEPARATORS.FIELD_LIST + extra;
4268
+ function buildSubqueryRawSelect2(model, alias) {
4269
+ const cols = [];
4270
+ for (const f of model.fields) {
4271
+ if (f.isRelation) continue;
4272
+ cols.push(`${alias}.${quoteColumn(model, f.name)}`);
4273
+ }
4274
+ return cols.length > 0 ? cols.join(SQL_SEPARATORS.FIELD_LIST) : "*";
4461
4275
  }
4462
- function finalizeSql(sql, params, dialect) {
4463
- const snapshot = params.snapshot();
4464
- validateSelectQuery(sql);
4465
- validateParamConsistencyByDialect(sql, snapshot.params, dialect);
4466
- return {
4467
- sql,
4468
- params: [...snapshot.params],
4469
- paramMappings: [...snapshot.mappings]
4470
- };
4276
+ function readWhereInput2(relArgs) {
4277
+ if (!isPlainObject(relArgs)) return {};
4278
+ const obj = relArgs;
4279
+ if (!("where" in obj)) return {};
4280
+ const w = obj.where;
4281
+ return isPlainObject(w) ? w : {};
4282
+ }
4283
+ function buildArrayAggRelation(args) {
4284
+ const {
4285
+ relationName,
4286
+ relArgs,
4287
+ field,
4288
+ relModel,
4289
+ parentModel,
4290
+ parentAlias,
4291
+ schemas,
4292
+ dialect,
4293
+ aliasCounter,
4294
+ params
4295
+ } = args;
4296
+ const isList = typeof field.type === "string" && field.type.endsWith("[]");
4297
+ const { childKeys: relKeyFields, parentKeys: parentKeyFields } = resolveRelationKeys(field, "include");
4298
+ if (relKeyFields.length === 0) return null;
4299
+ const innerAlias = `__aa_r${aliasCounter.count++}`;
4300
+ const joinAlias = `__aa_j${aliasCounter.count++}`;
4301
+ const indices = getFieldIndices(relModel);
4302
+ const scalarSel = extractScalarSelection(relArgs, relModel);
4303
+ const pkFields = getPrimaryKeyFields(relModel);
4304
+ const selectedFields = scalarSel.includeAllScalars ? Array.from(indices.scalarFields.keys()) : [.../* @__PURE__ */ new Set([...pkFields, ...scalarSel.selectedScalarFields])];
4305
+ const pkOrderExpr = pkFields.map((f) => `${innerAlias}.${quoteColumn(relModel, f)}`).join(SQL_SEPARATORS.FIELD_LIST);
4306
+ const pkFilterExpr = `${innerAlias}.${quoteColumn(relModel, pkFields[0])}`;
4307
+ const fkSelectParts = relKeyFields.map(
4308
+ (f, i) => `${innerAlias}.${quoteColumn(relModel, f)} AS "__fk${i}"`
4309
+ );
4310
+ const aggParts = selectedFields.map((fieldName) => {
4311
+ const f = indices.scalarFields.get(fieldName);
4312
+ if (!f) return null;
4313
+ const colRef = `${innerAlias}.${quoteColumn(relModel, fieldName)}`;
4314
+ const alias = `"${relationName}.${f.name}"`;
4315
+ return `array_agg(${colRef} ORDER BY ${pkOrderExpr}) FILTER (WHERE ${pkFilterExpr} IS NOT NULL) AS ${alias}`;
4316
+ }).filter(Boolean);
4317
+ const fkGroupByParts = relKeyFields.map(
4318
+ (f) => `${innerAlias}.${quoteColumn(relModel, f)}`
4319
+ );
4320
+ const relTable = buildTableReference(
4321
+ SQL_TEMPLATES.PUBLIC_SCHEMA,
4322
+ relModel.tableName,
4323
+ dialect
4324
+ );
4325
+ const whereInput = readWhereInput2(relArgs);
4326
+ let whereJoinsSql = "";
4327
+ let whereClauseSql = "";
4328
+ if (Object.keys(whereInput).length > 0) {
4329
+ const aliasGen = createAliasGenerator();
4330
+ const whereResult = buildWhereClause(whereInput, {
4331
+ alias: innerAlias,
4332
+ schemaModels: schemas,
4333
+ model: relModel,
4334
+ params,
4335
+ isSubquery: true,
4336
+ aliasGen,
4337
+ dialect
4338
+ });
4339
+ if (whereResult.joins.length > 0) {
4340
+ whereJoinsSql = " " + whereResult.joins.join(" ");
4341
+ }
4342
+ if (isValidWhereClause(whereResult.clause)) {
4343
+ whereClauseSql = ` ${SQL_TEMPLATES.WHERE} ${whereResult.clause}`;
4344
+ }
4345
+ }
4346
+ const subquery = `SELECT ${fkSelectParts.join(SQL_SEPARATORS.FIELD_LIST)}${SQL_SEPARATORS.FIELD_LIST}${aggParts.join(SQL_SEPARATORS.FIELD_LIST)} FROM ${relTable} ${innerAlias}${whereJoinsSql}${whereClauseSql} GROUP BY ${fkGroupByParts.join(SQL_SEPARATORS.FIELD_LIST)}`;
4347
+ const onParts = parentKeyFields.map(
4348
+ (f, i) => `${joinAlias}."__fk${i}" = ${parentAlias}.${quoteColumn(parentModel, f)}`
4349
+ );
4350
+ const onCondition = onParts.length === 1 ? onParts[0] : `(${onParts.join(" AND ")})`;
4351
+ const joinSql = `LEFT JOIN (${subquery}) ${joinAlias} ON ${onCondition}`;
4352
+ const selectExprs = selectedFields.map((fieldName) => {
4353
+ const f = indices.scalarFields.get(fieldName);
4354
+ if (!f) return null;
4355
+ return `${joinAlias}."${relationName}.${f.name}"`;
4356
+ }).filter(Boolean);
4357
+ return {
4358
+ joinSql,
4359
+ selectExprs,
4360
+ relationName,
4361
+ isList,
4362
+ scalarFieldNames: selectedFields
4363
+ };
4364
+ }
4365
+ function buildArrayAggSql(spec) {
4366
+ const {
4367
+ select,
4368
+ from,
4369
+ whereClause,
4370
+ whereJoins,
4371
+ orderBy,
4372
+ dialect,
4373
+ model,
4374
+ schemas,
4375
+ args,
4376
+ params
4377
+ } = spec;
4378
+ const entries = extractRelationEntries(args, model);
4379
+ const includeSpec = {};
4380
+ for (const e of entries) {
4381
+ includeSpec[e.name] = e.value;
4382
+ }
4383
+ if (Object.keys(includeSpec).length === 0) {
4384
+ return {
4385
+ sql: "",
4386
+ requiresReduction: false,
4387
+ includeSpec: {},
4388
+ isArrayAgg: false
4389
+ };
4390
+ }
4391
+ if (!canUseArrayAggForAll(includeSpec, model, schemas)) {
4392
+ return {
4393
+ sql: "",
4394
+ requiresReduction: false,
4395
+ includeSpec: {},
4396
+ isArrayAgg: false
4397
+ };
4398
+ }
4399
+ const baseJoins = whereJoins.length > 0 ? whereJoins.join(" ") : "";
4400
+ const baseWhere = whereClause && whereClause !== "1=1" ? `WHERE ${whereClause}` : "";
4401
+ const baseOrderBy = orderBy ? `ORDER BY ${orderBy}` : "";
4402
+ const subqueryScalarCols = buildSubqueryRawSelect2(model, from.alias);
4403
+ let baseSubquery = `SELECT ${subqueryScalarCols} FROM ${from.table} ${from.alias}` + (baseJoins ? ` ${baseJoins}` : "") + (baseWhere ? ` ${baseWhere}` : "") + (baseOrderBy ? ` ${baseOrderBy}` : "");
4404
+ baseSubquery = appendPagination(baseSubquery.trim(), spec);
4405
+ const aliasCounter = { count: 0 };
4406
+ const joins = [];
4407
+ const arraySelectExprs = [];
4408
+ for (const [relName, relValue] of Object.entries(includeSpec)) {
4409
+ if (relValue === false) continue;
4410
+ const field = model.fields.find((f) => f.name === relName);
4411
+ if (!field || !isValidRelationField(field)) continue;
4412
+ const relModel = getRelationModel2(model, relName, schemas);
4413
+ const built = buildArrayAggRelation({
4414
+ relationName: relName,
4415
+ relArgs: relValue,
4416
+ field,
4417
+ relModel,
4418
+ parentModel: model,
4419
+ parentAlias: from.alias,
4420
+ schemas,
4421
+ dialect,
4422
+ aliasCounter,
4423
+ params
4424
+ });
4425
+ if (!built) continue;
4426
+ joins.push(built.joinSql);
4427
+ arraySelectExprs.push(...built.selectExprs);
4428
+ }
4429
+ if (joins.length === 0) {
4430
+ return {
4431
+ sql: "",
4432
+ requiresReduction: false,
4433
+ includeSpec: {},
4434
+ isArrayAgg: false
4435
+ };
4436
+ }
4437
+ const baseSelect = (select != null ? select : "").trim();
4438
+ const allSelects = [baseSelect, ...arraySelectExprs].filter((s) => s && s.trim().length > 0).join(SQL_SEPARATORS.FIELD_LIST);
4439
+ if (!allSelects) {
4440
+ throw new Error("Array-agg SELECT requires at least one selected field");
4441
+ }
4442
+ const pkField = getPrimaryKeyField(model);
4443
+ const pkOrder = `${from.alias}.${quoteColumn(model, pkField)} ASC`;
4444
+ const sql = `
4445
+ SELECT ${allSelects}
4446
+ FROM (${baseSubquery}) ${from.alias}
4447
+ ${joins.join(" ")}
4448
+ ORDER BY ${pkOrder}
4449
+ `.trim();
4450
+ return { sql, requiresReduction: true, includeSpec, isArrayAgg: true };
4451
+ }
4452
+ var SELECT_FIELD_REGEX = /^\s*("(?:[^"]|"")+"|[a-z_][a-z0-9_]*)\s*\.\s*("(?:[^"]|"")+"|[a-z_][a-z0-9_]*)(?:\s+AS\s+("(?:[^"]|"")+"|[a-z_][a-z0-9_]*))?\s*$/i;
4453
+ function buildWhereSql(conditions) {
4454
+ if (!isNonEmptyArray(conditions)) return "";
4455
+ return " " + SQL_TEMPLATES.WHERE + " " + conditions.join(SQL_SEPARATORS.CONDITION_AND);
4456
+ }
4457
+ function buildJoinsSql(...joinGroups) {
4458
+ const all = [];
4459
+ for (const g of joinGroups) {
4460
+ if (isNonEmptyArray(g)) {
4461
+ for (const j of g) all.push(j);
4462
+ }
4463
+ }
4464
+ return all.length > 0 ? " " + all.join(" ") : "";
4465
+ }
4466
+ function buildSelectList(baseSelect, extraCols) {
4467
+ const base = baseSelect.trim();
4468
+ const extra = extraCols.trim();
4469
+ if (!base) return extra;
4470
+ if (!extra) return base;
4471
+ return base + SQL_SEPARATORS.FIELD_LIST + extra;
4472
+ }
4473
+ function finalizeSql(sql, params, dialect) {
4474
+ const snapshot = params.snapshot();
4475
+ validateSelectQuery(sql);
4476
+ validateParamConsistencyByDialect(sql, snapshot.params, dialect);
4477
+ return {
4478
+ sql,
4479
+ params: [...snapshot.params],
4480
+ paramMappings: [...snapshot.mappings]
4481
+ };
4471
4482
  }
4472
4483
  function unquoteIdent(s) {
4473
4484
  if (s.startsWith('"') && s.endsWith('"')) {
@@ -4525,47 +4536,45 @@ function buildOutputColumns(scalarNames, includeNames, hasCount) {
4525
4536
  }
4526
4537
  return formatted;
4527
4538
  }
4528
- function buildWindowOrder(args) {
4529
- const { baseOrder, idField, fromAlias, model } = args;
4530
- const fromLower = String(fromAlias).toLowerCase();
4531
- const orderFields = baseOrder.split(SQL_SEPARATORS.ORDER_BY).map((s) => s.trim().toLowerCase().replace(/\s+/g, " "));
4532
- const hasIdInOrder = orderFields.some((f) => {
4533
- return f.includes(`${fromLower}.id`) || f.includes(`${fromLower}."id"`);
4534
- });
4535
- if (hasIdInOrder) return baseOrder;
4536
- const idTiebreaker = idField ? ", " + col(fromAlias, "id", model) + " ASC" : "";
4537
- return baseOrder + idTiebreaker;
4538
- }
4539
- function extractDistinctOrderEntries(spec) {
4540
- if (isNotNullish(spec.args.orderBy)) {
4541
- const normalized = normalizeOrderByInput(
4542
- spec.args.orderBy,
4543
- parseOrderByValue
4544
- );
4545
- const entries = [];
4546
- for (const item of normalized) {
4547
- for (const field in item) {
4548
- if (!Object.prototype.hasOwnProperty.call(item, field)) continue;
4549
- const value = item[field];
4550
- if (typeof value === "string") {
4551
- entries.push({ field, direction: value });
4552
- continue;
4553
- }
4554
- const obj = value;
4555
- entries.push({ field, direction: obj.direction, nulls: obj.nulls });
4539
+ function getOrderByEntries(spec) {
4540
+ if (!isNotNullish(spec.args.orderBy)) return [];
4541
+ const normalized = normalizeOrderByInput(spec.args.orderBy, parseOrderByValue);
4542
+ const entries = [];
4543
+ for (const item of normalized) {
4544
+ for (const field in item) {
4545
+ if (!Object.prototype.hasOwnProperty.call(item, field)) continue;
4546
+ const value = item[field];
4547
+ if (typeof value === "string") {
4548
+ entries.push({ field, direction: value });
4549
+ continue;
4556
4550
  }
4551
+ const obj = value;
4552
+ entries.push({ field, direction: obj.direction, nulls: obj.nulls });
4557
4553
  }
4558
- if (entries.length > 0) return entries;
4559
4554
  }
4560
- if (isNotNullish(spec.distinct) && isNonEmptyArray(spec.distinct)) {
4561
- return [...spec.distinct].map((f) => ({
4562
- field: f,
4563
- direction: "asc"
4564
- }));
4555
+ return entries;
4556
+ }
4557
+ function renderOrderBySql(entries, alias, dialect, model) {
4558
+ if (entries.length === 0) return "";
4559
+ const out = [];
4560
+ for (const e of entries) {
4561
+ const dir = e.direction.toUpperCase();
4562
+ const c = col(alias, e.field, model);
4563
+ if (dialect === "postgres") {
4564
+ const nulls = isNotNullish(e.nulls) ? ` NULLS ${e.nulls.toUpperCase()}` : "";
4565
+ out.push(c + " " + dir + nulls);
4566
+ } else if (isNotNullish(e.nulls)) {
4567
+ const isNullExpr = `(${c} IS NULL)`;
4568
+ const nullRankDir = e.nulls === "first" ? "DESC" : "ASC";
4569
+ out.push(isNullExpr + " " + nullRankDir);
4570
+ out.push(c + " " + dir);
4571
+ } else {
4572
+ out.push(c + " " + dir);
4573
+ }
4565
4574
  }
4566
- return [];
4575
+ return out.join(SQL_SEPARATORS.ORDER_BY);
4567
4576
  }
4568
- function buildFieldNameOrderBy(entries, alias) {
4577
+ function renderOrderBySimple(entries, alias) {
4569
4578
  if (entries.length === 0) return "";
4570
4579
  const out = [];
4571
4580
  for (const e of entries) {
@@ -4576,40 +4585,73 @@ function buildFieldNameOrderBy(entries, alias) {
4576
4585
  const nullRankDir = e.nulls === "first" ? "DESC" : "ASC";
4577
4586
  out.push(isNullExpr + " " + nullRankDir);
4578
4587
  out.push(c + " " + dir);
4579
- continue;
4588
+ } else {
4589
+ out.push(c + " " + dir);
4580
4590
  }
4581
- out.push(c + " " + dir);
4582
4591
  }
4583
4592
  return out.join(SQL_SEPARATORS.ORDER_BY);
4584
4593
  }
4594
+ function ensureIdTiebreakerEntries(entries, model) {
4595
+ var _a3, _b;
4596
+ const idField = (_b = (_a3 = model == null ? void 0 : model.fields) == null ? void 0 : _a3.find) == null ? void 0 : _b.call(
4597
+ _a3,
4598
+ (f) => f.name === "id" && !f.isRelation
4599
+ );
4600
+ if (!idField) return entries;
4601
+ if (entries.some((e) => e.field === "id")) return entries;
4602
+ return [...entries, { field: "id", direction: "asc" }];
4603
+ }
4604
+ function ensurePostgresDistinctOrderEntries(args) {
4605
+ const { entries, distinct, model } = args;
4606
+ const distinctEntries = [...distinct].map((f) => ({
4607
+ field: f,
4608
+ direction: "asc"
4609
+ }));
4610
+ const canKeepAsIs = entries.length >= distinctEntries.length && distinctEntries.every((de, i) => entries[i].field === de.field);
4611
+ const merged = canKeepAsIs ? entries : [...distinctEntries, ...entries];
4612
+ return ensureIdTiebreakerEntries(merged, model);
4613
+ }
4614
+ function extractDistinctOrderEntries(spec) {
4615
+ const entries = getOrderByEntries(spec);
4616
+ if (entries.length > 0) return entries;
4617
+ if (isNotNullish(spec.distinct) && isNonEmptyArray(spec.distinct)) {
4618
+ return [...spec.distinct].map((f) => ({
4619
+ field: f,
4620
+ direction: "asc"
4621
+ }));
4622
+ }
4623
+ return [];
4624
+ }
4585
4625
  function buildSqliteDistinctQuery(spec, selectWithIncludes, countJoins) {
4586
- var _a, _b;
4587
- const { includes, from, whereClause, whereJoins, orderBy, distinct, model } = spec;
4626
+ var _a3, _b;
4627
+ const { includes, from, whereClause, whereJoins, distinct, model } = spec;
4588
4628
  if (!isNotNullish(distinct) || !isNonEmptyArray(distinct)) {
4589
4629
  throw new Error("buildSqliteDistinctQuery requires distinct fields");
4590
4630
  }
4591
4631
  const scalarNames = parseSimpleScalarSelect(spec.select, from.alias);
4592
4632
  const includeNames = includes.map((i) => i.name);
4593
- const hasCount = Boolean((_b = (_a = spec.args) == null ? void 0 : _a.select) == null ? void 0 : _b._count);
4633
+ const hasCount = Boolean((_b = (_a3 = spec.args) == null ? void 0 : _a3.select) == null ? void 0 : _b._count);
4594
4634
  const outerSelectCols = buildOutputColumns(
4595
4635
  scalarNames,
4596
4636
  includeNames,
4597
4637
  hasCount
4598
4638
  );
4599
4639
  const distinctCols = buildDistinctColumns([...distinct], from.alias, model);
4600
- const fallbackOrder = [...distinct].map((f) => col(from.alias, f, model) + " ASC").join(SQL_SEPARATORS.FIELD_LIST);
4601
- const idField = model.fields.find(
4602
- (f) => f.name === "id" && !f.isRelation
4603
- );
4604
- const baseOrder = isNonEmptyString(orderBy) ? orderBy : fallbackOrder;
4605
- const windowOrder = buildWindowOrder({
4606
- baseOrder,
4607
- idField,
4608
- fromAlias: from.alias,
4640
+ const baseEntries = getOrderByEntries(spec);
4641
+ const fallbackEntries = [...distinct].map((f) => ({
4642
+ field: f,
4643
+ direction: "asc"
4644
+ }));
4645
+ const resolvedEntries = baseEntries.length > 0 ? baseEntries : fallbackEntries;
4646
+ const windowEntries = ensureIdTiebreakerEntries(resolvedEntries, model);
4647
+ const windowOrder = renderOrderBySql(
4648
+ windowEntries,
4649
+ from.alias,
4650
+ "sqlite",
4609
4651
  model
4610
- });
4652
+ );
4611
4653
  const outerEntries = extractDistinctOrderEntries(spec);
4612
- const outerOrder = buildFieldNameOrderBy(outerEntries, '"__tp_distinct"');
4654
+ const outerOrder = renderOrderBySimple(outerEntries, '"__tp_distinct"');
4613
4655
  const joins = buildJoinsSql(whereJoins, countJoins);
4614
4656
  const conditions = [];
4615
4657
  if (whereClause && whereClause !== "1=1") conditions.push(whereClause);
@@ -4660,12 +4702,12 @@ function resolveCountSelect(countSelectRaw, model) {
4660
4702
  return null;
4661
4703
  }
4662
4704
  function buildIncludeColumns(spec) {
4663
- var _a, _b;
4705
+ var _a3, _b;
4664
4706
  const { select, includes, dialect, model, schemas, from, params } = spec;
4665
4707
  const baseSelect = (select != null ? select : "").trim();
4666
4708
  let countCols = "";
4667
4709
  let countJoins = [];
4668
- const countSelectRaw = (_b = (_a = spec.args) == null ? void 0 : _a.select) == null ? void 0 : _b._count;
4710
+ const countSelectRaw = (_b = (_a3 = spec.args) == null ? void 0 : _a3.select) == null ? void 0 : _b._count;
4669
4711
  if (countSelectRaw) {
4670
4712
  const resolvedCountSelect = resolveCountSelect(countSelectRaw, model);
4671
4713
  if (resolvedCountSelect && Object.keys(resolvedCountSelect).length > 0) {
@@ -4824,37 +4866,6 @@ function extractIncludeSpec(args) {
4824
4866
  function hasNestedIncludes(includeSpec) {
4825
4867
  return Object.keys(includeSpec).length > 0;
4826
4868
  }
4827
- function splitOrderByTerms(orderBy) {
4828
- const raw = orderBy.trim();
4829
- if (raw.length === 0) return [];
4830
- return raw.split(SQL_SEPARATORS.ORDER_BY).map((s) => s.trim()).filter((s) => s.length > 0);
4831
- }
4832
- function hasIdInOrderBy(orderBy, fromAlias) {
4833
- const lower = orderBy.toLowerCase();
4834
- const aliasLower = fromAlias.toLowerCase();
4835
- return lower.includes(`${aliasLower}.id `) || lower.includes(`${aliasLower}."id"`);
4836
- }
4837
- function ensureIdTiebreakerOrderBy(orderBy, fromAlias, model) {
4838
- var _a, _b;
4839
- const idField = (_b = (_a = model == null ? void 0 : model.fields) == null ? void 0 : _a.find) == null ? void 0 : _b.call(
4840
- _a,
4841
- (f) => f.name === "id" && !f.isRelation
4842
- );
4843
- if (!idField) return orderBy;
4844
- if (hasIdInOrderBy(orderBy, fromAlias)) return orderBy;
4845
- const t = col(fromAlias, "id", model) + " ASC";
4846
- return isNonEmptyString(orderBy) ? orderBy + ", " + t : t;
4847
- }
4848
- function ensurePostgresDistinctOrderBy(args) {
4849
- const { orderBy, distinct, fromAlias, model } = args;
4850
- const distinctTerms = distinct.map((f) => col(fromAlias, f, model) + " ASC");
4851
- const existing = splitOrderByTerms(orderBy);
4852
- const canKeepAsIs = existing.length >= distinctTerms.length && distinctTerms.every(
4853
- (term, i) => existing[i].toLowerCase().startsWith(term.split(" ASC")[0].toLowerCase())
4854
- );
4855
- const merged = canKeepAsIs ? orderBy : [...distinctTerms, ...existing].join(SQL_SEPARATORS.ORDER_BY);
4856
- return ensureIdTiebreakerOrderBy(merged, fromAlias, model);
4857
- }
4858
4869
  function constructFinalSql(spec) {
4859
4870
  const {
4860
4871
  select,
@@ -4869,7 +4880,6 @@ function constructFinalSql(spec) {
4869
4880
  params,
4870
4881
  dialect,
4871
4882
  model,
4872
- includes,
4873
4883
  schemas,
4874
4884
  pagination,
4875
4885
  args
@@ -4881,7 +4891,24 @@ function constructFinalSql(spec) {
4881
4891
  const includeSpec = extractIncludeSpec(args);
4882
4892
  const hasIncludes = hasNestedIncludes(includeSpec);
4883
4893
  const hasPagination = isNotNullish(pagination.take);
4884
- const shouldUseFlatJoin = dialect === "postgres" && hasPagination && hasIncludes && canUseFlatJoinForAll(includeSpec);
4894
+ const takeValue = typeof pagination.take === "number" ? pagination.take : null;
4895
+ const isLargeTake = takeValue !== null && takeValue > 50;
4896
+ const shouldUseArrayAgg = dialect === "postgres" && hasIncludes && method === "findMany" && hasPagination && isLargeTake && canUseArrayAggForAll(includeSpec, model, schemas);
4897
+ if (shouldUseArrayAgg) {
4898
+ const aaResult = buildArrayAggSql(spec);
4899
+ if (aaResult.sql) {
4900
+ const baseSqlResult = finalizeSql(aaResult.sql, params, dialect);
4901
+ return {
4902
+ sql: baseSqlResult.sql,
4903
+ params: baseSqlResult.params,
4904
+ paramMappings: baseSqlResult.paramMappings,
4905
+ requiresReduction: true,
4906
+ includeSpec: aaResult.includeSpec,
4907
+ isArrayAgg: true
4908
+ };
4909
+ }
4910
+ }
4911
+ const shouldUseFlatJoin = dialect === "postgres" && hasPagination && hasIncludes && canUseFlatJoinForAll(includeSpec, model, schemas);
4885
4912
  if (shouldUseFlatJoin) {
4886
4913
  const flatResult = buildFlatJoinSql(spec);
4887
4914
  if (flatResult.sql) {
@@ -4927,12 +4954,13 @@ function constructFinalSql(spec) {
4927
4954
  pushWhere(parts, conditions);
4928
4955
  let finalOrderBy = orderBy;
4929
4956
  if (dialect === "postgres" && isNonEmptyArray(distinct)) {
4930
- finalOrderBy = ensurePostgresDistinctOrderBy({
4931
- orderBy: orderBy || "",
4957
+ const currentEntries = getOrderByEntries(spec);
4958
+ const mergedEntries = ensurePostgresDistinctOrderEntries({
4959
+ entries: currentEntries.length > 0 ? currentEntries : [],
4932
4960
  distinct: [...distinct],
4933
- fromAlias: from.alias,
4934
4961
  model
4935
4962
  });
4963
+ finalOrderBy = renderOrderBySql(mergedEntries, from.alias, dialect, model);
4936
4964
  }
4937
4965
  if (isNonEmptyString(finalOrderBy))
4938
4966
  parts.push(SQL_TEMPLATES.ORDER_BY, finalOrderBy);
@@ -4940,24 +4968,6 @@ function constructFinalSql(spec) {
4940
4968
  sql = appendPagination(sql, spec);
4941
4969
  return finalizeSql(sql, params, dialect);
4942
4970
  }
4943
- var SELECT_FIELD_REGEX;
4944
- var init_assembly = __esm({
4945
- "src/builder/select/assembly.ts"() {
4946
- init_constants();
4947
- init_sql_utils();
4948
- init_sql_validators();
4949
- init_type_guards();
4950
- init_dynamic_params();
4951
- init_sql_builder_dialect();
4952
- init_includes();
4953
- init_string_builder();
4954
- init_model_field_cache();
4955
- init_pagination();
4956
- init_order_by_utils();
4957
- init_flat_join();
4958
- SELECT_FIELD_REGEX = /^\s*("(?:[^"]|"")+"|[a-z_][a-z0-9_]*)\s*\.\s*("(?:[^"]|"")+"|[a-z_][a-z0-9_]*)(?:\s+AS\s+("(?:[^"]|"")+"|[a-z_][a-z0-9_]*))?\s*$/i;
4959
- }
4960
- });
4961
4971
 
4962
4972
  // src/builder/select.ts
4963
4973
  function normalizeOrderByInput3(orderBy) {
@@ -4976,11 +4986,11 @@ function mapFirstOrderByByField(existing) {
4976
4986
  return m;
4977
4987
  }
4978
4988
  function buildPostgresDistinctOrderBy(distinctFields, existing) {
4979
- var _a;
4989
+ var _a3;
4980
4990
  const firstByField = mapFirstOrderByByField(existing);
4981
4991
  const next = [];
4982
4992
  for (const f of distinctFields) {
4983
- next.push((_a = firstByField.get(f)) != null ? _a : { [f]: "asc" });
4993
+ next.push((_a3 = firstByField.get(f)) != null ? _a3 : { [f]: "asc" });
4984
4994
  }
4985
4995
  const distinctSet = new Set(distinctFields);
4986
4996
  for (const obj of existing) {
@@ -5235,23 +5245,9 @@ function buildSelectSql(input) {
5235
5245
  });
5236
5246
  return constructFinalSql(spec);
5237
5247
  }
5238
- var init_select = __esm({
5239
- "src/builder/select.ts"() {
5240
- init_sql_builder_dialect();
5241
- init_pagination();
5242
- init_assembly();
5243
- init_fields();
5244
- init_includes();
5245
- init_order_by_utils();
5246
- init_param_store();
5247
- init_sql_utils();
5248
- init_type_guards();
5249
- init_field_assertions();
5250
- init_model_field_cache();
5251
- }
5252
- });
5253
5248
 
5254
5249
  // src/builder/shared/comparison-builder.ts
5250
+ var DEFAULT_EXCLUDE_KEYS = /* @__PURE__ */ new Set(["mode"]);
5255
5251
  function buildComparisons(expr, filter, params, dialect, builder, excludeKeys = DEFAULT_EXCLUDE_KEYS) {
5256
5252
  const out = [];
5257
5253
  for (const op in filter) {
@@ -5264,14 +5260,40 @@ function buildComparisons(expr, filter, params, dialect, builder, excludeKeys =
5264
5260
  }
5265
5261
  return out;
5266
5262
  }
5267
- var DEFAULT_EXCLUDE_KEYS;
5268
- var init_comparison_builder = __esm({
5269
- "src/builder/shared/comparison-builder.ts"() {
5270
- DEFAULT_EXCLUDE_KEYS = /* @__PURE__ */ new Set(["mode"]);
5271
- }
5272
- });
5273
5263
 
5274
5264
  // src/builder/aggregates.ts
5265
+ var MAX_NOT_DEPTH2 = 50;
5266
+ var AGGREGATES = [
5267
+ ["_sum", "SUM"],
5268
+ ["_avg", "AVG"],
5269
+ ["_min", "MIN"],
5270
+ ["_max", "MAX"]
5271
+ ];
5272
+ var COMPARISON_OPS = {
5273
+ [Ops.EQUALS]: "=",
5274
+ [Ops.NOT]: "<>",
5275
+ [Ops.GT]: ">",
5276
+ [Ops.GTE]: ">=",
5277
+ [Ops.LT]: "<",
5278
+ [Ops.LTE]: "<="
5279
+ };
5280
+ var HAVING_ALLOWED_OPS = /* @__PURE__ */ new Set([
5281
+ Ops.EQUALS,
5282
+ Ops.NOT,
5283
+ Ops.GT,
5284
+ Ops.GTE,
5285
+ Ops.LT,
5286
+ Ops.LTE,
5287
+ Ops.IN,
5288
+ Ops.NOT_IN
5289
+ ]);
5290
+ var HAVING_FIELD_FIRST_AGG_KEYS = Object.freeze([
5291
+ "_count",
5292
+ "_sum",
5293
+ "_avg",
5294
+ "_min",
5295
+ "_max"
5296
+ ]);
5275
5297
  function hasAnyOwnKey(obj) {
5276
5298
  for (const k in obj) {
5277
5299
  if (Object.prototype.hasOwnProperty.call(obj, k)) return true;
@@ -5779,58 +5801,6 @@ function buildCountSql(whereResult, tableName, alias, argsOrSkip, dialect, model
5779
5801
  paramMappings: sub.paramMappings
5780
5802
  };
5781
5803
  }
5782
- var MAX_NOT_DEPTH2, AGGREGATES, COMPARISON_OPS, HAVING_ALLOWED_OPS, HAVING_FIELD_FIRST_AGG_KEYS;
5783
- var init_aggregates = __esm({
5784
- "src/builder/aggregates.ts"() {
5785
- init_constants();
5786
- init_sql_utils();
5787
- init_param_store();
5788
- init_sql_validators();
5789
- init_type_guards();
5790
- init_sql_builder_dialect();
5791
- init_dynamic_params();
5792
- init_operators_scalar();
5793
- init_field_assertions();
5794
- init_comparison_builder();
5795
- init_pagination();
5796
- init_select();
5797
- init_primary_key_utils();
5798
- init_null_comparison();
5799
- init_in_operator_builder();
5800
- MAX_NOT_DEPTH2 = 50;
5801
- AGGREGATES = [
5802
- ["_sum", "SUM"],
5803
- ["_avg", "AVG"],
5804
- ["_min", "MIN"],
5805
- ["_max", "MAX"]
5806
- ];
5807
- COMPARISON_OPS = {
5808
- [Ops.EQUALS]: "=",
5809
- [Ops.NOT]: "<>",
5810
- [Ops.GT]: ">",
5811
- [Ops.GTE]: ">=",
5812
- [Ops.LT]: "<",
5813
- [Ops.LTE]: "<="
5814
- };
5815
- HAVING_ALLOWED_OPS = /* @__PURE__ */ new Set([
5816
- Ops.EQUALS,
5817
- Ops.NOT,
5818
- Ops.GT,
5819
- Ops.GTE,
5820
- Ops.LT,
5821
- Ops.LTE,
5822
- Ops.IN,
5823
- Ops.NOT_IN
5824
- ]);
5825
- HAVING_FIELD_FIRST_AGG_KEYS = Object.freeze([
5826
- "_count",
5827
- "_sum",
5828
- "_avg",
5829
- "_min",
5830
- "_max"
5831
- ]);
5832
- }
5833
- });
5834
5804
  function safeAlias(input) {
5835
5805
  const raw = String(input).toLowerCase();
5836
5806
  const cleaned = raw.replace(/[^a-z0-9_]/g, "_");
@@ -5846,10 +5816,10 @@ function isPrismaMethod(v) {
5846
5816
  return v === "findMany" || v === "findFirst" || v === "findUnique" || v === "aggregate" || v === "groupBy" || v === "count";
5847
5817
  }
5848
5818
  function resolveMethod(directive) {
5849
- var _a, _b;
5819
+ var _a3, _b;
5850
5820
  const m = directive == null ? void 0 : directive.method;
5851
5821
  if (isPrismaMethod(m)) return m;
5852
- const pm = (_b = (_a = directive == null ? void 0 : directive.query) == null ? void 0 : _a.processed) == null ? void 0 : _b.method;
5822
+ const pm = (_b = (_a3 = directive == null ? void 0 : directive.query) == null ? void 0 : _a3.processed) == null ? void 0 : _b.method;
5853
5823
  if (isPrismaMethod(pm)) return pm;
5854
5824
  return "findMany";
5855
5825
  }
@@ -6010,7 +5980,7 @@ function extractIncludeSpec2(processed, modelDef) {
6010
5980
  return includeSpec;
6011
5981
  }
6012
5982
  function buildAndNormalizeSql(args) {
6013
- var _a;
5983
+ var _a3;
6014
5984
  const {
6015
5985
  method,
6016
5986
  processed,
@@ -6036,13 +6006,15 @@ function buildAndNormalizeSql(args) {
6036
6006
  sqlResult.paramMappings,
6037
6007
  dialect
6038
6008
  );
6039
- const includeSpec = (_a = sqlResult.includeSpec && isPlainObject(sqlResult.includeSpec) ? sqlResult.includeSpec : null) != null ? _a : extractIncludeSpec2(processed, modelDef);
6009
+ const includeSpec = (_a3 = sqlResult.includeSpec && isPlainObject(sqlResult.includeSpec) ? sqlResult.includeSpec : null) != null ? _a3 : extractIncludeSpec2(processed, modelDef);
6040
6010
  const requiresReduction = sqlResult.requiresReduction === true;
6011
+ const isArrayAgg = sqlResult.isArrayAgg === true;
6041
6012
  return {
6042
6013
  sql: normalized.sql,
6043
6014
  paramMappings: normalized.paramMappings,
6044
6015
  requiresReduction,
6045
- includeSpec
6016
+ includeSpec,
6017
+ isArrayAgg
6046
6018
  };
6047
6019
  }
6048
6020
  function finalizeDirective(args) {
@@ -6053,11 +6025,12 @@ function finalizeDirective(args) {
6053
6025
  normalizedMappings,
6054
6026
  dialect,
6055
6027
  requiresReduction,
6056
- includeSpec
6028
+ includeSpec,
6029
+ isArrayAgg
6057
6030
  } = args;
6058
6031
  const params = normalizedMappings.map((m) => {
6059
- var _a;
6060
- return (_a = m.value) != null ? _a : void 0;
6032
+ var _a3;
6033
+ return (_a3 = m.value) != null ? _a3 : void 0;
6061
6034
  });
6062
6035
  validateParamConsistencyByDialect(normalizedSql, params, dialect);
6063
6036
  const { staticParams, dynamicKeys, paramOrder } = buildParamsFromMappings(normalizedMappings);
@@ -6070,6 +6043,7 @@ function finalizeDirective(args) {
6070
6043
  paramMappings: normalizedMappings,
6071
6044
  requiresReduction,
6072
6045
  includeSpec,
6046
+ isArrayAgg,
6073
6047
  originalDirective: directive
6074
6048
  };
6075
6049
  }
@@ -6103,22 +6077,10 @@ function generateSQL(directive) {
6103
6077
  normalizedMappings: built.paramMappings,
6104
6078
  dialect,
6105
6079
  requiresReduction: built.requiresReduction,
6106
- includeSpec: built.includeSpec
6080
+ includeSpec: built.includeSpec,
6081
+ isArrayAgg: built.isArrayAgg
6107
6082
  });
6108
6083
  }
6109
- var init_sql_generator = __esm({
6110
- "src/sql-generator.ts"() {
6111
- init_joins();
6112
- init_select();
6113
- init_aggregates();
6114
- init_sql_builder_dialect();
6115
- init_where();
6116
- init_sql_utils();
6117
- init_constants();
6118
- init_sql_validators();
6119
- init_type_guards();
6120
- }
6121
- });
6122
6084
 
6123
6085
  // src/utils/s3-fifo.ts
6124
6086
  function withDispose(it) {
@@ -6129,222 +6091,217 @@ function withDispose(it) {
6129
6091
  }
6130
6092
  return it;
6131
6093
  }
6132
- function createBoundedCache(maxSize) {
6133
- return new BoundedCache(maxSize);
6134
- }
6135
- var BoundedCache;
6136
- var init_s3_fifo = __esm({
6137
- "src/utils/s3-fifo.ts"() {
6138
- BoundedCache = class {
6139
- constructor(maxSize) {
6140
- this.map = /* @__PURE__ */ new Map();
6141
- this.ghost = /* @__PURE__ */ new Set();
6142
- this.smallHead = null;
6143
- this.smallTail = null;
6144
- this.smallSize = 0;
6145
- this.mainHead = null;
6146
- this.mainTail = null;
6147
- this.mainSize = 0;
6148
- this.maxSize = maxSize;
6149
- this.smallLimit = Math.max(1, Math.floor(maxSize * 0.1));
6150
- this.mainLimit = maxSize - this.smallLimit;
6151
- this.ghostLimit = this.mainLimit;
6152
- }
6153
- get size() {
6154
- return this.map.size;
6155
- }
6156
- get(key) {
6157
- const node = this.map.get(key);
6158
- if (!node) return void 0;
6159
- node.freq = Math.min(node.freq + 1, 3);
6160
- return node.value;
6161
- }
6162
- set(key, value) {
6163
- const existing = this.map.get(key);
6164
- if (existing) {
6165
- existing.value = value;
6166
- return this;
6167
- }
6168
- if (this.ghost.has(key)) {
6169
- this.ghost.delete(key);
6170
- const node2 = this.createNode(key, value, "main");
6171
- this.map.set(key, node2);
6172
- this.pushMain(node2);
6173
- if (this.mainSize > this.mainLimit) this.evictMain();
6174
- return this;
6175
- }
6176
- const node = this.createNode(key, value, "small");
6177
- this.map.set(key, node);
6178
- this.pushSmall(node);
6179
- if (this.size > this.maxSize) {
6180
- if (this.smallSize > this.smallLimit) this.evictSmall();
6181
- else this.evictMain();
6182
- }
6183
- return this;
6184
- }
6185
- has(key) {
6186
- return this.map.has(key);
6187
- }
6188
- delete(key) {
6189
- const node = this.map.get(key);
6190
- if (!node) return false;
6191
- this.map.delete(key);
6192
- this.removeNode(node);
6193
- return true;
6194
- }
6195
- clear() {
6196
- this.map.clear();
6197
- this.ghost.clear();
6198
- this.smallHead = this.smallTail = null;
6199
- this.mainHead = this.mainTail = null;
6200
- this.smallSize = this.mainSize = 0;
6201
- }
6202
- keys() {
6203
- return withDispose(
6204
- (function* (self) {
6205
- for (const key of self.map.keys()) yield key;
6206
- })(this)
6207
- );
6208
- }
6209
- values() {
6210
- return withDispose(
6211
- (function* (self) {
6212
- for (const node of self.map.values()) yield node.value;
6213
- })(this)
6214
- );
6215
- }
6216
- entries() {
6217
- return withDispose(
6218
- (function* (self) {
6219
- for (const [key, node] of self.map.entries())
6220
- yield [key, node.value];
6221
- })(this)
6222
- );
6223
- }
6224
- forEach(callbackfn, thisArg) {
6225
- for (const [key, node] of this.map.entries()) {
6226
- callbackfn.call(thisArg, node.value, key, this);
6227
- }
6228
- }
6229
- [Symbol.iterator]() {
6230
- return this.entries();
6231
- }
6232
- get [Symbol.toStringTag]() {
6233
- return "BoundedCache";
6234
- }
6235
- createNode(key, value, queue) {
6236
- return { key, value, freq: 0, queue, prev: null, next: null };
6237
- }
6238
- pushSmall(node) {
6239
- node.next = this.smallHead;
6240
- node.prev = null;
6241
- if (this.smallHead) this.smallHead.prev = node;
6242
- else this.smallTail = node;
6243
- this.smallHead = node;
6244
- this.smallSize++;
6245
- }
6246
- pushMain(node) {
6247
- node.next = this.mainHead;
6248
- node.prev = null;
6249
- if (this.mainHead) this.mainHead.prev = node;
6250
- else this.mainTail = node;
6251
- this.mainHead = node;
6252
- this.mainSize++;
6253
- }
6254
- popSmall() {
6255
- if (!this.smallTail) return null;
6256
- const node = this.smallTail;
6257
- this.smallTail = node.prev;
6258
- if (this.smallTail) this.smallTail.next = null;
6259
- else this.smallHead = null;
6260
- node.prev = null;
6261
- node.next = null;
6262
- this.smallSize--;
6263
- return node;
6264
- }
6265
- popMain() {
6266
- if (!this.mainTail) return null;
6267
- const node = this.mainTail;
6268
- this.mainTail = node.prev;
6269
- if (this.mainTail) this.mainTail.next = null;
6270
- else this.mainHead = null;
6271
- node.prev = null;
6272
- node.next = null;
6273
- this.mainSize--;
6274
- return node;
6275
- }
6276
- removeNode(node) {
6277
- this.unlinkNode(node);
6278
- if (node.queue === "small") {
6279
- if (node === this.smallHead) this.smallHead = node.next;
6280
- if (node === this.smallTail) this.smallTail = node.prev;
6281
- this.smallSize--;
6282
- } else {
6283
- if (node === this.mainHead) this.mainHead = node.next;
6284
- if (node === this.mainTail) this.mainTail = node.prev;
6285
- this.mainSize--;
6286
- }
6287
- node.prev = null;
6288
- node.next = null;
6289
- }
6290
- unlinkNode(node) {
6291
- if (node.prev) node.prev.next = node.next;
6292
- if (node.next) node.next.prev = node.prev;
6293
- }
6294
- shouldPromoteFromSmall(node) {
6295
- return node.freq > 1;
6296
- }
6297
- shouldRetryInMain(node) {
6298
- return node.freq >= 1;
6299
- }
6300
- promoteToMain(node) {
6301
- node.queue = "main";
6302
- this.pushMain(node);
6303
- }
6304
- addToGhost(key) {
6305
- this.ghost.add(key);
6306
- if (this.ghost.size <= this.ghostLimit) return;
6307
- const firstGhost = this.ghost.values().next().value;
6308
- if (firstGhost !== void 0) this.ghost.delete(firstGhost);
6309
- }
6310
- evictFromCache(node) {
6311
- this.map.delete(node.key);
6312
- }
6313
- evictSmall() {
6314
- while (this.smallSize > 0) {
6315
- const node = this.popSmall();
6316
- if (!node) return;
6317
- if (this.shouldPromoteFromSmall(node)) {
6318
- this.promoteToMain(node);
6319
- if (this.mainSize > this.mainLimit) {
6320
- this.evictMain();
6321
- return;
6322
- }
6323
- continue;
6324
- }
6325
- this.evictFromCache(node);
6326
- this.addToGhost(node.key);
6327
- return;
6328
- }
6329
- }
6330
- evictMain() {
6331
- while (this.mainSize > 0) {
6332
- const node = this.popMain();
6333
- if (!node) return;
6334
- if (this.shouldRetryInMain(node)) {
6335
- node.freq--;
6336
- this.pushMain(node);
6337
- continue;
6338
- }
6339
- this.evictFromCache(node);
6094
+ var BoundedCache = class {
6095
+ constructor(maxSize) {
6096
+ this.map = /* @__PURE__ */ new Map();
6097
+ this.ghost = /* @__PURE__ */ new Set();
6098
+ this.smallHead = null;
6099
+ this.smallTail = null;
6100
+ this.smallSize = 0;
6101
+ this.mainHead = null;
6102
+ this.mainTail = null;
6103
+ this.mainSize = 0;
6104
+ this.maxSize = maxSize;
6105
+ this.smallLimit = Math.max(1, Math.floor(maxSize * 0.1));
6106
+ this.mainLimit = maxSize - this.smallLimit;
6107
+ this.ghostLimit = this.mainLimit;
6108
+ }
6109
+ get size() {
6110
+ return this.map.size;
6111
+ }
6112
+ get(key) {
6113
+ const node = this.map.get(key);
6114
+ if (!node) return void 0;
6115
+ node.freq = Math.min(node.freq + 1, 3);
6116
+ return node.value;
6117
+ }
6118
+ set(key, value) {
6119
+ const existing = this.map.get(key);
6120
+ if (existing) {
6121
+ existing.value = value;
6122
+ return this;
6123
+ }
6124
+ if (this.ghost.has(key)) {
6125
+ this.ghost.delete(key);
6126
+ const node2 = this.createNode(key, value, "main");
6127
+ this.map.set(key, node2);
6128
+ this.pushMain(node2);
6129
+ if (this.mainSize > this.mainLimit) this.evictMain();
6130
+ return this;
6131
+ }
6132
+ const node = this.createNode(key, value, "small");
6133
+ this.map.set(key, node);
6134
+ this.pushSmall(node);
6135
+ if (this.size > this.maxSize) {
6136
+ if (this.smallSize > this.smallLimit) this.evictSmall();
6137
+ else this.evictMain();
6138
+ }
6139
+ return this;
6140
+ }
6141
+ has(key) {
6142
+ return this.map.has(key);
6143
+ }
6144
+ delete(key) {
6145
+ const node = this.map.get(key);
6146
+ if (!node) return false;
6147
+ this.map.delete(key);
6148
+ this.removeNode(node);
6149
+ return true;
6150
+ }
6151
+ clear() {
6152
+ this.map.clear();
6153
+ this.ghost.clear();
6154
+ this.smallHead = this.smallTail = null;
6155
+ this.mainHead = this.mainTail = null;
6156
+ this.smallSize = this.mainSize = 0;
6157
+ }
6158
+ keys() {
6159
+ return withDispose(
6160
+ (function* (self) {
6161
+ for (const key of self.map.keys()) yield key;
6162
+ })(this)
6163
+ );
6164
+ }
6165
+ values() {
6166
+ return withDispose(
6167
+ (function* (self) {
6168
+ for (const node of self.map.values()) yield node.value;
6169
+ })(this)
6170
+ );
6171
+ }
6172
+ entries() {
6173
+ return withDispose(
6174
+ (function* (self) {
6175
+ for (const [key, node] of self.map.entries())
6176
+ yield [key, node.value];
6177
+ })(this)
6178
+ );
6179
+ }
6180
+ forEach(callbackfn, thisArg) {
6181
+ for (const [key, node] of this.map.entries()) {
6182
+ callbackfn.call(thisArg, node.value, key, this);
6183
+ }
6184
+ }
6185
+ [Symbol.iterator]() {
6186
+ return this.entries();
6187
+ }
6188
+ get [Symbol.toStringTag]() {
6189
+ return "BoundedCache";
6190
+ }
6191
+ createNode(key, value, queue) {
6192
+ return { key, value, freq: 0, queue, prev: null, next: null };
6193
+ }
6194
+ pushSmall(node) {
6195
+ node.next = this.smallHead;
6196
+ node.prev = null;
6197
+ if (this.smallHead) this.smallHead.prev = node;
6198
+ else this.smallTail = node;
6199
+ this.smallHead = node;
6200
+ this.smallSize++;
6201
+ }
6202
+ pushMain(node) {
6203
+ node.next = this.mainHead;
6204
+ node.prev = null;
6205
+ if (this.mainHead) this.mainHead.prev = node;
6206
+ else this.mainTail = node;
6207
+ this.mainHead = node;
6208
+ this.mainSize++;
6209
+ }
6210
+ popSmall() {
6211
+ if (!this.smallTail) return null;
6212
+ const node = this.smallTail;
6213
+ this.smallTail = node.prev;
6214
+ if (this.smallTail) this.smallTail.next = null;
6215
+ else this.smallHead = null;
6216
+ node.prev = null;
6217
+ node.next = null;
6218
+ this.smallSize--;
6219
+ return node;
6220
+ }
6221
+ popMain() {
6222
+ if (!this.mainTail) return null;
6223
+ const node = this.mainTail;
6224
+ this.mainTail = node.prev;
6225
+ if (this.mainTail) this.mainTail.next = null;
6226
+ else this.mainHead = null;
6227
+ node.prev = null;
6228
+ node.next = null;
6229
+ this.mainSize--;
6230
+ return node;
6231
+ }
6232
+ removeNode(node) {
6233
+ this.unlinkNode(node);
6234
+ if (node.queue === "small") {
6235
+ if (node === this.smallHead) this.smallHead = node.next;
6236
+ if (node === this.smallTail) this.smallTail = node.prev;
6237
+ this.smallSize--;
6238
+ } else {
6239
+ if (node === this.mainHead) this.mainHead = node.next;
6240
+ if (node === this.mainTail) this.mainTail = node.prev;
6241
+ this.mainSize--;
6242
+ }
6243
+ node.prev = null;
6244
+ node.next = null;
6245
+ }
6246
+ unlinkNode(node) {
6247
+ if (node.prev) node.prev.next = node.next;
6248
+ if (node.next) node.next.prev = node.prev;
6249
+ }
6250
+ shouldPromoteFromSmall(node) {
6251
+ return node.freq > 1;
6252
+ }
6253
+ shouldRetryInMain(node) {
6254
+ return node.freq >= 1;
6255
+ }
6256
+ promoteToMain(node) {
6257
+ node.queue = "main";
6258
+ this.pushMain(node);
6259
+ }
6260
+ addToGhost(key) {
6261
+ this.ghost.add(key);
6262
+ if (this.ghost.size <= this.ghostLimit) return;
6263
+ const firstGhost = this.ghost.values().next().value;
6264
+ if (firstGhost !== void 0) this.ghost.delete(firstGhost);
6265
+ }
6266
+ evictFromCache(node) {
6267
+ this.map.delete(node.key);
6268
+ }
6269
+ evictSmall() {
6270
+ while (this.smallSize > 0) {
6271
+ const node = this.popSmall();
6272
+ if (!node) return;
6273
+ if (this.shouldPromoteFromSmall(node)) {
6274
+ this.promoteToMain(node);
6275
+ if (this.mainSize > this.mainLimit) {
6276
+ this.evictMain();
6340
6277
  return;
6341
6278
  }
6279
+ continue;
6342
6280
  }
6343
- };
6281
+ this.evictFromCache(node);
6282
+ this.addToGhost(node.key);
6283
+ return;
6284
+ }
6344
6285
  }
6345
- });
6346
-
6347
- // src/fast-path.ts
6286
+ evictMain() {
6287
+ while (this.mainSize > 0) {
6288
+ const node = this.popMain();
6289
+ if (!node) return;
6290
+ if (this.shouldRetryInMain(node)) {
6291
+ node.freq--;
6292
+ this.pushMain(node);
6293
+ continue;
6294
+ }
6295
+ this.evictFromCache(node);
6296
+ return;
6297
+ }
6298
+ }
6299
+ };
6300
+ function createBoundedCache(maxSize) {
6301
+ return new BoundedCache(maxSize);
6302
+ }
6303
+
6304
+ // src/fast-path.ts
6348
6305
  function getIdField(model) {
6349
6306
  const idField = model.fields.find((f) => f.name === "id" && !f.isRelation);
6350
6307
  if (!idField) return null;
@@ -6504,17 +6461,36 @@ function tryFastPath(model, method, args, dialect) {
6504
6461
  }
6505
6462
  return null;
6506
6463
  }
6507
- var init_fast_path = __esm({
6508
- "src/fast-path.ts"() {
6509
- init_sql_utils();
6510
- init_constants();
6511
- init_type_guards();
6512
- init_normalize_value();
6513
- init_query_cache();
6514
- }
6515
- });
6516
6464
 
6517
6465
  // src/query-cache.ts
6466
+ var _hits, _misses;
6467
+ var QueryCacheStats = class {
6468
+ constructor() {
6469
+ __privateAdd(this, _hits, 0);
6470
+ __privateAdd(this, _misses, 0);
6471
+ }
6472
+ hit() {
6473
+ __privateWrapper(this, _hits)._++;
6474
+ }
6475
+ miss() {
6476
+ __privateWrapper(this, _misses)._++;
6477
+ }
6478
+ reset() {
6479
+ __privateSet(this, _hits, 0);
6480
+ __privateSet(this, _misses, 0);
6481
+ }
6482
+ get snapshot() {
6483
+ return Object.freeze({
6484
+ hits: __privateGet(this, _hits),
6485
+ misses: __privateGet(this, _misses),
6486
+ size: queryCache.size
6487
+ });
6488
+ }
6489
+ };
6490
+ _hits = new WeakMap();
6491
+ _misses = new WeakMap();
6492
+ var queryCache = createBoundedCache(1e3);
6493
+ var queryCacheStats = new QueryCacheStats();
6518
6494
  function makeAlias(name) {
6519
6495
  const base = name.toLowerCase().replace(/[^a-z0-9_]/g, "_").slice(0, 50);
6520
6496
  const safe = /^[a-z_]/.test(base) ? base : `_${base}`;
@@ -6709,7 +6685,8 @@ function buildSQLFull(model, models, method, args, dialect) {
6709
6685
  return __spreadProps(__spreadValues({}, sqlResult), {
6710
6686
  paramMappings: result.paramMappings,
6711
6687
  requiresReduction: result.requiresReduction,
6712
- includeSpec: result.includeSpec
6688
+ includeSpec: result.includeSpec,
6689
+ isArrayAgg: result.isArrayAgg
6713
6690
  });
6714
6691
  }
6715
6692
  function buildSQLWithCache(model, models, method, args, dialect) {
@@ -6722,7 +6699,8 @@ function buildSQLWithCache(model, models, method, args, dialect) {
6722
6699
  params: [...cached.params],
6723
6700
  paramMappings: cached.paramMappings,
6724
6701
  requiresReduction: cached.requiresReduction,
6725
- includeSpec: cached.includeSpec
6702
+ includeSpec: cached.includeSpec,
6703
+ isArrayAgg: cached.isArrayAgg
6726
6704
  };
6727
6705
  }
6728
6706
  queryCacheStats.miss();
@@ -6740,77 +6718,104 @@ function buildSQLWithCache(model, models, method, args, dialect) {
6740
6718
  params: [...result.params],
6741
6719
  paramMappings: result.paramMappings,
6742
6720
  requiresReduction: result.requiresReduction,
6743
- includeSpec: result.includeSpec
6721
+ includeSpec: result.includeSpec,
6722
+ isArrayAgg: result.isArrayAgg
6744
6723
  });
6745
6724
  return result;
6746
6725
  }
6747
- var _hits, _misses, QueryCacheStats, queryCache, queryCacheStats;
6748
- var init_query_cache = __esm({
6749
- "src/query-cache.ts"() {
6750
- init_where();
6751
- init_select();
6752
- init_aggregates();
6753
- init_sql_utils();
6754
- init_constants();
6755
- init_s3_fifo();
6756
- init_fast_path();
6757
- QueryCacheStats = class {
6758
- constructor() {
6759
- __privateAdd(this, _hits, 0);
6760
- __privateAdd(this, _misses, 0);
6761
- }
6762
- hit() {
6763
- __privateWrapper(this, _hits)._++;
6764
- }
6765
- miss() {
6766
- __privateWrapper(this, _misses)._++;
6726
+
6727
+ // src/builder/select/row-transformers.ts
6728
+ function transformAggregateRow(row) {
6729
+ if (!row || typeof row !== "object") return row;
6730
+ const result = {};
6731
+ for (const key in row) {
6732
+ if (!Object.prototype.hasOwnProperty.call(row, key)) continue;
6733
+ let value = row[key];
6734
+ if (typeof value === "string" && /^-?\d+(\.\d+)?$/.test(value)) {
6735
+ value = value.includes(".") ? parseFloat(value) : parseInt(value, 10);
6736
+ }
6737
+ const dotIndex = key.indexOf(".");
6738
+ if (dotIndex === -1) {
6739
+ result[key] = value;
6740
+ continue;
6741
+ }
6742
+ const prefix = key.slice(0, dotIndex);
6743
+ const suffix = key.slice(dotIndex + 1);
6744
+ if (AGGREGATE_PREFIXES.has(prefix)) {
6745
+ if (!result[prefix]) {
6746
+ result[prefix] = {};
6767
6747
  }
6768
- reset() {
6769
- __privateSet(this, _hits, 0);
6770
- __privateSet(this, _misses, 0);
6748
+ result[prefix][suffix] = value;
6749
+ } else {
6750
+ result[key] = value;
6751
+ }
6752
+ }
6753
+ return result;
6754
+ }
6755
+ function extractCountValue(row) {
6756
+ if (!row || typeof row !== "object") return 0;
6757
+ if ("_count._all" in row) {
6758
+ const value = row["_count._all"];
6759
+ if (typeof value === "string") return parseInt(value, 10);
6760
+ return value;
6761
+ }
6762
+ if ("_count" in row && row["_count"] && typeof row["_count"] === "object") {
6763
+ const countObj = row["_count"];
6764
+ if ("_all" in countObj) {
6765
+ const value = countObj["_all"];
6766
+ if (typeof value === "string") return parseInt(value, 10);
6767
+ return value;
6768
+ }
6769
+ }
6770
+ const keys = Object.keys(row);
6771
+ for (const key of keys) {
6772
+ if (key.includes("count") || key.includes("COUNT")) {
6773
+ const value = row[key];
6774
+ if (typeof value === "number" || typeof value === "bigint") {
6775
+ return value;
6771
6776
  }
6772
- get snapshot() {
6773
- return Object.freeze({
6774
- hits: __privateGet(this, _hits),
6775
- misses: __privateGet(this, _misses),
6776
- size: queryCache.size
6777
- });
6777
+ if (typeof value === "string") {
6778
+ return parseInt(value, 10);
6778
6779
  }
6779
- };
6780
- _hits = new WeakMap();
6781
- _misses = new WeakMap();
6782
- queryCache = createBoundedCache(1e3);
6783
- queryCacheStats = new QueryCacheStats();
6780
+ }
6784
6781
  }
6785
- });
6782
+ return 0;
6783
+ }
6784
+ function getRowTransformer(method) {
6785
+ if (method === "count") {
6786
+ return extractCountValue;
6787
+ }
6788
+ if (method === "groupBy" || method === "aggregate") {
6789
+ return transformAggregateRow;
6790
+ }
6791
+ return null;
6792
+ }
6786
6793
 
6787
6794
  // src/result-transformers.ts
6788
6795
  function transformQueryResults(method, results) {
6789
- var _a;
6796
+ var _a3, _b;
6790
6797
  if (method === "findFirst" || method === "findUnique") {
6791
6798
  if (Array.isArray(results)) {
6792
- return (_a = results[0]) != null ? _a : null;
6799
+ return (_a3 = results[0]) != null ? _a3 : null;
6800
+ }
6801
+ }
6802
+ if (method === "aggregate") {
6803
+ if (Array.isArray(results)) {
6804
+ return (_b = results[0]) != null ? _b : null;
6793
6805
  }
6794
6806
  }
6795
6807
  if (method === "count") {
6796
6808
  if (Array.isArray(results) && results.length > 0) {
6797
- const row = results[0];
6798
- if (typeof row === "number" || typeof row === "bigint") {
6799
- return row;
6800
- }
6801
- if (row && typeof row === "object" && "_count._all" in row) {
6802
- return row["_count._all"];
6809
+ const first = results[0];
6810
+ if (typeof first === "number" || typeof first === "bigint") {
6811
+ return first;
6803
6812
  }
6804
- return row;
6813
+ return extractCountValue(first);
6805
6814
  }
6806
6815
  return 0;
6807
6816
  }
6808
6817
  return results;
6809
6818
  }
6810
- var init_result_transformers = __esm({
6811
- "src/result-transformers.ts"() {
6812
- }
6813
- });
6814
6819
 
6815
6820
  // src/batch.ts
6816
6821
  function quoteBatchIdent(id) {
@@ -7038,9 +7043,9 @@ function wrapQueryForMethod(method, cteName, resultAlias) {
7038
7043
  }
7039
7044
  }
7040
7045
  function isAllCountQueries(queries, keys) {
7041
- var _a;
7046
+ var _a3;
7042
7047
  for (const key of keys) {
7043
- if (((_a = queries[key]) == null ? void 0 : _a.method) !== "count") return false;
7048
+ if (((_a3 = queries[key]) == null ? void 0 : _a3.method) !== "count") return false;
7044
7049
  }
7045
7050
  return true;
7046
7051
  }
@@ -7279,8 +7284,8 @@ function buildMergedCountBatchSql(queries, keys, aliasesByKey, modelMap, models,
7279
7284
  const fromSql = rewrittenSubs.join(" CROSS JOIN ");
7280
7285
  const sql = `SELECT ${selectParts.join(", ")} FROM ${fromSql}`;
7281
7286
  const aliases = keys.map((k) => {
7282
- var _a;
7283
- return (_a = aliasesByKey.get(k)) != null ? _a : "";
7287
+ var _a3;
7288
+ return (_a3 = aliasesByKey.get(k)) != null ? _a3 : "";
7284
7289
  });
7285
7290
  return { sql, params: finalParams, keys, aliases };
7286
7291
  }
@@ -7457,12 +7462,29 @@ function parseCountValue(value) {
7457
7462
  }
7458
7463
  return 0;
7459
7464
  }
7460
- function parseBatchCountResults(row, count) {
7465
+ function parseBatchCountResults(row, queryCount) {
7461
7466
  const results = [];
7462
- for (let i = 0; i < count; i++) {
7463
- const key = `count_${i}`;
7467
+ for (let i = 0; i < queryCount; i++) {
7468
+ const key = `_count_${i}`;
7464
7469
  const value = row[key];
7465
- results.push(parseCountValue(value));
7470
+ if (value === null || value === void 0) {
7471
+ results.push(0);
7472
+ continue;
7473
+ }
7474
+ if (typeof value === "number") {
7475
+ results.push(value);
7476
+ continue;
7477
+ }
7478
+ if (typeof value === "bigint") {
7479
+ results.push(Number(value));
7480
+ continue;
7481
+ }
7482
+ if (typeof value === "string") {
7483
+ const parsed = parseInt(value, 10);
7484
+ results.push(isNaN(parsed) ? 0 : parsed);
7485
+ continue;
7486
+ }
7487
+ results.push(0);
7466
7488
  }
7467
7489
  return results;
7468
7490
  }
@@ -7631,11 +7653,11 @@ function parseBatchValue(rawValue, method, modelName, modelMap) {
7631
7653
  }
7632
7654
  }
7633
7655
  function parseBatchResults(row, keys, queries, aliases, modelMap) {
7634
- var _a;
7656
+ var _a3;
7635
7657
  const results = {};
7636
7658
  for (let i = 0; i < keys.length; i++) {
7637
7659
  const key = keys[i];
7638
- const columnKey = (_a = aliases == null ? void 0 : aliases[i]) != null ? _a : key;
7660
+ const columnKey = (_a3 = aliases == null ? void 0 : aliases[i]) != null ? _a3 : key;
7639
7661
  const rawValue = row[columnKey];
7640
7662
  const query = queries[key];
7641
7663
  results[key] = parseBatchValue(
@@ -7647,13 +7669,6 @@ function parseBatchResults(row, keys, queries, aliases, modelMap) {
7647
7669
  }
7648
7670
  return results;
7649
7671
  }
7650
- var init_batch = __esm({
7651
- "src/batch.ts"() {
7652
- init_query_cache();
7653
- init_result_transformers();
7654
- init_sql_utils();
7655
- }
7656
- });
7657
7672
 
7658
7673
  // src/transaction.ts
7659
7674
  function isolationLevelToPostgresKeyword(level) {
@@ -7724,7 +7739,11 @@ function createTransactionExecutor(deps) {
7724
7739
  q.args || {},
7725
7740
  dialect
7726
7741
  );
7727
- const rawResults = yield sql.unsafe(sqlStr, params);
7742
+ let rawResults = yield sql.unsafe(sqlStr, params);
7743
+ const rowTransformer = getRowTransformer(q.method);
7744
+ if (rowTransformer && Array.isArray(rawResults)) {
7745
+ rawResults = rawResults.map(rowTransformer);
7746
+ }
7728
7747
  results.push(transformQueryResults(q.method, rawResults));
7729
7748
  }
7730
7749
  return results;
@@ -7734,50 +7753,23 @@ function createTransactionExecutor(deps) {
7734
7753
  }
7735
7754
  };
7736
7755
  }
7737
- var init_transaction = __esm({
7738
- "src/transaction.ts"() {
7739
- init_query_cache();
7740
- init_result_transformers();
7741
- }
7742
- });
7743
7756
 
7744
7757
  // src/builder/shared/key-utils.ts
7745
- function buildCompositeKey(row, fields) {
7758
+ function buildKey(row, fields) {
7746
7759
  if (fields.length === 0) return null;
7747
7760
  if (fields.length === 1) {
7748
7761
  const val = row[fields[0]];
7749
- if (val == null) return null;
7750
- const t = typeof val;
7751
- if (t === "string") return `s:${val}`;
7752
- if (t === "number") return Number.isFinite(val) ? `n:${val}` : null;
7753
- if (t === "boolean") return val ? "b:1" : "b:0";
7754
- if (t === "bigint") return `i:${val}`;
7755
- return `o:${val}`;
7756
- }
7757
- const parts = new Array(fields.length);
7762
+ return val == null ? null : val;
7763
+ }
7764
+ let key = "";
7758
7765
  for (let i = 0; i < fields.length; i++) {
7759
7766
  const val = row[fields[i]];
7760
7767
  if (val == null) return null;
7761
- const t = typeof val;
7762
- if (t === "string") {
7763
- parts[i] = `s:${val}`;
7764
- } else if (t === "number") {
7765
- if (!Number.isFinite(val)) return null;
7766
- parts[i] = `n:${val}`;
7767
- } else if (t === "boolean") {
7768
- parts[i] = val ? "b:1" : "b:0";
7769
- } else if (t === "bigint") {
7770
- parts[i] = `i:${val}`;
7771
- } else {
7772
- parts[i] = `o:${val}`;
7773
- }
7768
+ if (i > 0) key += "";
7769
+ key += typeof val === "string" ? val : String(val);
7774
7770
  }
7775
- return parts.join("");
7771
+ return key;
7776
7772
  }
7777
- var init_key_utils = __esm({
7778
- "src/builder/shared/key-utils.ts"() {
7779
- }
7780
- });
7781
7773
 
7782
7774
  // src/builder/select/reducer.ts
7783
7775
  function buildRelationScalarCols(relModel, relPath, includeAllScalars, selectedScalarFields) {
@@ -7793,6 +7785,14 @@ function buildRelationScalarCols(relModel, relPath, includeAllScalars, selectedS
7793
7785
  }
7794
7786
  return out;
7795
7787
  }
7788
+ function extractChildLimit(relArgs) {
7789
+ if (!isPlainObject(relArgs)) return void 0;
7790
+ const obj = relArgs;
7791
+ if ("take" in obj && typeof obj.take === "number" && obj.take > 0) {
7792
+ return obj.take;
7793
+ }
7794
+ return void 0;
7795
+ }
7796
7796
  function buildReducerConfig(parentModel, includeSpec, allModels, prefix = "", depth = 0) {
7797
7797
  if (depth > 10) {
7798
7798
  throw new Error(
@@ -7815,7 +7815,7 @@ function buildReducerConfig(parentModel, includeSpec, allModels, prefix = "", de
7815
7815
  `Related model '${field.relatedModel}' not found for relation '${incName}'`
7816
7816
  );
7817
7817
  }
7818
- const isList2 = typeof field.type === "string" && field.type.endsWith("[]");
7818
+ const isList = typeof field.type === "string" && field.type.endsWith("[]");
7819
7819
  const primaryKeyFields = getPrimaryKeyFields(relatedModel);
7820
7820
  const scalarSel = extractScalarSelection(incValue, relatedModel);
7821
7821
  const relPath = prefix ? `${prefix}.${incName}` : incName;
@@ -7837,14 +7837,16 @@ function buildReducerConfig(parentModel, includeSpec, allModels, prefix = "", de
7837
7837
  scalarSel.includeAllScalars,
7838
7838
  scalarSel.selectedScalarFields
7839
7839
  );
7840
+ const childLimit = isList ? extractChildLimit(incValue) : void 0;
7840
7841
  includedRelations.push({
7841
7842
  name: incName,
7842
- cardinality: isList2 ? "many" : "one",
7843
+ cardinality: isList ? "many" : "one",
7843
7844
  relatedModel,
7844
7845
  primaryKeyFields,
7845
7846
  includeAllScalars: scalarSel.includeAllScalars,
7846
7847
  selectedScalarFields: scalarSel.selectedScalarFields,
7847
7848
  nestedIncludes,
7849
+ childLimit,
7848
7850
  path: relPath,
7849
7851
  keyCols,
7850
7852
  scalarCols
@@ -7876,7 +7878,7 @@ function initNestedPlaceholders(obj, nested) {
7876
7878
  }
7877
7879
  }
7878
7880
  function materializeRelationObject(row, rel) {
7879
- const relKey = buildCompositeKey(row, rel.keyCols);
7881
+ const relKey = buildKey(row, rel.keyCols);
7880
7882
  if (relKey == null) return null;
7881
7883
  const obj = {};
7882
7884
  for (const c of rel.scalarCols) {
@@ -7892,7 +7894,7 @@ function processNestedRelations(obj, rel, row, manyStore) {
7892
7894
  }
7893
7895
  }
7894
7896
  function processRelation(parentObj, rel, row, manyStore) {
7895
- const relKey = buildCompositeKey(row, rel.keyCols);
7897
+ const relKey = buildKey(row, rel.keyCols);
7896
7898
  if (relKey == null) return;
7897
7899
  if (rel.cardinality === "one") {
7898
7900
  let current = parentObj[rel.name];
@@ -7906,6 +7908,9 @@ function processRelation(parentObj, rel, row, manyStore) {
7906
7908
  return;
7907
7909
  }
7908
7910
  const arr = parentObj[rel.name];
7911
+ if (rel.childLimit && arr.length >= rel.childLimit) {
7912
+ return;
7913
+ }
7909
7914
  const idx = getIndexForParent(manyStore, parentObj, rel.path);
7910
7915
  const existing = idx.get(relKey);
7911
7916
  if (existing) {
@@ -7939,7 +7944,7 @@ function reduceFlatRows(rows, config) {
7939
7944
  const manyStore = /* @__PURE__ */ new WeakMap();
7940
7945
  for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
7941
7946
  const row = rows[rowIdx];
7942
- const parentKey = buildCompositeKey(row, parentKeyCols);
7947
+ const parentKey = buildKey(row, parentKeyCols);
7943
7948
  if (parentKey == null) continue;
7944
7949
  let record = resultMap.get(parentKey);
7945
7950
  if (!record) {
@@ -7962,18 +7967,9 @@ function reduceFlatRows(rows, config) {
7962
7967
  }
7963
7968
  return Array.from(resultMap.values());
7964
7969
  }
7965
- var init_reducer = __esm({
7966
- "src/builder/select/reducer.ts"() {
7967
- init_model_field_cache();
7968
- init_primary_key_utils();
7969
- init_key_utils();
7970
- init_model_field_cache();
7971
- init_relation_utils();
7972
- }
7973
- });
7974
7970
 
7975
7971
  // src/builder/select/segment-planner.ts
7976
- function isList(field) {
7972
+ function isListField(field) {
7977
7973
  return typeof field.type === "string" && field.type.endsWith("[]");
7978
7974
  }
7979
7975
  function resolveRelation(model, relName, allModels) {
@@ -7983,47 +7979,6 @@ function resolveRelation(model, relName, allModels) {
7983
7979
  if (!relModel) return null;
7984
7980
  return { field, relModel };
7985
7981
  }
7986
- function effectiveFanout(stats) {
7987
- return 1 + stats.coverage * (stats.avg - 1);
7988
- }
7989
- function estimateFlatRows(parentCount, relations, stats) {
7990
- var _a;
7991
- let rows = parentCount;
7992
- for (const rel of relations) {
7993
- const relStats = (_a = stats == null ? void 0 : stats[rel.modelName]) == null ? void 0 : _a[rel.relName];
7994
- const fanout = relStats ? effectiveFanout(relStats) : 10;
7995
- const next = rows * fanout;
7996
- if (next > MAX_ESTIMATED_ROWS) {
7997
- return MAX_ESTIMATED_ROWS;
7998
- }
7999
- rows = next;
8000
- }
8001
- return Math.ceil(rows);
8002
- }
8003
- function collectOneToManyRelations(entries, model, allModels) {
8004
- const out = [];
8005
- for (const entry of entries) {
8006
- const resolved = resolveRelation(model, entry.name, allModels);
8007
- if (!resolved) continue;
8008
- if (!isList(resolved.field)) continue;
8009
- out.push({
8010
- name: entry.name,
8011
- relArgs: entry.value,
8012
- field: resolved.field,
8013
- relModel: resolved.relModel,
8014
- hasPagination: hasChildPagination(entry.value)
8015
- });
8016
- }
8017
- return out;
8018
- }
8019
- function getParentCount(method, args) {
8020
- if (method === "findFirst" || method === "findUnique") return 1;
8021
- if ((args == null ? void 0 : args.take) !== void 0 && (args == null ? void 0 : args.take) !== null) {
8022
- const take = typeof args.take === "number" ? Math.abs(args.take) : null;
8023
- if (take !== null) return take;
8024
- }
8025
- return null;
8026
- }
8027
7982
  function buildWhereInSegment(name, relArgs, field, relModel) {
8028
7983
  const keys = resolveRelationKeys(field, "whereIn");
8029
7984
  if (keys.childKeys.length !== 1) return null;
@@ -8033,7 +7988,7 @@ function buildWhereInSegment(name, relArgs, field, relModel) {
8033
7988
  childModelName: relModel.name,
8034
7989
  fkFieldName: keys.childKeys[0],
8035
7990
  parentKeyFieldName: keys.parentKeys[0],
8036
- isList: true
7991
+ isList: isListField(field)
8037
7992
  };
8038
7993
  }
8039
7994
  function deepClone(obj) {
@@ -8067,85 +8022,154 @@ function removeRelationsFromArgs(args, names) {
8067
8022
  }
8068
8023
  return filtered;
8069
8024
  }
8025
+ function ensureParentKeysInSelect(args, segments) {
8026
+ if (!(args == null ? void 0 : args.select)) return { args, injectedKeys: [] };
8027
+ const injected = [];
8028
+ const newSelect = __spreadValues({}, args.select);
8029
+ for (const seg of segments) {
8030
+ if (!newSelect[seg.parentKeyFieldName]) {
8031
+ newSelect[seg.parentKeyFieldName] = true;
8032
+ injected.push(seg.parentKeyFieldName);
8033
+ }
8034
+ }
8035
+ if (injected.length === 0) return { args, injectedKeys: [] };
8036
+ return { args: __spreadProps(__spreadValues({}, args), { select: newSelect }), injectedKeys: injected };
8037
+ }
8070
8038
  function planQueryStrategy(params) {
8071
- const { model, method, args, allModels, relationStats } = params;
8039
+ const { model, args, allModels } = params;
8040
+ const emptyPlan = {
8041
+ filteredArgs: args,
8042
+ whereInSegments: [],
8043
+ injectedParentKeys: []
8044
+ };
8072
8045
  const entries = extractRelationEntries(args, model);
8073
8046
  if (entries.length === 0) {
8074
- return { filteredArgs: args, whereInSegments: [] };
8047
+ return emptyPlan;
8075
8048
  }
8076
- const oneToManyRels = collectOneToManyRelations(entries, model, allModels);
8077
- const unpaginatedOneToMany = oneToManyRels.filter((r) => !r.hasPagination);
8078
- if (unpaginatedOneToMany.length === 0) {
8079
- return { filteredArgs: args, whereInSegments: [] };
8080
- }
8081
- const parentCount = getParentCount(method, args);
8082
8049
  const whereInSegments = [];
8083
8050
  const toRemove = /* @__PURE__ */ new Set();
8084
- if (unpaginatedOneToMany.length > 1) {
8085
- for (const rel of unpaginatedOneToMany) {
8086
- const segment = buildWhereInSegment(
8087
- rel.name,
8088
- rel.relArgs,
8089
- rel.field,
8090
- rel.relModel
8091
- );
8092
- if (segment) {
8093
- whereInSegments.push(segment);
8094
- toRemove.add(rel.name);
8095
- }
8051
+ for (const entry of entries) {
8052
+ const resolved = resolveRelation(model, entry.name, allModels);
8053
+ if (!resolved) continue;
8054
+ if (isListField(resolved.field) && hasChildPagination(entry.value)) {
8055
+ continue;
8096
8056
  }
8097
- } else if (unpaginatedOneToMany.length === 1) {
8098
- const rel = unpaginatedOneToMany[0];
8099
- if (parentCount === null) {
8100
- const segment = buildWhereInSegment(
8101
- rel.name,
8102
- rel.relArgs,
8103
- rel.field,
8104
- rel.relModel
8105
- );
8106
- if (segment) {
8107
- whereInSegments.push(segment);
8108
- toRemove.add(rel.name);
8109
- }
8110
- } else {
8111
- const estimated = estimateFlatRows(
8112
- parentCount,
8113
- [{ modelName: model.name, relName: rel.name, field: rel.field }],
8114
- relationStats
8115
- );
8116
- if (estimated > HARD_FANOUT_CAP) {
8117
- const segment = buildWhereInSegment(
8118
- rel.name,
8119
- rel.relArgs,
8120
- rel.field,
8121
- rel.relModel
8122
- );
8123
- if (segment) {
8124
- whereInSegments.push(segment);
8125
- toRemove.add(rel.name);
8126
- }
8127
- }
8057
+ const segment = buildWhereInSegment(
8058
+ entry.name,
8059
+ entry.value,
8060
+ resolved.field,
8061
+ resolved.relModel
8062
+ );
8063
+ if (segment) {
8064
+ whereInSegments.push(segment);
8065
+ toRemove.add(entry.name);
8128
8066
  }
8129
8067
  }
8130
8068
  if (toRemove.size === 0) {
8131
- return { filteredArgs: args, whereInSegments: [] };
8069
+ return emptyPlan;
8132
8070
  }
8133
8071
  const filteredArgs = removeRelationsFromArgs(args, toRemove);
8134
- return { filteredArgs, whereInSegments };
8135
- }
8136
- var HARD_FANOUT_CAP, MAX_ESTIMATED_ROWS;
8137
- var init_segment_planner = __esm({
8138
- "src/builder/select/segment-planner.ts"() {
8139
- init_type_guards();
8140
- init_relation_extraction_utils();
8141
- init_relation_key_utils();
8142
- init_relation_utils();
8143
- HARD_FANOUT_CAP = 5e3;
8144
- MAX_ESTIMATED_ROWS = Number.MAX_SAFE_INTEGER / 1e3;
8072
+ const { args: finalArgs, injectedKeys } = ensureParentKeysInSelect(
8073
+ filteredArgs,
8074
+ whereInSegments
8075
+ );
8076
+ return {
8077
+ filteredArgs: finalArgs,
8078
+ whereInSegments,
8079
+ injectedParentKeys: injectedKeys
8080
+ };
8081
+ }
8082
+
8083
+ // src/builder/select/array-agg-reducer.ts
8084
+ function buildArrayAggReducerConfig(parentModel, includeSpec, allModels) {
8085
+ const modelMap = new Map(allModels.map((m) => [m.name, m]));
8086
+ const parentJsonSet = getJsonFieldSet(parentModel);
8087
+ const parentScalarFields = getScalarFieldNames(parentModel);
8088
+ const relations = [];
8089
+ for (const [relName, relValue] of Object.entries(includeSpec)) {
8090
+ if (relValue === false) continue;
8091
+ const field = parentModel.fields.find((f) => f.name === relName);
8092
+ if (!field || !field.isRelation || !field.relatedModel) continue;
8093
+ const relModel = modelMap.get(field.relatedModel);
8094
+ if (!relModel) continue;
8095
+ const isList = typeof field.type === "string" && field.type.endsWith("[]");
8096
+ const indices = getFieldIndices(relModel);
8097
+ const scalarSel = extractScalarSelection(relValue, relModel);
8098
+ const pkFields = getPrimaryKeyFields(relModel);
8099
+ const relJsonSet = getJsonFieldSet(relModel);
8100
+ const selectedFields = scalarSel.includeAllScalars ? Array.from(indices.scalarFields.keys()) : [.../* @__PURE__ */ new Set([...pkFields, ...scalarSel.selectedScalarFields])];
8101
+ const scalarCols = selectedFields.map((fieldName) => {
8102
+ const f = indices.scalarFields.get(fieldName);
8103
+ if (!f) return null;
8104
+ return {
8105
+ fieldName: f.name,
8106
+ colName: `${relName}.${f.name}`,
8107
+ isJson: relJsonSet.has(f.name)
8108
+ };
8109
+ }).filter(Boolean);
8110
+ relations.push({
8111
+ name: relName,
8112
+ isList,
8113
+ scalarFields: scalarCols,
8114
+ pkFieldName: pkFields[0]
8115
+ });
8145
8116
  }
8146
- });
8117
+ return {
8118
+ parentModel,
8119
+ parentScalarFields,
8120
+ parentJsonSet,
8121
+ relations
8122
+ };
8123
+ }
8124
+ function reduceArrayAggRows(rows, config) {
8125
+ var _a3;
8126
+ if (rows.length === 0) return [];
8127
+ const { parentScalarFields, parentJsonSet, relations } = config;
8128
+ const results = new Array(rows.length);
8129
+ for (let i = 0; i < rows.length; i++) {
8130
+ const row = rows[i];
8131
+ const record = {};
8132
+ for (const fieldName of parentScalarFields) {
8133
+ if (!(fieldName in row)) continue;
8134
+ record[fieldName] = maybeParseJson(
8135
+ row[fieldName],
8136
+ parentJsonSet,
8137
+ fieldName
8138
+ );
8139
+ }
8140
+ for (const rel of relations) {
8141
+ const firstCol = rel.scalarFields[0];
8142
+ if (!firstCol) {
8143
+ record[rel.name] = rel.isList ? [] : null;
8144
+ continue;
8145
+ }
8146
+ const arr = row[firstCol.colName];
8147
+ if (!Array.isArray(arr) || arr.length === 0) {
8148
+ record[rel.name] = rel.isList ? [] : null;
8149
+ continue;
8150
+ }
8151
+ const len = arr.length;
8152
+ const children = new Array(len);
8153
+ for (let j = 0; j < len; j++) {
8154
+ const child = {};
8155
+ for (const col2 of rel.scalarFields) {
8156
+ const values = row[col2.colName];
8157
+ child[col2.fieldName] = parseJsonIfNeeded(
8158
+ col2.isJson,
8159
+ Array.isArray(values) ? values[j] : null
8160
+ );
8161
+ }
8162
+ children[j] = child;
8163
+ }
8164
+ record[rel.name] = rel.isList ? children : (_a3 = children[0]) != null ? _a3 : null;
8165
+ }
8166
+ results[i] = record;
8167
+ }
8168
+ return results;
8169
+ }
8147
8170
 
8148
8171
  // src/builder/shared/where-in-executor-base.ts
8172
+ var MAX_RECURSIVE_DEPTH = 10;
8149
8173
  function getParamLimit(dialect) {
8150
8174
  return dialect === "postgres" ? 32e3 : 900;
8151
8175
  }
@@ -8198,8 +8222,14 @@ function stitchResults(parentRows, segment, childRows, stripFk) {
8198
8222
  }
8199
8223
  }
8200
8224
  }
8201
- function executeSegmentBase(segment, parentRows, allModels, modelMap, dialect, execute) {
8225
+ function executeSingleSegment(segment, parentRows, allModels, modelMap, dialect, execute, depth) {
8202
8226
  return __async(this, null, function* () {
8227
+ if (depth > MAX_RECURSIVE_DEPTH) {
8228
+ for (const parent of parentRows) {
8229
+ parent[segment.relationName] = segment.isList ? [] : null;
8230
+ }
8231
+ return;
8232
+ }
8203
8233
  const parentIds = parentRows.map((r) => r[segment.parentKeyFieldName]).filter((v) => v != null);
8204
8234
  if (parentIds.length === 0) {
8205
8235
  for (const parent of parentRows) {
@@ -8219,23 +8249,41 @@ function executeSegmentBase(segment, parentRows, allModels, modelMap, dialect, e
8219
8249
  }
8220
8250
  const allChildRows = [];
8221
8251
  let needsStripFk = false;
8252
+ let nestedSegments = [];
8222
8253
  for (const chunk of chunks) {
8223
8254
  const childArgs = buildChildArgs(
8224
8255
  segment.relArgs,
8225
8256
  segment.fkFieldName,
8226
8257
  chunk
8227
8258
  );
8228
- const stripFk = ensureFkInSelect(childArgs, segment.fkFieldName);
8259
+ const childPlan = planQueryStrategy({
8260
+ model: childModel,
8261
+ args: childArgs,
8262
+ allModels});
8263
+ if (nestedSegments.length === 0 && childPlan.whereInSegments.length > 0) {
8264
+ nestedSegments = childPlan.whereInSegments;
8265
+ }
8266
+ const stripFk = ensureFkInSelect(
8267
+ childPlan.filteredArgs,
8268
+ segment.fkFieldName
8269
+ );
8229
8270
  if (stripFk) needsStripFk = true;
8230
8271
  const result = buildSQL(
8231
8272
  childModel,
8232
8273
  allModels,
8233
8274
  "findMany",
8234
- childArgs,
8275
+ childPlan.filteredArgs,
8235
8276
  dialect
8236
8277
  );
8237
8278
  let rows = yield execute(result.sql, result.params);
8238
- if (result.requiresReduction && result.includeSpec) {
8279
+ if (result.isArrayAgg && result.includeSpec) {
8280
+ const config = buildArrayAggReducerConfig(
8281
+ childModel,
8282
+ result.includeSpec,
8283
+ allModels
8284
+ );
8285
+ rows = reduceArrayAggRows(rows, config);
8286
+ } else if (result.requiresReduction && result.includeSpec) {
8239
8287
  const config = buildReducerConfig(
8240
8288
  childModel,
8241
8289
  result.includeSpec,
@@ -8247,229 +8295,260 @@ function executeSegmentBase(segment, parentRows, allModels, modelMap, dialect, e
8247
8295
  allChildRows.push(row);
8248
8296
  }
8249
8297
  }
8298
+ if (nestedSegments.length > 0 && allChildRows.length > 0) {
8299
+ for (const row of allChildRows) {
8300
+ for (const nestedSeg of nestedSegments) {
8301
+ row[nestedSeg.relationName] = nestedSeg.isList ? [] : null;
8302
+ }
8303
+ }
8304
+ yield resolveSegmentsIntelligent(
8305
+ nestedSegments,
8306
+ allChildRows,
8307
+ allModels,
8308
+ modelMap,
8309
+ dialect,
8310
+ execute,
8311
+ depth + 1
8312
+ );
8313
+ }
8250
8314
  stitchResults(parentRows, segment, allChildRows, needsStripFk);
8251
8315
  });
8252
8316
  }
8253
- var init_where_in_executor_base = __esm({
8254
- "src/builder/shared/where-in-executor-base.ts"() {
8255
- init_src();
8256
- init_reducer();
8257
- init_type_guards();
8258
- }
8259
- });
8260
-
8261
- // src/builder/where-in-executor.ts
8262
- function executeWhereInSegments(params) {
8317
+ function resolveSegmentsIntelligent(segments, parentRows, allModels, modelMap, dialect, execute, depth) {
8263
8318
  return __async(this, null, function* () {
8264
- const { segments, parentRows, allModels, modelMap, dialect, execute } = params;
8319
+ if (depth > MAX_RECURSIVE_DEPTH) return;
8265
8320
  if (segments.length === 0) return;
8266
- if (parentRows.length === 0) return;
8267
- for (const segment of segments) {
8268
- yield executeSegmentBase(
8269
- segment,
8321
+ if (segments.length === 1) {
8322
+ yield executeSingleSegment(
8323
+ segments[0],
8270
8324
  parentRows,
8271
8325
  allModels,
8272
8326
  modelMap,
8273
8327
  dialect,
8274
- execute
8328
+ execute,
8329
+ depth
8275
8330
  );
8331
+ return;
8276
8332
  }
8333
+ yield Promise.all(
8334
+ segments.map(
8335
+ (seg) => executeSingleSegment(
8336
+ seg,
8337
+ parentRows,
8338
+ allModels,
8339
+ modelMap,
8340
+ dialect,
8341
+ execute,
8342
+ depth
8343
+ )
8344
+ )
8345
+ );
8346
+ });
8347
+ }
8348
+ function executeSegmentBase(segment, parentRows, allModels, modelMap, dialect, execute, depth = 0) {
8349
+ return __async(this, null, function* () {
8350
+ yield executeSingleSegment(
8351
+ segment,
8352
+ parentRows,
8353
+ allModels,
8354
+ modelMap,
8355
+ dialect,
8356
+ execute,
8357
+ depth
8358
+ );
8277
8359
  });
8278
8360
  }
8279
- var init_where_in_executor = __esm({
8280
- "src/builder/where-in-executor.ts"() {
8281
- init_where_in_executor_base();
8282
- }
8283
- });
8284
8361
 
8285
- // src/builder/select/core-reducer.ts
8286
- var getOrCreateRelationMap, getOrCreateChildMap, createParentObject, createChildObject, extractChildKey, attachChildToParent, createRelationProcessor, createCoreReducer;
8287
- var init_core_reducer = __esm({
8288
- "src/builder/select/core-reducer.ts"() {
8289
- init_primary_key_utils();
8290
- init_key_utils();
8291
- init_model_field_cache();
8292
- getOrCreateRelationMap = (relationMaps, parent) => {
8293
- let relMap = relationMaps.get(parent);
8294
- if (!relMap) {
8295
- relMap = /* @__PURE__ */ new Map();
8296
- relationMaps.set(parent, relMap);
8297
- }
8298
- return relMap;
8299
- };
8300
- getOrCreateChildMap = (relMap, path) => {
8301
- let childMap = relMap.get(path);
8302
- if (!childMap) {
8303
- childMap = /* @__PURE__ */ new Map();
8304
- relMap.set(path, childMap);
8305
- }
8306
- return childMap;
8307
- };
8308
- createParentObject = (row, scalarFields, jsonSet, includedRelations) => {
8309
- const parent = {};
8310
- for (const field of scalarFields) {
8311
- if (!(field.name in row)) continue;
8312
- parent[field.name] = maybeParseJson(row[field.name], jsonSet, field.name);
8313
- }
8314
- for (const rel of includedRelations) {
8315
- parent[rel.name] = rel.cardinality === "many" ? [] : null;
8316
- }
8317
- return parent;
8318
- };
8319
- createChildObject = (row, rel) => {
8320
- const child = {};
8321
- for (const spec of rel.scalarCols) {
8322
- if (!(spec.colName in row)) continue;
8323
- child[spec.fieldName] = parseJsonIfNeeded(spec.isJson, row[spec.colName]);
8324
- }
8325
- if (rel.nestedIncludes) {
8326
- for (const nested of rel.nestedIncludes.includedRelations) {
8327
- child[nested.name] = nested.cardinality === "many" ? [] : null;
8362
+ // src/builder/where-in-executor.ts
8363
+ var ADAPTIVE_PARENT_THRESHOLD = 15;
8364
+ var ADAPTIVE_DEPTH_THRESHOLD = 2;
8365
+ function measureRelArgsDepth(relArgs) {
8366
+ if (!relArgs || relArgs === true || typeof relArgs !== "object") return 0;
8367
+ const args = relArgs;
8368
+ const nested = args.include || args.select;
8369
+ if (!nested || typeof nested !== "object") return 0;
8370
+ let maxChildDepth = 0;
8371
+ for (const val of Object.values(nested)) {
8372
+ if (val === false) continue;
8373
+ if (val === true) {
8374
+ maxChildDepth = Math.max(maxChildDepth, 1);
8375
+ continue;
8376
+ }
8377
+ if (val && typeof val === "object") {
8378
+ maxChildDepth = Math.max(maxChildDepth, 1 + measureRelArgsDepth(val));
8379
+ }
8380
+ }
8381
+ return maxChildDepth;
8382
+ }
8383
+ function measureSegmentNestingDepth(segments) {
8384
+ let maxDepth = 0;
8385
+ for (const seg of segments) {
8386
+ const depth = 1 + measureRelArgsDepth(seg.relArgs);
8387
+ maxDepth = Math.max(maxDepth, depth);
8388
+ }
8389
+ return maxDepth;
8390
+ }
8391
+ function shouldAdaptivelySwitch(actualParentCount, segments) {
8392
+ if (actualParentCount > ADAPTIVE_PARENT_THRESHOLD) return false;
8393
+ if (segments.length === 0) return false;
8394
+ const depth = measureSegmentNestingDepth(segments);
8395
+ return depth >= ADAPTIVE_DEPTH_THRESHOLD;
8396
+ }
8397
+ function executeCorrelatedFallback(parentRows, parentModel, allModels, dialect, execute, originalArgs, method, segments) {
8398
+ return __async(this, null, function* () {
8399
+ const pkField = getPrimaryKeyField(parentModel);
8400
+ const pks = parentRows.map((r) => r[pkField]).filter(Boolean);
8401
+ if (pks.length === 0) {
8402
+ for (const parent of parentRows) {
8403
+ for (const seg of segments) {
8404
+ parent[seg.relationName] = seg.isList ? [] : null;
8328
8405
  }
8329
8406
  }
8330
- return child;
8331
- };
8332
- extractChildKey = (row, rel) => {
8333
- const cols = rel.primaryKeyFields.map((f) => `${rel.path}.${f}`);
8334
- return buildCompositeKey(row, cols);
8335
- };
8336
- attachChildToParent = (parent, child, rel) => {
8337
- if (rel.cardinality === "many") {
8338
- parent[rel.name].push(child);
8339
- } else {
8340
- parent[rel.name] = child;
8341
- }
8342
- };
8343
- createRelationProcessor = (relationMaps) => {
8344
- const processRelation2 = (parent, rel, row) => {
8345
- const childKey = extractChildKey(row, rel);
8346
- if (!childKey) return;
8347
- const relMap = getOrCreateRelationMap(relationMaps, parent);
8348
- const childMap = getOrCreateChildMap(relMap, rel.path);
8349
- if (childMap.has(childKey)) {
8350
- const existing = childMap.get(childKey);
8351
- if (rel.nestedIncludes) {
8352
- for (const nested of rel.nestedIncludes.includedRelations) {
8353
- processRelation2(existing, nested, row);
8354
- }
8355
- }
8356
- return;
8357
- }
8358
- const child = createChildObject(row, rel);
8359
- childMap.set(childKey, child);
8360
- attachChildToParent(parent, child, rel);
8361
- if (rel.nestedIncludes) {
8362
- for (const nested of rel.nestedIncludes.includedRelations) {
8363
- processRelation2(child, nested, row);
8364
- }
8407
+ return;
8408
+ }
8409
+ const fallbackArgs = __spreadValues({}, originalArgs);
8410
+ delete fallbackArgs.take;
8411
+ delete fallbackArgs.skip;
8412
+ delete fallbackArgs.cursor;
8413
+ fallbackArgs.where = { [pkField]: { in: pks } };
8414
+ if (originalArgs.orderBy) {
8415
+ fallbackArgs.orderBy = originalArgs.orderBy;
8416
+ }
8417
+ const result = buildSQL(
8418
+ parentModel,
8419
+ allModels,
8420
+ method,
8421
+ fallbackArgs,
8422
+ dialect
8423
+ );
8424
+ let rows = yield execute(result.sql, result.params);
8425
+ if (result.isArrayAgg && result.includeSpec) {
8426
+ const config = buildArrayAggReducerConfig(
8427
+ parentModel,
8428
+ result.includeSpec,
8429
+ allModels
8430
+ );
8431
+ rows = reduceArrayAggRows(rows, config);
8432
+ } else if (result.requiresReduction && result.includeSpec) {
8433
+ const config = buildReducerConfig(
8434
+ parentModel,
8435
+ result.includeSpec,
8436
+ allModels
8437
+ );
8438
+ rows = reduceFlatRows(rows, config);
8439
+ }
8440
+ const rowsByPk = /* @__PURE__ */ new Map();
8441
+ for (const row of rows) {
8442
+ rowsByPk.set(row[pkField], row);
8443
+ }
8444
+ for (const parent of parentRows) {
8445
+ const pk = parent[pkField];
8446
+ const fullRow = rowsByPk.get(pk);
8447
+ if (fullRow) {
8448
+ for (const seg of segments) {
8449
+ parent[seg.relationName] = fullRow[seg.relationName];
8365
8450
  }
8366
- };
8367
- return processRelation2;
8368
- };
8369
- createCoreReducer = (config) => {
8370
- const parentMap = /* @__PURE__ */ new Map();
8371
- const relationMaps = /* @__PURE__ */ new WeakMap();
8372
- const scalarFields = config.parentModel.fields.filter((f) => !f.isRelation);
8373
- const jsonSet = getJsonFieldSet(config.parentModel);
8374
- const parentPkFields = getPrimaryKeyFields(config.parentModel);
8375
- const includedRelations = config.includedRelations;
8376
- const extractParentKey = (row) => buildCompositeKey(row, parentPkFields);
8377
- const processRelation2 = createRelationProcessor(relationMaps);
8378
- const processRow = (row) => {
8379
- const parentKey = extractParentKey(row);
8380
- if (!parentKey) return null;
8381
- const parent = parentMap.has(parentKey) ? parentMap.get(parentKey) : (() => {
8382
- const newParent = createParentObject(
8383
- row,
8384
- scalarFields,
8385
- jsonSet,
8386
- includedRelations
8387
- );
8388
- parentMap.set(parentKey, newParent);
8389
- return newParent;
8390
- })();
8391
- for (const rel of includedRelations) {
8392
- processRelation2(parent, rel, row);
8451
+ } else {
8452
+ for (const seg of segments) {
8453
+ parent[seg.relationName] = seg.isList ? [] : null;
8393
8454
  }
8394
- return parentKey;
8395
- };
8396
- return {
8397
- processRow,
8398
- getParent: (key) => {
8399
- var _a;
8400
- return (_a = parentMap.get(key)) != null ? _a : null;
8401
- },
8402
- getAllParents: () => Array.from(parentMap.values()),
8403
- getParentMap: () => parentMap
8404
- };
8405
- };
8406
- }
8407
- });
8408
-
8409
- // src/builder/select/streaming-reducer.ts
8410
- function createStreamingReducer(config) {
8411
- const coreReducer = createCoreReducer({
8412
- parentModel: config.parentModel,
8413
- includedRelations: config.includedRelations
8455
+ }
8456
+ }
8414
8457
  });
8415
- return {
8416
- processRow(row) {
8417
- coreReducer.processRow(row);
8418
- },
8419
- getResults() {
8420
- return coreReducer.getAllParents();
8421
- },
8422
- getParentMap() {
8423
- return coreReducer.getParentMap();
8458
+ }
8459
+ function executeWhereInSegments(params) {
8460
+ return __async(this, null, function* () {
8461
+ const {
8462
+ segments,
8463
+ parentRows,
8464
+ parentModel,
8465
+ allModels,
8466
+ modelMap,
8467
+ dialect,
8468
+ execute,
8469
+ originalArgs,
8470
+ method
8471
+ } = params;
8472
+ if (originalArgs && method && parentModel && shouldAdaptivelySwitch(parentRows.length, segments)) {
8473
+ yield executeCorrelatedFallback(
8474
+ parentRows,
8475
+ parentModel,
8476
+ allModels,
8477
+ dialect,
8478
+ execute,
8479
+ originalArgs,
8480
+ method,
8481
+ segments
8482
+ );
8483
+ return;
8424
8484
  }
8425
- };
8485
+ if (segments.length === 1) {
8486
+ yield executeSegmentBase(
8487
+ segments[0],
8488
+ parentRows,
8489
+ allModels,
8490
+ modelMap,
8491
+ dialect,
8492
+ execute,
8493
+ 0
8494
+ );
8495
+ return;
8496
+ }
8497
+ yield Promise.all(
8498
+ segments.map(
8499
+ (segment) => executeSegmentBase(
8500
+ segment,
8501
+ parentRows,
8502
+ allModels,
8503
+ modelMap,
8504
+ dialect,
8505
+ execute,
8506
+ 0
8507
+ )
8508
+ )
8509
+ );
8510
+ });
8426
8511
  }
8427
- var init_streaming_reducer = __esm({
8428
- "src/builder/select/streaming-reducer.ts"() {
8429
- init_core_reducer();
8430
- }
8431
- });
8432
8512
 
8433
- // src/builder/select/streaming-progressive-reducer.ts
8434
- function createProgressiveReducer(config) {
8435
- const coreReducer = createCoreReducer({
8436
- parentModel: config.parentModel,
8437
- includedRelations: config.includedRelations
8438
- });
8439
- const completedKeys = /* @__PURE__ */ new Set();
8440
- return {
8441
- processRow(row) {
8442
- coreReducer.processRow(row);
8443
- },
8444
- getCurrentParentKey(row) {
8445
- return coreReducer.processRow(row);
8446
- },
8447
- getCompletedParent(parentKey) {
8448
- if (completedKeys.has(parentKey)) return null;
8449
- const parent = coreReducer.getParent(parentKey);
8450
- if (!parent) return null;
8451
- completedKeys.add(parentKey);
8452
- return parent;
8453
- },
8454
- getRemainingParents() {
8455
- const remaining = [];
8456
- for (const [key, parent] of coreReducer.getParentMap()) {
8457
- if (!completedKeys.has(key)) {
8458
- remaining.push(parent);
8459
- completedKeys.add(key);
8513
+ // src/builder/select/streaming-where-in-executor.ts
8514
+ var MAX_RECURSIVE_DEPTH2 = 10;
8515
+ function buildParentKeyIndex(parentRows, parentKeyFieldName) {
8516
+ const index = /* @__PURE__ */ new Map();
8517
+ for (const parent of parentRows) {
8518
+ const keyVal = parent[parentKeyFieldName];
8519
+ if (keyVal == null) continue;
8520
+ let arr = index.get(keyVal);
8521
+ if (!arr) {
8522
+ arr = [];
8523
+ index.set(keyVal, arr);
8524
+ }
8525
+ arr.push(parent);
8526
+ }
8527
+ return index;
8528
+ }
8529
+ function stitchChildrenToParents(children, segment, parentKeyIndex) {
8530
+ for (const child of children) {
8531
+ const childKey = child[segment.fkFieldName];
8532
+ const matchingParents = parentKeyIndex.get(childKey);
8533
+ if (!matchingParents) continue;
8534
+ for (const parent of matchingParents) {
8535
+ if (segment.isList) {
8536
+ if (!Array.isArray(parent[segment.relationName])) {
8537
+ parent[segment.relationName] = [];
8460
8538
  }
8539
+ parent[segment.relationName].push(child);
8540
+ } else {
8541
+ parent[segment.relationName] = child;
8461
8542
  }
8462
- return remaining;
8463
8543
  }
8464
- };
8465
- }
8466
- var init_streaming_progressive_reducer = __esm({
8467
- "src/builder/select/streaming-progressive-reducer.ts"() {
8468
- init_core_reducer();
8469
8544
  }
8470
- });
8471
-
8472
- // src/builder/select/streaming-where-in-executor.ts
8545
+ }
8546
+ function ensureFkInSelect2(childArgs, fkFieldName) {
8547
+ if (!childArgs.select) return false;
8548
+ if (childArgs.select[fkFieldName]) return false;
8549
+ childArgs.select = __spreadProps(__spreadValues({}, childArgs.select), { [fkFieldName]: true });
8550
+ return true;
8551
+ }
8473
8552
  function executeWhereInSegmentsStreaming(params) {
8474
8553
  return __async(this, null, function* () {
8475
8554
  const {
@@ -8480,9 +8559,7 @@ function executeWhereInSegmentsStreaming(params) {
8480
8559
  allModels,
8481
8560
  modelMap,
8482
8561
  dialect,
8483
- execute,
8484
- batchSize = 100,
8485
- maxConcurrency = 10
8562
+ execute
8486
8563
  } = params;
8487
8564
  if (segments.length === 0) {
8488
8565
  throw new Error("executeWhereInSegmentsStreaming requires segments");
@@ -8490,100 +8567,157 @@ function executeWhereInSegmentsStreaming(params) {
8490
8567
  if (dialect !== "postgres") {
8491
8568
  throw new Error("Streaming WHERE IN requires postgres dialect");
8492
8569
  }
8493
- const parentMap = /* @__PURE__ */ new Map();
8494
- const batches = /* @__PURE__ */ new Map();
8495
- const inFlightMap = /* @__PURE__ */ new Map();
8496
- for (const seg of segments) {
8497
- batches.set(seg.relationName, []);
8498
- }
8499
- const pkField = getPrimaryKeyField(parentModel);
8500
8570
  const parentRows = yield execute(parentSql, parentParams);
8571
+ if (parentRows.length === 0) return [];
8501
8572
  for (const row of parentRows) {
8502
- const pk = row[pkField];
8503
- parentMap.set(pk, __spreadValues({}, row));
8504
8573
  for (const seg of segments) {
8505
8574
  row[seg.relationName] = seg.isList ? [] : null;
8506
8575
  }
8576
+ }
8577
+ yield resolveSegments(
8578
+ segments,
8579
+ parentRows,
8580
+ allModels,
8581
+ modelMap,
8582
+ dialect,
8583
+ execute,
8584
+ 0
8585
+ );
8586
+ return parentRows;
8587
+ });
8588
+ }
8589
+ function executeWithPreFetchedParents(params) {
8590
+ return __async(this, null, function* () {
8591
+ const {
8592
+ segments,
8593
+ parentRows,
8594
+ parentModel,
8595
+ allModels,
8596
+ modelMap,
8597
+ dialect,
8598
+ execute
8599
+ } = params;
8600
+ if (segments.length === 0) return parentRows;
8601
+ if (parentRows.length === 0) return [];
8602
+ for (const row of parentRows) {
8507
8603
  for (const seg of segments) {
8508
- const batch = batches.get(seg.relationName);
8509
- const parentKey = row[seg.parentKeyFieldName];
8510
- batch.push(parentKey);
8511
- if (batch.length >= batchSize) {
8512
- const idsToFetch = [...batch];
8513
- batch.length = 0;
8514
- const promise = fetchAndAttachChildren(
8515
- seg,
8516
- idsToFetch,
8517
- parentMap,
8518
- allModels,
8519
- modelMap,
8520
- dialect,
8521
- execute
8522
- );
8523
- inFlightMap.set(promise, seg.relationName);
8524
- promise.finally(() => {
8525
- inFlightMap.delete(promise);
8526
- });
8527
- if (inFlightMap.size >= maxConcurrency) {
8528
- yield Promise.race(inFlightMap.keys());
8529
- }
8530
- }
8604
+ row[seg.relationName] = seg.isList ? [] : null;
8531
8605
  }
8532
8606
  }
8533
- for (const seg of segments) {
8534
- const batch = batches.get(seg.relationName);
8535
- if (batch.length > 0) {
8536
- const promise = fetchAndAttachChildren(
8607
+ yield resolveSegments(
8608
+ segments,
8609
+ parentRows,
8610
+ allModels,
8611
+ modelMap,
8612
+ dialect,
8613
+ execute,
8614
+ 0
8615
+ );
8616
+ return parentRows;
8617
+ });
8618
+ }
8619
+ function resolveSegments(segments, parentRows, allModels, modelMap, dialect, execute, depth) {
8620
+ return __async(this, null, function* () {
8621
+ if (depth > MAX_RECURSIVE_DEPTH2) return;
8622
+ if (segments.length === 0) return;
8623
+ if (segments.length === 1) {
8624
+ yield resolveSingleSegment(
8625
+ segments[0],
8626
+ parentRows,
8627
+ allModels,
8628
+ modelMap,
8629
+ dialect,
8630
+ execute,
8631
+ depth
8632
+ );
8633
+ return;
8634
+ }
8635
+ yield Promise.all(
8636
+ segments.map(
8637
+ (seg) => resolveSingleSegment(
8537
8638
  seg,
8538
- batch,
8539
- parentMap,
8639
+ parentRows,
8540
8640
  allModels,
8541
8641
  modelMap,
8542
8642
  dialect,
8543
- execute
8544
- );
8545
- inFlightMap.set(promise, seg.relationName);
8546
- promise.finally(() => {
8547
- inFlightMap.delete(promise);
8548
- });
8549
- }
8550
- }
8551
- yield Promise.all(inFlightMap.keys());
8552
- return Array.from(parentMap.values());
8643
+ execute,
8644
+ depth
8645
+ )
8646
+ )
8647
+ );
8553
8648
  });
8554
8649
  }
8555
- function fetchAndAttachChildren(segment, parentIds, parentMap, allModels, modelMap, dialect, execute) {
8650
+ function resolveSingleSegment(segment, parentRows, allModels, modelMap, dialect, execute, depth) {
8556
8651
  return __async(this, null, function* () {
8557
8652
  const childModel = modelMap.get(segment.childModelName);
8558
- if (!childModel) return;
8653
+ if (!childModel) {
8654
+ return;
8655
+ }
8656
+ const parentIds = parentRows.map((r) => r[segment.parentKeyFieldName]).filter((v) => v != null);
8657
+ if (parentIds.length === 0) {
8658
+ return;
8659
+ }
8660
+ const uniqueIds = [...new Set(parentIds)];
8559
8661
  const childArgs = buildChildArgs2(
8560
8662
  segment.relArgs,
8561
8663
  segment.fkFieldName,
8562
- parentIds
8664
+ uniqueIds
8563
8665
  );
8666
+ const needsStripFk = ensureFkInSelect2(childArgs, segment.fkFieldName);
8667
+ const childPlan = planQueryStrategy({
8668
+ model: childModel,
8669
+ args: childArgs,
8670
+ allModels});
8564
8671
  const result = buildSQL(
8565
8672
  childModel,
8566
8673
  allModels,
8567
8674
  "findMany",
8568
- childArgs,
8675
+ childPlan.filteredArgs,
8569
8676
  dialect
8570
8677
  );
8571
8678
  let children = yield execute(result.sql, result.params);
8572
- if (result.requiresReduction && result.includeSpec) {
8679
+ if (result.isArrayAgg && result.includeSpec) {
8680
+ const config = buildArrayAggReducerConfig(
8681
+ childModel,
8682
+ result.includeSpec,
8683
+ allModels
8684
+ );
8685
+ children = reduceArrayAggRows(children, config);
8686
+ } else if (result.requiresReduction && result.includeSpec) {
8573
8687
  const config = buildReducerConfig(childModel, result.includeSpec, allModels);
8574
8688
  children = reduceFlatRows(children, config);
8575
8689
  }
8576
- for (const child of children) {
8577
- const fkValue = child[segment.fkFieldName];
8578
- const parent = parentMap.get(fkValue);
8579
- if (!parent) continue;
8580
- if (segment.isList) {
8581
- if (!Array.isArray(parent[segment.relationName])) {
8582
- parent[segment.relationName] = [];
8690
+ if (childPlan.whereInSegments.length > 0 && children.length > 0) {
8691
+ for (const child of children) {
8692
+ for (const nestedSeg of childPlan.whereInSegments) {
8693
+ child[nestedSeg.relationName] = nestedSeg.isList ? [] : null;
8694
+ }
8695
+ }
8696
+ yield resolveSegments(
8697
+ childPlan.whereInSegments,
8698
+ children,
8699
+ allModels,
8700
+ modelMap,
8701
+ dialect,
8702
+ execute,
8703
+ depth + 1
8704
+ );
8705
+ if (childPlan.injectedParentKeys.length > 0) {
8706
+ for (const child of children) {
8707
+ for (const key of childPlan.injectedParentKeys) {
8708
+ delete child[key];
8709
+ }
8583
8710
  }
8584
- parent[segment.relationName].push(child);
8585
- } else {
8586
- parent[segment.relationName] = child;
8711
+ }
8712
+ }
8713
+ const parentKeyIndex = buildParentKeyIndex(
8714
+ parentRows,
8715
+ segment.parentKeyFieldName
8716
+ );
8717
+ stitchChildrenToParents(children, segment, parentKeyIndex);
8718
+ if (needsStripFk) {
8719
+ for (const child of children) {
8720
+ delete child[segment.fkFieldName];
8587
8721
  }
8588
8722
  }
8589
8723
  });
@@ -8595,77 +8729,180 @@ function buildChildArgs2(relArgs, fkFieldName, parentIds) {
8595
8729
  base.where = existingWhere ? { AND: [existingWhere, inCondition] } : inCondition;
8596
8730
  return base;
8597
8731
  }
8598
- var init_streaming_where_in_executor = __esm({
8599
- "src/builder/select/streaming-where-in-executor.ts"() {
8600
- init_primary_key_utils();
8601
- init_src();
8602
- init_reducer();
8603
- }
8604
- });
8605
8732
 
8606
- // src/builder/select/row-transformers.ts
8607
- function transformAggregateRow(row) {
8608
- if (!row || typeof row !== "object") return row;
8609
- const result = {};
8610
- for (const key in row) {
8611
- if (!Object.prototype.hasOwnProperty.call(row, key)) continue;
8612
- const value = row[key];
8613
- const dotIndex = key.indexOf(".");
8614
- if (dotIndex === -1) {
8615
- result[key] = value;
8616
- continue;
8617
- }
8618
- const prefix = key.slice(0, dotIndex);
8619
- const suffix = key.slice(dotIndex + 1);
8620
- if (AGGREGATE_PREFIXES.has(prefix)) {
8621
- if (!result[prefix]) {
8622
- result[prefix] = {};
8623
- }
8624
- result[prefix][suffix] = value;
8625
- } else {
8626
- result[key] = value;
8627
- }
8733
+ // src/builder/select/core-reducer.ts
8734
+ var getOrCreateRelationMap = (relationMaps, parent) => {
8735
+ let relMap = relationMaps.get(parent);
8736
+ if (!relMap) {
8737
+ relMap = /* @__PURE__ */ new Map();
8738
+ relationMaps.set(parent, relMap);
8628
8739
  }
8629
- return result;
8630
- }
8631
- function extractCountValue(row) {
8632
- if (!row || typeof row !== "object") return 0;
8633
- if ("_count._all" in row) {
8634
- return row["_count._all"];
8740
+ return relMap;
8741
+ };
8742
+ var getOrCreateChildMap = (relMap, path) => {
8743
+ let childMap = relMap.get(path);
8744
+ if (!childMap) {
8745
+ childMap = /* @__PURE__ */ new Map();
8746
+ relMap.set(path, childMap);
8635
8747
  }
8636
- if ("_count" in row && row["_count"] && typeof row["_count"] === "object") {
8637
- const countObj = row["_count"];
8638
- if ("_all" in countObj) {
8639
- return countObj["_all"];
8748
+ return childMap;
8749
+ };
8750
+ var createParentObject = (row, scalarFields, jsonSet, includedRelations) => {
8751
+ const parent = {};
8752
+ for (const field of scalarFields) {
8753
+ if (!(field.name in row)) continue;
8754
+ parent[field.name] = maybeParseJson(row[field.name], jsonSet, field.name);
8755
+ }
8756
+ for (const rel of includedRelations) {
8757
+ parent[rel.name] = rel.cardinality === "many" ? [] : null;
8758
+ }
8759
+ return parent;
8760
+ };
8761
+ var createChildObject = (row, rel) => {
8762
+ const child = {};
8763
+ for (const spec of rel.scalarCols) {
8764
+ if (!(spec.colName in row)) continue;
8765
+ child[spec.fieldName] = parseJsonIfNeeded(spec.isJson, row[spec.colName]);
8766
+ }
8767
+ if (rel.nestedIncludes) {
8768
+ for (const nested of rel.nestedIncludes.includedRelations) {
8769
+ child[nested.name] = nested.cardinality === "many" ? [] : null;
8640
8770
  }
8641
8771
  }
8642
- const keys = Object.keys(row);
8643
- for (const key of keys) {
8644
- if (key.includes("count") || key.includes("COUNT")) {
8645
- const value = row[key];
8646
- if (typeof value === "number" || typeof value === "bigint") {
8647
- return value;
8772
+ return child;
8773
+ };
8774
+ var attachChildToParent = (parent, child, rel) => {
8775
+ if (rel.cardinality === "many") {
8776
+ parent[rel.name].push(child);
8777
+ } else {
8778
+ parent[rel.name] = child;
8779
+ }
8780
+ };
8781
+ function prepareRelations(relations) {
8782
+ return relations.map((rel) => ({
8783
+ rel,
8784
+ prefixedPkFields: rel.primaryKeyFields.map((f) => `${rel.path}.${f}`),
8785
+ nested: rel.nestedIncludes ? prepareRelations(rel.nestedIncludes.includedRelations) : null
8786
+ }));
8787
+ }
8788
+ var createRelationProcessor = (relationMaps) => {
8789
+ const processRelation2 = (parent, prepared, row) => {
8790
+ const { rel, prefixedPkFields, nested } = prepared;
8791
+ const childKey = buildKey(row, prefixedPkFields);
8792
+ if (childKey == null) return;
8793
+ const relMap = getOrCreateRelationMap(relationMaps, parent);
8794
+ const childMap = getOrCreateChildMap(relMap, rel.path);
8795
+ if (childMap.has(childKey)) {
8796
+ if (nested) {
8797
+ const existing = childMap.get(childKey);
8798
+ for (const nestedPrepared of nested) {
8799
+ processRelation2(existing, nestedPrepared, row);
8800
+ }
8648
8801
  }
8802
+ return;
8649
8803
  }
8650
- }
8651
- return 0;
8804
+ const child = createChildObject(row, rel);
8805
+ childMap.set(childKey, child);
8806
+ attachChildToParent(parent, child, rel);
8807
+ if (nested) {
8808
+ for (const nestedPrepared of nested) {
8809
+ processRelation2(child, nestedPrepared, row);
8810
+ }
8811
+ }
8812
+ };
8813
+ return processRelation2;
8814
+ };
8815
+ var createCoreReducer = (config) => {
8816
+ const parentMap = /* @__PURE__ */ new Map();
8817
+ const relationMaps = /* @__PURE__ */ new WeakMap();
8818
+ const scalarFields = config.parentModel.fields.filter((f) => !f.isRelation);
8819
+ const jsonSet = getJsonFieldSet(config.parentModel);
8820
+ const parentPkFields = getPrimaryKeyFields(config.parentModel);
8821
+ const includedRelations = config.includedRelations;
8822
+ const preparedRelations = prepareRelations(includedRelations);
8823
+ const processRelation2 = createRelationProcessor(relationMaps);
8824
+ const processRow = (row) => {
8825
+ const parentKey = buildKey(row, parentPkFields);
8826
+ if (parentKey == null) return null;
8827
+ let parent;
8828
+ if (parentMap.has(parentKey)) {
8829
+ parent = parentMap.get(parentKey);
8830
+ } else {
8831
+ parent = createParentObject(row, scalarFields, jsonSet, includedRelations);
8832
+ parentMap.set(parentKey, parent);
8833
+ }
8834
+ for (const prepared of preparedRelations) {
8835
+ processRelation2(parent, prepared, row);
8836
+ }
8837
+ return parentKey;
8838
+ };
8839
+ return {
8840
+ processRow,
8841
+ getParent: (key) => {
8842
+ var _a3;
8843
+ return (_a3 = parentMap.get(key)) != null ? _a3 : null;
8844
+ },
8845
+ getAllParents: () => Array.from(parentMap.values()),
8846
+ getParentMap: () => parentMap
8847
+ };
8848
+ };
8849
+
8850
+ // src/builder/select/streaming-reducer.ts
8851
+ function createStreamingReducer(config) {
8852
+ const coreReducer = createCoreReducer({
8853
+ parentModel: config.parentModel,
8854
+ includedRelations: config.includedRelations
8855
+ });
8856
+ return {
8857
+ processRow(row) {
8858
+ coreReducer.processRow(row);
8859
+ },
8860
+ getResults() {
8861
+ return coreReducer.getAllParents();
8862
+ },
8863
+ getParentMap() {
8864
+ return coreReducer.getParentMap();
8865
+ }
8866
+ };
8652
8867
  }
8653
- function getRowTransformer(method) {
8654
- if (method === "count") {
8655
- return extractCountValue;
8656
- }
8657
- if (method === "groupBy" || method === "aggregate") {
8658
- return transformAggregateRow;
8659
- }
8660
- return null;
8868
+
8869
+ // src/builder/select/streaming-progressive-reducer.ts
8870
+ function createProgressiveReducer(config) {
8871
+ const coreReducer = createCoreReducer({
8872
+ parentModel: config.parentModel,
8873
+ includedRelations: config.includedRelations
8874
+ });
8875
+ const completedKeys = /* @__PURE__ */ new Set();
8876
+ return {
8877
+ processRow(row) {
8878
+ coreReducer.processRow(row);
8879
+ },
8880
+ getCurrentParentKey(row) {
8881
+ return coreReducer.processRow(row);
8882
+ },
8883
+ getCompletedParent(parentKey) {
8884
+ if (completedKeys.has(parentKey)) return null;
8885
+ const parent = coreReducer.getParent(parentKey);
8886
+ if (!parent) return null;
8887
+ completedKeys.add(parentKey);
8888
+ return parent;
8889
+ },
8890
+ getRemainingParents() {
8891
+ const remaining = [];
8892
+ for (const [key, parent] of coreReducer.getParentMap()) {
8893
+ if (!completedKeys.has(key)) {
8894
+ remaining.push(parent);
8895
+ completedKeys.add(key);
8896
+ }
8897
+ }
8898
+ return remaining;
8899
+ }
8900
+ };
8661
8901
  }
8662
- var init_row_transformers = __esm({
8663
- "src/builder/select/row-transformers.ts"() {
8664
- init_constants();
8665
- }
8666
- });
8667
8902
 
8668
8903
  // src/generated-runtime.ts
8904
+ var SQLITE_STMT_CACHE = /* @__PURE__ */ new WeakMap();
8905
+ var STMT_CACHE_LIMIT = 1e3;
8669
8906
  function getOrPrepareStatement(client, sql) {
8670
8907
  let cache = SQLITE_STMT_CACHE.get(client);
8671
8908
  if (!cache) {
@@ -8673,13 +8910,16 @@ function getOrPrepareStatement(client, sql) {
8673
8910
  SQLITE_STMT_CACHE.set(client, cache);
8674
8911
  }
8675
8912
  let stmt = cache.get(sql);
8676
- if (!stmt) {
8677
- stmt = client.prepare(sql);
8913
+ if (stmt) {
8914
+ cache.delete(sql);
8678
8915
  cache.set(sql, stmt);
8679
- if (cache.size > 1e3) {
8680
- const firstKey = cache.keys().next().value;
8681
- cache.delete(firstKey);
8682
- }
8916
+ return stmt;
8917
+ }
8918
+ stmt = client.prepare(sql);
8919
+ cache.set(sql, stmt);
8920
+ if (cache.size > STMT_CACHE_LIMIT) {
8921
+ const firstKey = cache.keys().next().value;
8922
+ cache.delete(firstKey);
8683
8923
  }
8684
8924
  return stmt;
8685
8925
  }
@@ -8689,69 +8929,64 @@ function shouldSqliteUseGet(method) {
8689
8929
  function normalizeParams(params) {
8690
8930
  return params.map((p) => normalizeValue(p));
8691
8931
  }
8692
- function executePostgresQuery(client, sql, params, method, requiresReduction, includeSpec, model, allModels) {
8932
+ function executePostgresQuery(client, sql, params, method, requiresReduction, includeSpec, model, allModels, isArrayAgg) {
8693
8933
  return __async(this, null, function* () {
8694
8934
  const normalizedParams = normalizeParams(params);
8695
- const query = client.unsafe(sql, normalizedParams);
8696
- if (requiresReduction && includeSpec && model) {
8935
+ if (isArrayAgg && includeSpec) {
8936
+ const config = buildArrayAggReducerConfig(model, includeSpec, allModels);
8937
+ const results2 = [];
8938
+ yield client.unsafe(sql, normalizedParams).forEach((row) => {
8939
+ results2.push(row);
8940
+ });
8941
+ return reduceArrayAggRows(results2, config);
8942
+ }
8943
+ if (requiresReduction && includeSpec) {
8697
8944
  const config = buildReducerConfig(model, includeSpec, allModels);
8698
- const { createStreamingReducer: createStreamingReducer2 } = yield Promise.resolve().then(() => (init_src(), src_exports));
8699
- const reducer = createStreamingReducer2(config);
8700
- yield query.forEach((row) => {
8945
+ const reducer = createStreamingReducer(config);
8946
+ yield client.unsafe(sql, normalizedParams).forEach((row) => {
8701
8947
  reducer.processRow(row);
8702
8948
  });
8703
8949
  return reducer.getResults();
8704
8950
  }
8705
- if (method === "count") {
8951
+ const needsTransform = method === "groupBy" || method === "aggregate" || method === "count";
8952
+ if (!needsTransform) {
8706
8953
  const results2 = [];
8707
- yield query.forEach((row) => {
8708
- results2.push(extractCountValue(row));
8954
+ yield client.unsafe(sql, normalizedParams).forEach((row) => {
8955
+ results2.push(row);
8709
8956
  });
8710
8957
  return results2;
8711
8958
  }
8712
- if (method === "groupBy" || method === "aggregate") {
8713
- const results2 = [];
8714
- yield query.forEach((row) => {
8715
- results2.push(transformAggregateRow(row));
8959
+ const rowTransformer = getRowTransformer(method);
8960
+ const results = [];
8961
+ if (rowTransformer) {
8962
+ yield client.unsafe(sql, normalizedParams).forEach((row) => {
8963
+ results.push(rowTransformer(row));
8964
+ });
8965
+ } else {
8966
+ yield client.unsafe(sql, normalizedParams).forEach((row) => {
8967
+ results.push(row);
8716
8968
  });
8717
- return results2;
8718
8969
  }
8719
- const results = [];
8720
- yield query.forEach((row) => {
8721
- results.push(row);
8722
- });
8723
8970
  return results;
8724
8971
  });
8725
8972
  }
8726
8973
  function executeSqliteQuery(client, sql, params, method, requiresReduction, includeSpec, model, allModels) {
8727
8974
  const normalizedParams = normalizeParams(params);
8728
- const stmt = getOrPrepareStatement(client, sql);
8729
- if (shouldSqliteUseGet(method)) {
8730
- const row = stmt.get(...normalizedParams);
8731
- if (row === void 0) {
8732
- return method === "count" ? [0] : [];
8733
- }
8734
- if (method === "count") {
8735
- return [extractCountValue(row)];
8736
- }
8737
- if (method === "aggregate") {
8738
- return [transformAggregateRow(row)];
8739
- }
8740
- return [row];
8741
- }
8742
- const rows = stmt.all(...normalizedParams);
8743
- if (method === "count") {
8744
- if (rows.length === 0) return [0];
8745
- return [extractCountValue(rows[0])];
8746
- }
8747
- if (method === "groupBy" || method === "aggregate") {
8748
- return rows.map((row) => transformAggregateRow(row));
8749
- }
8750
- if (requiresReduction && includeSpec && model) {
8975
+ const shouldTransform = method === "groupBy" || method === "aggregate" || method === "count";
8976
+ if (requiresReduction && includeSpec) {
8751
8977
  const config = buildReducerConfig(model, includeSpec, allModels);
8752
- return reduceFlatRows(rows, config);
8978
+ const stmt2 = getOrPrepareStatement(client, sql);
8979
+ const useGet2 = shouldSqliteUseGet(method);
8980
+ const rawResults2 = useGet2 ? stmt2.get(...normalizedParams) : stmt2.all(...normalizedParams);
8981
+ const results2 = Array.isArray(rawResults2) ? rawResults2 : [rawResults2];
8982
+ const transformed = shouldTransform ? results2.map(transformAggregateRow) : results2;
8983
+ return reduceFlatRows(transformed, config);
8753
8984
  }
8754
- return rows;
8985
+ const stmt = getOrPrepareStatement(client, sql);
8986
+ const useGet = shouldSqliteUseGet(method);
8987
+ const rawResults = useGet ? stmt.get(...normalizedParams) : stmt.all(...normalizedParams);
8988
+ const results = Array.isArray(rawResults) ? rawResults : [rawResults];
8989
+ return shouldTransform ? results.map(transformAggregateRow) : results;
8755
8990
  }
8756
8991
  function executeRaw(client, sql, params, dialect) {
8757
8992
  return __async(this, null, function* () {
@@ -8761,47 +8996,8 @@ function executeRaw(client, sql, params, dialect) {
8761
8996
  throw new Error("Raw execution for sqlite not supported in transactions");
8762
8997
  });
8763
8998
  }
8764
- var SQLITE_STMT_CACHE;
8765
- var init_generated_runtime = __esm({
8766
- "src/generated-runtime.ts"() {
8767
- init_src();
8768
- SQLITE_STMT_CACHE = /* @__PURE__ */ new WeakMap();
8769
- }
8770
- });
8771
8999
 
8772
9000
  // src/index.ts
8773
- var src_exports = {};
8774
- __export(src_exports, {
8775
- buildBatchCountSql: () => buildBatchCountSql,
8776
- buildBatchSql: () => buildBatchSql,
8777
- buildReducerConfig: () => buildReducerConfig,
8778
- buildSQL: () => buildSQL,
8779
- createPrismaSQL: () => createPrismaSQL,
8780
- createProgressiveReducer: () => createProgressiveReducer,
8781
- createStreamingReducer: () => createStreamingReducer,
8782
- createToSQL: () => createToSQL,
8783
- createTransactionExecutor: () => createTransactionExecutor,
8784
- executePostgresQuery: () => executePostgresQuery,
8785
- executeRaw: () => executeRaw,
8786
- executeSqliteQuery: () => executeSqliteQuery,
8787
- executeWhereInSegments: () => executeWhereInSegments,
8788
- executeWhereInSegmentsStreaming: () => executeWhereInSegmentsStreaming,
8789
- extractCountValue: () => extractCountValue,
8790
- generateAllSQL: () => generateAllSQL,
8791
- generateSQL: () => generateSQL2,
8792
- generateSQLByModel: () => generateSQLByModel,
8793
- getOrPrepareStatement: () => getOrPrepareStatement,
8794
- getRowTransformer: () => getRowTransformer,
8795
- normalizeParams: () => normalizeParams,
8796
- normalizeValue: () => normalizeValue,
8797
- parseBatchCountResults: () => parseBatchCountResults,
8798
- parseBatchResults: () => parseBatchResults,
8799
- planQueryStrategy: () => planQueryStrategy,
8800
- reduceFlatRows: () => reduceFlatRows,
8801
- shouldSqliteUseGet: () => shouldSqliteUseGet,
8802
- transformAggregateRow: () => transformAggregateRow,
8803
- transformQueryResults: () => transformQueryResults
8804
- });
8805
9001
  function buildSQL(model, models, method, args, dialect) {
8806
9002
  return buildSQLWithCache(model, models, method, args, dialect);
8807
9003
  }
@@ -8903,28 +9099,7 @@ function generateSQLByModel(directives) {
8903
9099
  }
8904
9100
  return byModel;
8905
9101
  }
8906
- var init_src = __esm({
8907
- "src/index.ts"() {
8908
- init_sql_builder_dialect();
8909
- init_sql_generator();
8910
- init_query_cache();
8911
- init_batch();
8912
- init_transaction();
8913
- init_result_transformers();
8914
- init_reducer();
8915
- init_segment_planner();
8916
- init_where_in_executor();
8917
- init_reducer();
8918
- init_normalize_value();
8919
- init_streaming_reducer();
8920
- init_streaming_progressive_reducer();
8921
- init_streaming_where_in_executor();
8922
- init_row_transformers();
8923
- init_generated_runtime();
8924
- }
8925
- });
8926
- init_src();
8927
9102
 
8928
- export { buildBatchCountSql, buildBatchSql, buildReducerConfig, buildSQL, createPrismaSQL, createProgressiveReducer, createStreamingReducer, createToSQL, createTransactionExecutor, executePostgresQuery, executeRaw, executeSqliteQuery, executeWhereInSegments, executeWhereInSegmentsStreaming, extractCountValue, generateAllSQL, generateSQL2 as generateSQL, generateSQLByModel, getOrPrepareStatement, getRowTransformer, normalizeParams, normalizeValue, parseBatchCountResults, parseBatchResults, planQueryStrategy, reduceFlatRows, shouldSqliteUseGet, transformAggregateRow, transformQueryResults };
9103
+ export { buildArrayAggReducerConfig, buildBatchCountSql, buildBatchSql, buildReducerConfig, buildSQL, createPrismaSQL, createProgressiveReducer, createStreamingReducer, createToSQL, createTransactionExecutor, executePostgresQuery, executeRaw, executeSqliteQuery, executeWhereInSegments, executeWhereInSegmentsStreaming, executeWithPreFetchedParents, extractCountValue, generateAllSQL, generateSQL2 as generateSQL, generateSQLByModel, getOrPrepareStatement, getPrimaryKeyField, getRowTransformer, normalizeParams, normalizeValue, parseBatchCountResults, parseBatchResults, planQueryStrategy, reduceArrayAggRows, reduceFlatRows, shouldSqliteUseGet, transformAggregateRow, transformQueryResults };
8929
9104
  //# sourceMappingURL=index.js.map
8930
9105
  //# sourceMappingURL=index.js.map