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