@prisma/orm-family-sql 8.0.0-rc.1-dev.46 → 8.0.0-rc.10-dev.1

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.
Files changed (207) hide show
  1. package/README.md +2 -6
  2. package/dist/{ast-Lbl4VwqP.mjs → ast-5tg0fGPQ.mjs} +2 -58
  3. package/dist/ast-5tg0fGPQ.mjs.map +1 -0
  4. package/dist/{ast-HFcfQZr-.d.mts → ast-DuLukI6f.d.mts} +4 -36
  5. package/dist/ast-DuLukI6f.d.mts.map +1 -0
  6. package/dist/{authored-check-naming-Hf9990DV.mjs → authored-check-naming-BEvfamnI.mjs} +2 -2
  7. package/dist/{authored-check-naming-Hf9990DV.mjs.map → authored-check-naming-BEvfamnI.mjs.map} +1 -1
  8. package/dist/{authoring-type-constructors-Blqoa2Ua-DqvNCOb2.mjs → authoring-type-constructors-BD-XuavC-CJV-TxFh.mjs} +10 -4
  9. package/dist/authoring-type-constructors-BD-XuavC-CJV-TxFh.mjs.map +1 -0
  10. package/dist/builder.d.mts +3 -3
  11. package/dist/builder__runtime.d.mts +26 -9
  12. package/dist/builder__runtime.d.mts.map +1 -1
  13. package/dist/builder__runtime.mjs +18 -9
  14. package/dist/builder__runtime.mjs.map +1 -1
  15. package/dist/builder__types.d.mts +3 -3
  16. package/dist/{codec-descriptor-registry-N0dhtKaH.mjs → codec-descriptor-registry-ECZ4ohtG.mjs} +2 -2
  17. package/dist/{codec-descriptor-registry-N0dhtKaH.mjs.map → codec-descriptor-registry-ECZ4ohtG.mjs.map} +1 -1
  18. package/dist/{config-types-gAm54C_v.mjs → config-types-BNJgLUUQ.mjs} +2 -2
  19. package/dist/{config-types-gAm54C_v.mjs.map → config-types-BNJgLUUQ.mjs.map} +1 -1
  20. package/dist/{config-types-D9fdKG3g.d.mts → config-types-Bd3ud-mX.d.mts} +3 -3
  21. package/dist/{config-types-D9fdKG3g.d.mts.map → config-types-Bd3ud-mX.d.mts.map} +1 -1
  22. package/dist/{contract-builder-D4a5dT7j.mjs → contract-builder-BOmEsrRi.mjs} +24 -5
  23. package/dist/contract-builder-BOmEsrRi.mjs.map +1 -0
  24. package/dist/{contract-builder-CG_tGDbB.d.mts → contract-builder-De_sioHE.d.mts} +15 -3
  25. package/dist/contract-builder-De_sioHE.d.mts.map +1 -0
  26. package/dist/contract-emitter.mjs +1 -1
  27. package/dist/contract-psl.d.mts +1 -1
  28. package/dist/contract-psl.mjs +1 -1
  29. package/dist/contract-psl__attribute-specs.d.mts +77 -0
  30. package/dist/contract-psl__attribute-specs.d.mts.map +1 -0
  31. package/dist/contract-psl__attribute-specs.mjs +2 -0
  32. package/dist/contract-psl__provider.d.mts +1 -1
  33. package/dist/contract-psl__provider.mjs +3 -3
  34. package/dist/contract-psl__provider.mjs.map +1 -1
  35. package/dist/contract-ts.d.mts +3 -3
  36. package/dist/contract-ts.mjs +3 -3
  37. package/dist/contract-ts__config-types.d.mts +1 -1
  38. package/dist/contract-ts__config-types.mjs +1 -1
  39. package/dist/contract-ts__contract-builder.d.mts +2 -2
  40. package/dist/contract-ts__contract-builder.mjs +2 -2
  41. package/dist/contract.d.mts +3 -3
  42. package/dist/contract.mjs +6 -6
  43. package/dist/contract__authored-check-naming.mjs +1 -1
  44. package/dist/contract__foreign-key-materialization.mjs +1 -1
  45. package/dist/contract__index-naming.mjs +1 -1
  46. package/dist/contract__types.d.mts +2 -2
  47. package/dist/contract__types.mjs +2 -2
  48. package/dist/contract__validators.d.mts +2 -2
  49. package/dist/contract__validators.mjs +2 -2
  50. package/dist/{control-D3cB5YQp.mjs → control-BIIMOKMy.mjs} +11 -9
  51. package/dist/control-BIIMOKMy.mjs.map +1 -0
  52. package/dist/{control-adapter-C99J7aEF-B7eQd7vD.d.mts → control-adapter-C99J7aEF-GODO43Ai.d.mts} +5 -5
  53. package/dist/{control-adapter-C99J7aEF-B7eQd7vD.d.mts.map → control-adapter-C99J7aEF-GODO43Ai.d.mts.map} +1 -1
  54. package/dist/control-adapter-DzTFiMaG.d.mts +1 -0
  55. package/dist/{control-DTLJ1WtZ.d.mts → control-b-6t8eI_.d.mts} +138 -19
  56. package/dist/control-b-6t8eI_.d.mts.map +1 -0
  57. package/dist/{db-D18PrXKW-DvTv4JFn.d.mts → db-BhQdL6Za-DubRGJvv.d.mts} +86 -62
  58. package/dist/{db-D18PrXKW-DvTv4JFn.d.mts.map → db-BhQdL6Za-DubRGJvv.d.mts.map} +1 -1
  59. package/dist/{ddl-types-CXx4vPz6-BsgrnSUY.d.mts → ddl-types-CXx4vPz6-Dko-GTTj.d.mts} +3 -3
  60. package/dist/{ddl-types-CXx4vPz6-BsgrnSUY.d.mts.map → ddl-types-CXx4vPz6-Dko-GTTj.d.mts.map} +1 -1
  61. package/dist/{derived-checks-DFMRmiAu-DGfB8aS4.mjs → derived-checks-DGjY5t7S-B3txNm7X.mjs} +48 -15
  62. package/dist/derived-checks-DGjY5t7S-B3txNm7X.mjs.map +1 -0
  63. package/dist/{derived-checks-DPdD01O0-DGqOFjs6.d.mts → derived-checks-DPdD01O0-DNBs1ZDA.d.mts} +2 -2
  64. package/dist/{derived-checks-DPdD01O0-DGqOFjs6.d.mts.map → derived-checks-DPdD01O0-DNBs1ZDA.d.mts.map} +1 -1
  65. package/dist/{diff-DbTNVm2f.d.mts → diff-CN1ou7vM.d.mts} +5 -5
  66. package/dist/{diff-DbTNVm2f.d.mts.map → diff-CN1ou7vM.d.mts.map} +1 -1
  67. package/dist/{dist-ZK6oeI5e.mjs → dist-D5__KJs-.mjs} +2 -1
  68. package/dist/dist-D5__KJs-.mjs.map +1 -0
  69. package/dist/{expression-CX5mTA-z.mjs → expression-B2Ox7zKM.mjs} +6 -2
  70. package/dist/expression-B2Ox7zKM.mjs.map +1 -0
  71. package/dist/{expression-FJK6Ar-d.d.mts → expression-mku9I7Ue.d.mts} +16 -7
  72. package/dist/{expression-FJK6Ar-d.d.mts.map → expression-mku9I7Ue.d.mts.map} +1 -1
  73. package/dist/family.d.mts +10 -10
  74. package/dist/family.mjs +8 -8
  75. package/dist/family__control-adapter.d.mts +2 -2
  76. package/dist/family__control.d.mts +4 -4
  77. package/dist/family__control.mjs +4 -4
  78. package/dist/family__diff.d.mts +2 -2
  79. package/dist/family__diff.mjs +1 -1
  80. package/dist/family__ir.d.mts +1 -1
  81. package/dist/family__ir.mjs +1 -1
  82. package/dist/family__migration.d.mts +1 -1
  83. package/dist/family__pack.d.mts +72 -0
  84. package/dist/family__pack.d.mts.map +1 -1
  85. package/dist/family__pack.mjs +4 -2
  86. package/dist/family__pack.mjs.map +1 -1
  87. package/dist/family__psl-infer.mjs +1 -1
  88. package/dist/family__runtime.d.mts +1 -1
  89. package/dist/family__runtime.mjs +1 -1
  90. package/dist/family__verify.mjs +1 -1
  91. package/dist/{foreign-key-materialization-Cu7-7LHl.mjs → foreign-key-materialization-0TrwfShD.mjs} +2 -2
  92. package/dist/{foreign-key-materialization-Cu7-7LHl.mjs.map → foreign-key-materialization-0TrwfShD.mjs.map} +1 -1
  93. package/dist/{index-C5I8D-MB.d.mts → index-CLAshwKN.d.mts} +2 -2
  94. package/dist/{index-C5I8D-MB.d.mts.map → index-CLAshwKN.d.mts.map} +1 -1
  95. package/dist/{index-C-vQOMY_.d.mts → index-DzBzeTAy.d.mts} +10 -10
  96. package/dist/{index-C-vQOMY_.d.mts.map → index-DzBzeTAy.d.mts.map} +1 -1
  97. package/dist/{index-naming-DREt6js7-CRH27yUv.mjs → index-naming-fQMLqyC4-4FzPVtCR.mjs} +4 -4
  98. package/dist/index-naming-fQMLqyC4-4FzPVtCR.mjs.map +1 -0
  99. package/dist/{interpreter-DyiUUAWh-DYdjIpiE.mjs → interpreter-CZ_iVQV4-CJ6COgSE.mjs} +123 -302
  100. package/dist/interpreter-CZ_iVQV4-CJ6COgSE.mjs.map +1 -0
  101. package/dist/ir-I-xciGUH.mjs.map +1 -1
  102. package/dist/{ir-Bghjt-FG.d.mts → ir-R9GE8gsm.d.mts} +2 -2
  103. package/dist/{ir-Bghjt-FG.d.mts.map → ir-R9GE8gsm.d.mts.map} +1 -1
  104. package/dist/{middleware-AhTz1BOW-th-Suxuf.d.mts → middleware-AhTz1BOW-CtQWS4mb.d.mts} +2 -2
  105. package/dist/{middleware-AhTz1BOW-th-Suxuf.d.mts.map → middleware-AhTz1BOW-CtQWS4mb.d.mts.map} +1 -1
  106. package/dist/middleware-Cev-ZFyS.d.mts +1 -0
  107. package/dist/{migration-CjDRZNep.d.mts → migration-Bhce5i_m.d.mts} +3 -3
  108. package/dist/{migration-CjDRZNep.d.mts.map → migration-Bhce5i_m.d.mts.map} +1 -1
  109. package/dist/operations.d.mts +1 -1
  110. package/dist/orm-client.d.mts +131 -95
  111. package/dist/orm-client.d.mts.map +1 -1
  112. package/dist/orm-client.mjs +1021 -942
  113. package/dist/orm-client.mjs.map +1 -1
  114. package/dist/plan-C7VP7jOh.d.mts +2 -0
  115. package/dist/{plan-CDxduYaN-pLIyyJaB.d.mts → plan-CDxduYaN-B2kMLIQQ.d.mts} +3 -3
  116. package/dist/{plan-CDxduYaN-pLIyyJaB.d.mts.map → plan-CDxduYaN-B2kMLIQQ.d.mts.map} +1 -1
  117. package/dist/{prepared-statement-9QpkE6JG-C430V3MO.d.mts → prepared-statement-9QpkE6JG-B9xqBu5T.d.mts} +16 -16
  118. package/dist/{prepared-statement-9QpkE6JG-C430V3MO.d.mts.map → prepared-statement-9QpkE6JG-B9xqBu5T.d.mts.map} +1 -1
  119. package/dist/{psl-infer-Dk5kgKre.mjs → psl-infer-TBwKfKgU.mjs} +2 -2
  120. package/dist/{psl-infer-Dk5kgKre.mjs.map → psl-infer-TBwKfKgU.mjs.map} +1 -1
  121. package/dist/query-lane-context-CGdMIEuv.d.mts +1 -0
  122. package/dist/{query-lane-context-Qa-eddrE-kuZ8Z86-.d.mts → query-lane-context-Qa-eddrE-BQV6J9nV.d.mts} +4 -4
  123. package/dist/{query-lane-context-Qa-eddrE-kuZ8Z86-.d.mts.map → query-lane-context-Qa-eddrE-BQV6J9nV.d.mts.map} +1 -1
  124. package/dist/relational-core.d.mts +12 -12
  125. package/dist/relational-core.mjs +3 -3
  126. package/dist/relational-core__aggregate-descriptor-registry.d.mts +1 -1
  127. package/dist/relational-core__ast.d.mts +4 -4
  128. package/dist/relational-core__ast.mjs +2 -2
  129. package/dist/relational-core__codec-descriptor-registry.d.mts +3 -3
  130. package/dist/relational-core__codec-descriptor-registry.mjs +1 -1
  131. package/dist/relational-core__contract-free.d.mts +3 -3
  132. package/dist/relational-core__expression.d.mts +1 -1
  133. package/dist/relational-core__expression.mjs +1 -1
  134. package/dist/relational-core__middleware.d.mts +2 -2
  135. package/dist/relational-core__plan.d.mts +3 -3
  136. package/dist/relational-core__query-lane-context.d.mts +2 -2
  137. package/dist/relational-core__types.d.mts +2 -2
  138. package/dist/{runtime-DpKF2Yu2.d.mts → runtime-CzCx0TKe.d.mts} +3 -3
  139. package/dist/{runtime-DpKF2Yu2.d.mts.map → runtime-CzCx0TKe.d.mts.map} +1 -1
  140. package/dist/{runtime-tIHpGCcG.mjs → runtime-PknWErjr.mjs} +2 -2
  141. package/dist/{runtime-tIHpGCcG.mjs.map → runtime-PknWErjr.mjs.map} +1 -1
  142. package/dist/runtime.d.mts +4 -4
  143. package/dist/runtime.mjs +2 -2
  144. package/dist/runtime__internal__prepared-query.d.mts +1 -1
  145. package/dist/{schema-differ-DpG_gnur-DFAtGezx.d.mts → schema-differ-DpG_gnur-BICVtTHY.d.mts} +2 -2
  146. package/dist/{schema-differ-DpG_gnur-DFAtGezx.d.mts.map → schema-differ-DpG_gnur-BICVtTHY.d.mts.map} +1 -1
  147. package/dist/schema-ir.mjs +1 -1
  148. package/dist/schema-ir__types.mjs +1 -1
  149. package/dist/{schema-verify-C_PEdlAr-Dxxjm6EM.mjs → schema-verify-C_PEdlAr-CmXrFuW1.mjs} +2 -2
  150. package/dist/{schema-verify-C_PEdlAr-Dxxjm6EM.mjs.map → schema-verify-C_PEdlAr-CmXrFuW1.mjs.map} +1 -1
  151. package/dist/sql-attribute-specs-CG0yitvD-CG-0eW98.mjs +275 -0
  152. package/dist/sql-attribute-specs-CG0yitvD-CG-0eW98.mjs.map +1 -0
  153. package/dist/{sql-contract-serializer-2oBWuxTe-DKZTf2n8.mjs → sql-contract-serializer-Bxu4a5oQ-D0lKpb4a.mjs} +24 -5
  154. package/dist/sql-contract-serializer-Bxu4a5oQ-D0lKpb4a.mjs.map +1 -0
  155. package/dist/{sql-execution-plan--jKyLpe5-CMGhgO0M.d.mts → sql-execution-plan--jKyLpe5-Bcz9QM2s.d.mts} +2 -2
  156. package/dist/{sql-execution-plan--jKyLpe5-CMGhgO0M.d.mts.map → sql-execution-plan--jKyLpe5-Bcz9QM2s.d.mts.map} +1 -1
  157. package/dist/{timestamp-now-generator-DRXygu32-DN9Qb1uI.mjs → timestamp-now-generator-BZnBo7IC-DbN5Apqe.mjs} +27 -19
  158. package/dist/timestamp-now-generator-BZnBo7IC-DbN5Apqe.mjs.map +1 -0
  159. package/dist/{types-4YenawkP-CwaaZSid.mjs → types-BvupgHcG-c8QDupnu.mjs} +13 -6
  160. package/dist/types-BvupgHcG-c8QDupnu.mjs.map +1 -0
  161. package/dist/{types-UcHa2cTe.d.mts → types-C36_3E6_.d.mts} +3 -2
  162. package/dist/types-C36_3E6_.d.mts.map +1 -0
  163. package/dist/{types-CyxGtOOh-BggSa6Fe.d.mts → types-CyxGtOOh-BJnoWm0f.d.mts} +8 -8
  164. package/dist/{types-CyxGtOOh-BggSa6Fe.d.mts.map → types-CyxGtOOh-BJnoWm0f.d.mts.map} +1 -1
  165. package/dist/{types-CUsJrvEl.mjs → types-D0B65hip.mjs} +3 -2
  166. package/dist/types-D0B65hip.mjs.map +1 -0
  167. package/dist/types-DvsoMNLs.d.mts +1 -0
  168. package/dist/{types-IqZMLrFC-DcH8v_u3.d.mts → types-IqZMLrFC-BIRftuU7.d.mts} +4 -4
  169. package/dist/{types-IqZMLrFC-DcH8v_u3.d.mts.map → types-IqZMLrFC-BIRftuU7.d.mts.map} +1 -1
  170. package/dist/{types-v3qxLLxo-DCeKv7yY.d.mts → types-v3qxLLxo-Clw_yBAh.d.mts} +2 -2
  171. package/dist/{types-v3qxLLxo-DCeKv7yY.d.mts.map → types-v3qxLLxo-Clw_yBAh.d.mts.map} +1 -1
  172. package/dist/{validators-Belo8QqM.d.mts → validators-CbqMxQfW.d.mts} +23 -4
  173. package/dist/validators-CbqMxQfW.d.mts.map +1 -0
  174. package/dist/{validators-CrWD6bSP.mjs → validators-DD98VrpC.mjs} +0 -0
  175. package/dist/validators-DD98VrpC.mjs.map +1 -0
  176. package/dist/{verify-u0UTdZgD-DSAaz9rW.mjs → verify-ChiDeTk8-HEewdjrM.mjs} +3 -3
  177. package/dist/verify-ChiDeTk8-HEewdjrM.mjs.map +1 -0
  178. package/package.json +20 -21
  179. package/dist/ast-HFcfQZr-.d.mts.map +0 -1
  180. package/dist/ast-Lbl4VwqP.mjs.map +0 -1
  181. package/dist/authoring-type-constructors-Blqoa2Ua-DqvNCOb2.mjs.map +0 -1
  182. package/dist/contract-builder-CG_tGDbB.d.mts.map +0 -1
  183. package/dist/contract-builder-D4a5dT7j.mjs.map +0 -1
  184. package/dist/control-D3cB5YQp.mjs.map +0 -1
  185. package/dist/control-DTLJ1WtZ.d.mts.map +0 -1
  186. package/dist/control-adapter-MZJQiwcE.d.mts +0 -1
  187. package/dist/derived-checks-DFMRmiAu-DGfB8aS4.mjs.map +0 -1
  188. package/dist/dist-ZK6oeI5e.mjs.map +0 -1
  189. package/dist/expression-CX5mTA-z.mjs.map +0 -1
  190. package/dist/index-naming-DREt6js7-CRH27yUv.mjs.map +0 -1
  191. package/dist/interpreter-DyiUUAWh-DYdjIpiE.mjs.map +0 -1
  192. package/dist/lane-query-builder.d.mts +0 -236
  193. package/dist/lane-query-builder.d.mts.map +0 -1
  194. package/dist/lane-query-builder.mjs +0 -67
  195. package/dist/lane-query-builder.mjs.map +0 -1
  196. package/dist/middleware--TtoxUiW.d.mts +0 -1
  197. package/dist/plan-BHLdb0Z7.d.mts +0 -2
  198. package/dist/query-lane-context-XMvk7fmY.d.mts +0 -1
  199. package/dist/sql-contract-serializer-2oBWuxTe-DKZTf2n8.mjs.map +0 -1
  200. package/dist/timestamp-now-generator-DRXygu32-DN9Qb1uI.mjs.map +0 -1
  201. package/dist/types-4YenawkP-CwaaZSid.mjs.map +0 -1
  202. package/dist/types-B0msOnBM.d.mts +0 -1
  203. package/dist/types-CUsJrvEl.mjs.map +0 -1
  204. package/dist/types-UcHa2cTe.d.mts.map +0 -1
  205. package/dist/validators-Belo8QqM.d.mts.map +0 -1
  206. package/dist/validators-CrWD6bSP.mjs.map +0 -1
  207. package/dist/verify-u0UTdZgD-DSAaz9rW.mjs.map +0 -1
@@ -2,15 +2,15 @@ import { t as resolveStorageTable } from "./resolve-storage-table-DZsfnzeW.mjs";
2
2
  import { i as isUniqueConstraintViolation } from "./dist-x6jvtkKM.mjs";
3
3
  import { C as LiteralExpr, D as OrExpr, F as SubqueryExpr, I as TableSource, L as UpdateAst, O as OrderByItem, P as SelectAst, R as WindowFuncExpr, S as ListExpression, T as NullCheckExpr, U as isWhereExpr, V as isAggregateFn, _ as InsertAst, b as JsonArrayAggExpr, c as DeleteAst, f as EqColJoinOn, j as ProjectionItem, k as ParamRef, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, s as DefaultValueExpr, t as AggregateExpr, v as InsertOnConflict, w as NotExpr, x as JsonObjectExpr, y as JoinAst } from "./types-Dt4e_jC--COeP8xzN.mjs";
4
4
  import { t as collectOrderedParamRefs } from "./util-DQQgv2j1-D6INZaRG.mjs";
5
- import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast-Lbl4VwqP.mjs";
6
- import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-N0dhtKaH.mjs";
5
+ import { n as JsonDocumentProjection, r as NativeJsonValueProjection, t as CodecJsonValueProjection } from "./ast-5tg0fGPQ.mjs";
6
+ import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-ECZ4ohtG.mjs";
7
7
  import { structuredError } from "@prisma/orm-framework/utils/structured-error";
8
8
  import { InternalError } from "@prisma/orm-framework/utils/internal-error";
9
9
  import { domainModelsAtDefaultNamespace } from "@prisma/orm-framework/contract/types";
10
10
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
11
+ import { AsyncIterableResult, createMetaBuilder, isRuntimeError, runtimeError } from "@prisma/orm-framework/components/runtime";
11
12
  import { blindCast, castAs } from "@prisma/orm-framework/utils/casts";
12
13
  import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
13
- import { AsyncIterableResult, createMetaBuilder, isRuntimeError, runtimeError } from "@prisma/orm-framework/components/runtime";
14
14
  //#region ../../../3-extensions/sql-orm-client/dist/index.mjs
15
15
  const operationNamesByRegistry = /* @__PURE__ */ new WeakMap();
16
16
  /**
@@ -139,9 +139,6 @@ function resolveFieldToColumn(contract, namespaceId, modelName, fieldName) {
139
139
  * base-table field map. Base fields are intentionally absent so callers can
140
140
  * gate variant qualification strictly to variant-owned fields.
141
141
  *
142
- * `baseModelName` is a default-namespace model name, consistent with the rest
143
- * of this module; namespace context is bound downstream at table resolution.
144
- *
145
142
  * Uncached on purpose: `resolvePolymorphismInfo` already memoizes the variant
146
143
  * lookup, and the remaining work is one pass over the variant's field→column
147
144
  * map, so a second cache layer would buy nothing.
@@ -190,8 +187,7 @@ function getColumnToFieldMap(contract, namespaceId, modelName) {
190
187
  }
191
188
  const completeColumnToFieldCache = /* @__PURE__ */ new WeakMap();
192
189
  /**
193
- * Like getColumnToFieldMap but includes identity-mapped fields (where field name equals column
194
- * name). getColumnToFieldMap only returns explicit remaps; this returns ALL column→field entries.
190
+ * Like getColumnToFieldMap, but a field without a storage `column` maps under its own name.
195
191
  */
196
192
  function getCompleteColumnToFieldMap(contract, namespaceId, modelName) {
197
193
  let perContract = completeColumnToFieldCache.get(contract);
@@ -346,6 +342,13 @@ function assertReturningCapability(contract, action) {
346
342
  action
347
343
  } });
348
344
  }
345
+ function assertDistinctOnCapability(contract, methodName) {
346
+ if (contract.capabilities["postgres"]?.["distinctOn"] === true) return;
347
+ throw ormError("ORM.CAPABILITY_MISSING", `${methodName}() requires capability postgres.distinctOn`, { meta: {
348
+ capability: "postgres.distinctOn",
349
+ method: methodName
350
+ } });
351
+ }
349
352
  function hasContractCapability(contract, capability) {
350
353
  const capabilities = contract.capabilities;
351
354
  const value = capabilities[capability];
@@ -537,16 +540,6 @@ function mapResultRows(result, mapper) {
537
540
  };
538
541
  return new AsyncIterableResult(generator());
539
542
  }
540
- async function acquireRuntimeScope(runtime) {
541
- if (typeof runtime.connection !== "function") return { scope: runtime };
542
- const connection = await runtime.connection();
543
- const release = connection.release;
544
- if (typeof release === "function") return {
545
- scope: connection,
546
- release: () => release.call(connection) ?? Promise.resolve()
547
- };
548
- return { scope: connection };
549
- }
550
543
  function deriveParamsFromAst(ast) {
551
544
  return { params: collectOrderedParamRefs(ast).map((p) => p.kind === "param-ref" ? p.value : void 0) };
552
545
  }
@@ -591,8 +584,8 @@ function buildOrmQueryPlan(contract, ast, params, annotations) {
591
584
  * terminals where annotations arrive at the call site, not via state.
592
585
  *
593
586
  * Returns the input plan unchanged when `annotations` is undefined
594
- * or empty. Reserved framework namespaces (`codecs`, `limit`) on the
595
- * input plan win over caller-supplied entries under the same key —
587
+ * or empty. Reserved namespaces already on the input plan (`codecs`, target keys such as `pg`)
588
+ * win over caller-supplied entries under the same key —
596
589
  * see the reserved-namespace policy on `defineAnnotation`.
597
590
  */
598
591
  function mergeAnnotations(plan, annotations) {
@@ -611,202 +604,626 @@ function mergeAnnotations(plan, annotations) {
611
604
  })
612
605
  });
613
606
  }
614
- function combineWhereExprs(filters) {
615
- if (filters.length === 0) return;
616
- if (filters.length === 1) return filters[0];
617
- return AndExpr.of(filters);
618
- }
619
- function toAggregateProjection(contract, aggregates, namespaceId, tableName, selector) {
620
- const { codec, input: inputCodec, lower } = resolveAggregate({
621
- aggregates,
622
- contract,
623
- namespaceId,
624
- tableName,
625
- fn: selector.fn,
626
- column: selector.column
627
- });
628
- const inputExpr = selector.column === void 0 ? void 0 : ColumnRef.of(tableName, selector.column);
629
- return {
630
- expr: lower !== void 0 ? lower({
631
- expr: inputExpr,
632
- inputCodec
633
- }) : plainAggregateExpr(selector.fn, inputExpr),
634
- codec
635
- };
636
- }
637
- function validateGroupedComparable(value) {
638
- switch (value.kind) {
639
- case "param-ref": throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: value.kind } });
640
- case "literal":
641
- case "column-ref":
642
- case "identifier-ref":
643
- case "aggregate":
644
- case "operation": return value;
645
- case "function-call":
646
- case "cast":
647
- case "case": throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported comparable kind in grouped having: "${value.kind}"`, { meta: { kind: value.kind } });
648
- case "list":
649
- if (value.values.some((entry) => entry.kind === "param-ref")) throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: "list" } });
650
- return value;
651
- default: throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported comparable kind in grouped having: "${value.kind}"`, { meta: { kind: value.kind } });
652
- }
653
- }
654
- function validateGroupedMetricExpr(expr) {
655
- if (expr.kind !== "aggregate") throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "groupBy().having() only supports aggregate metric expressions", { meta: { kind: expr.kind } });
656
- return expr;
607
+ function namespaceCoordinateForSource(source) {
608
+ return source.kind === "table-source" ? source.namespaceId : void 0;
657
609
  }
658
- function rejectHavingExpr(expr) {
659
- throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported grouped having expression kind "${expr.kind}"`, { meta: { kind: expr.kind } });
610
+ function bindWhereExpr(contract, expr, namespaceId) {
611
+ return bindWhereExprNode(contract, expr, namespaceId);
660
612
  }
661
- function validateGroupedHavingExpr(expr) {
613
+ function bindWhereExprNode(contract, expr, namespaceId) {
662
614
  return expr.accept({
663
- columnRef: rejectHavingExpr,
664
- identifierRef: rejectHavingExpr,
665
- subquery: rejectHavingExpr,
666
- operation: rejectHavingExpr,
667
- aggregate: rejectHavingExpr,
668
- windowFunc: rejectHavingExpr,
669
- functionCall: rejectHavingExpr,
670
- cast: rejectHavingExpr,
671
- case: rejectHavingExpr,
672
- jsonObject: rejectHavingExpr,
673
- jsonArrayAgg: rejectHavingExpr,
674
- literal: rejectHavingExpr,
675
- param() {
676
- throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: "param-ref" } });
615
+ columnRef(expr) {
616
+ return bindExpression(contract, expr);
677
617
  },
678
- preparedParam() {
679
- throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "PreparedParamRef is not supported in grouped having expressions", { meta: { kind: "prepared-param-ref" } });
618
+ identifierRef(expr) {
619
+ return expr;
620
+ },
621
+ subquery(expr) {
622
+ return bindExpression(contract, expr);
623
+ },
624
+ operation(expr) {
625
+ return bindExpression(contract, expr);
626
+ },
627
+ aggregate(expr) {
628
+ return bindExpression(contract, expr);
629
+ },
630
+ windowFunc(expr) {
631
+ return bindExpression(contract, expr);
632
+ },
633
+ functionCall(expr) {
634
+ return bindExpression(contract, expr);
635
+ },
636
+ cast(expr) {
637
+ return bindExpression(contract, expr);
638
+ },
639
+ case(expr) {
640
+ return bindExpression(contract, expr);
641
+ },
642
+ jsonObject(expr) {
643
+ return bindExpression(contract, expr);
644
+ },
645
+ jsonArrayAgg(expr) {
646
+ return bindExpression(contract, expr);
647
+ },
648
+ literal(expr) {
649
+ return expr;
650
+ },
651
+ param(expr) {
652
+ return expr;
653
+ },
654
+ preparedParam(expr) {
655
+ return expr;
656
+ },
657
+ list(expr) {
658
+ return bindExpression(contract, expr);
659
+ },
660
+ binary(expr) {
661
+ const left = bindExpression(contract, expr.left);
662
+ const bindingColumn = left.kind === "column-ref" ? left : void 0;
663
+ return new BinaryExpr(expr.op, left, bindComparable(contract, expr.right, bindingColumn, namespaceId));
680
664
  },
681
- list: rejectHavingExpr,
682
665
  and(expr) {
683
- return AndExpr.of(expr.exprs.map((child) => validateGroupedHavingExpr(child)));
666
+ return AndExpr.of(expr.exprs.map((part) => bindWhereExprNode(contract, part, namespaceId)));
684
667
  },
685
668
  or(expr) {
686
- return OrExpr.of(expr.exprs.map((child) => validateGroupedHavingExpr(child)));
669
+ return OrExpr.of(expr.exprs.map((part) => bindWhereExprNode(contract, part, namespaceId)));
670
+ },
671
+ exists(expr) {
672
+ return expr.notExists ? ExistsExpr.notExists(bindSelectAst(contract, expr.subquery)) : ExistsExpr.exists(bindSelectAst(contract, expr.subquery));
687
673
  },
688
- exists: rejectHavingExpr,
689
674
  nullCheck(expr) {
690
- return new NullCheckExpr(validateGroupedMetricExpr(expr.expr), expr.isNull);
675
+ return expr.isNull ? NullCheckExpr.isNull(bindExpression(contract, expr.expr)) : NullCheckExpr.isNotNull(bindExpression(contract, expr.expr));
691
676
  },
692
677
  not(expr) {
693
- return new NotExpr(validateGroupedHavingExpr(expr.expr));
694
- },
695
- binary(expr) {
696
- return new BinaryExpr(expr.op, validateGroupedMetricExpr(expr.left), validateGroupedComparable(expr.right));
678
+ return new NotExpr(bindWhereExprNode(contract, expr.expr, namespaceId));
697
679
  },
698
- rawExpr: rejectHavingExpr
680
+ rawExpr(expr) {
681
+ return expr;
682
+ }
699
683
  });
700
684
  }
701
- function compileAggregate(contract, aggregates, namespaceId, tableName, filters, aggregateSpec) {
702
- const entries = Object.entries(aggregateSpec);
703
- if (entries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "aggregate() requires at least one aggregation selector", { meta: {
704
- method: "aggregate",
705
- namespaceId,
706
- tableName
707
- } });
708
- const projection = entries.map(([alias, selector]) => {
709
- const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
710
- return ProjectionItem.of(alias, expr, codec);
711
- });
712
- let ast = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection(projection);
713
- const where = combineWhereExprs(filters);
714
- if (where) ast = ast.withWhere(where);
715
- const { params } = deriveParamsFromAst(ast);
716
- return buildOrmQueryPlan(contract, ast, params);
685
+ function bindComparable(contract, comparable, bindingColumn, namespaceId) {
686
+ if (comparable.kind === "param-ref" || bindingColumn === void 0) return comparable.kind === "param-ref" ? comparable : comparable.kind === "literal" || comparable.kind === "list" ? comparable : bindExpression(contract, comparable);
687
+ if (comparable.kind === "literal") return createParamRef(contract, bindingColumn, comparable.value, namespaceId);
688
+ if (comparable.kind === "list") return ListExpression.of(comparable.values.map((value) => value.kind === "literal" ? createParamRef(contract, bindingColumn, value.value, namespaceId) : value));
689
+ return bindExpression(contract, comparable);
717
690
  }
718
- function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, filters, groupByColumns, aggregateSpec, havingExpr) {
719
- if (groupByColumns.length === 0) throw ormError("ORM.GROUP_BY_FIELD_MISSING", "groupBy() requires at least one field", { meta: {
720
- namespaceId,
721
- tableName
722
- } });
723
- const entries = Object.entries(aggregateSpec);
724
- if (entries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "groupBy().aggregate() requires at least one aggregation selector", { meta: {
725
- method: "groupBy.aggregate",
726
- namespaceId,
727
- tableName
691
+ function createParamRef(contract, columnRef, value, namespaceId) {
692
+ const resolved = resolveStorageTable(contract.storage, columnRef.table, namespaceId);
693
+ if (resolved === void 0 || !resolved.table.columns[columnRef.column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${columnRef.column}" in table "${columnRef.table}"`, { meta: {
694
+ tableName: columnRef.table,
695
+ column: columnRef.column
728
696
  } });
729
- const projection = [...groupByColumns.map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column))), ...entries.map(([alias, selector]) => {
730
- const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
731
- return ProjectionItem.of(alias, expr, codec);
732
- })];
733
- let ast = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection(projection).withGroupBy(groupByColumns.map((column) => ColumnRef.of(tableName, column)));
734
- const where = combineWhereExprs(filters);
735
- if (where) ast = ast.withWhere(where);
736
- if (havingExpr) ast = ast.withHaving(validateGroupedHavingExpr(havingExpr));
737
- const { params } = deriveParamsFromAst(ast);
738
- return buildOrmQueryPlan(contract, ast, params);
739
- }
740
- function buildReturningColumns(contract, namespaceId, tableName, returningColumns) {
741
- return (returningColumns && returningColumns.length > 0 ? [...returningColumns] : resolveTableColumns(contract, namespaceId, tableName)).map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
697
+ const codec = codecRefForStorageColumn(contract.storage, resolved.namespaceId, columnRef.table, columnRef.column);
698
+ return ParamRef.of(value, codec ? { codec } : void 0);
742
699
  }
743
- function toParamAssignments(contract, namespaceId, tableName, values) {
744
- const assignments = {};
745
- const table = storageTableForContract(contract, namespaceId, tableName);
746
- for (const [column, value] of Object.entries(values)) {
747
- if (!table.columns[column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${column}" in table "${tableName}"`, { meta: {
748
- namespaceId,
749
- tableName,
750
- column
751
- } });
752
- const codec = codecRefForStorageColumn(contract.storage, namespaceId, tableName, column);
753
- assignments[column] = ParamRef.of(value, {
754
- name: column,
755
- ...ifDefined("codec", codec)
756
- });
757
- }
758
- return { assignments };
700
+ function createExpressionBinder(contract) {
701
+ return { select: (ast) => bindSelectAst(contract, ast) };
759
702
  }
760
- function normalizeInsertRows(contract, namespaceId, tableName, rows) {
761
- if (rows.length === 0) throw new InternalError("normalizeInsertRows requires at least one row");
762
- const orderedColumns = [];
763
- const seenColumns = /* @__PURE__ */ new Set();
764
- for (const row of rows) for (const column of Object.keys(row)) {
765
- if (seenColumns.has(column)) continue;
766
- seenColumns.add(column);
767
- orderedColumns.push(column);
768
- }
769
- const table = storageTableForContract(contract, namespaceId, tableName);
770
- return { rows: rows.map((row) => {
771
- if (orderedColumns.length === 0) return {};
772
- const normalizedRow = {};
773
- for (const column of orderedColumns) {
774
- if (Object.hasOwn(row, column)) {
775
- if (!table.columns[column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${column}" in table "${tableName}"`, { meta: {
776
- namespaceId,
777
- tableName,
778
- column
779
- } });
780
- const codec = codecRefForStorageColumn(contract.storage, namespaceId, tableName, column);
781
- normalizedRow[column] = ParamRef.of(row[column], {
782
- name: column,
783
- ...ifDefined("codec", codec)
784
- });
785
- continue;
786
- }
787
- normalizedRow[column] = new DefaultValueExpr();
788
- }
789
- return normalizedRow;
790
- }) };
703
+ function bindExpression(contract, expr) {
704
+ return expr.rewrite(createExpressionBinder(contract));
791
705
  }
792
- function compileInsertReturning(contract, namespaceId, tableName, rows, returningColumns) {
793
- const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
794
- const ast = InsertAst.into(tableSourceForContract(contract, namespaceId, tableName)).withRows(normalizedRows).withReturning(buildReturningColumns(contract, namespaceId, tableName, returningColumns));
795
- const { params } = deriveParamsFromAst(ast);
796
- return buildOrmQueryPlan(contract, ast, params);
706
+ function bindProjectionExpr(contract, expr) {
707
+ return expr.kind === "literal" ? expr : bindExpression(contract, expr);
797
708
  }
798
- function compileInsertCount(contract, namespaceId, tableName, rows) {
799
- const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
800
- const ast = InsertAst.into(tableSourceForContract(contract, namespaceId, tableName)).withRows(normalizedRows);
801
- const { params } = deriveParamsFromAst(ast);
802
- return buildOrmQueryPlan(contract, ast, params);
709
+ function bindOrderByItem(contract, orderItem) {
710
+ return new OrderByItem(bindExpression(contract, orderItem.expr), orderItem.dir);
803
711
  }
804
- function stripUndefinedValues(row) {
712
+ function bindJoin(contract, join) {
713
+ const namespaceId = namespaceCoordinateForSource(join.source);
714
+ return new JoinAst(join.joinType, bindFromSource(contract, join.source), join.on.kind === "eq-col-join-on" ? join.on : bindWhereExprNode(contract, join.on, namespaceId), join.lateral);
715
+ }
716
+ function bindFromSource(contract, source) {
717
+ if (source.kind === "table-source") return source;
718
+ if (source.kind === "derived-table-source") return DerivedTableSource.as(source.alias, bindSelectAst(contract, source.query));
719
+ return source;
720
+ }
721
+ function bindSelectAst(contract, ast) {
722
+ const namespaceId = ast.from !== void 0 ? namespaceCoordinateForSource(ast.from) : void 0;
723
+ return new SelectAst({
724
+ ...ast.from !== void 0 ? { from: bindFromSource(contract, ast.from) } : {},
725
+ joins: ast.joins?.map((join) => bindJoin(contract, join)),
726
+ projection: ast.projection.map((projection) => new ProjectionItem(projection.alias, bindProjectionExpr(contract, projection.expr), projection.codec)),
727
+ where: ast.where ? bindWhereExprNode(contract, ast.where, namespaceId) : void 0,
728
+ orderBy: ast.orderBy?.map((orderItem) => bindOrderByItem(contract, orderItem)),
729
+ distinct: ast.distinct,
730
+ distinctOn: ast.distinctOn?.map((expr) => bindExpression(contract, expr)),
731
+ groupBy: ast.groupBy?.map((expr) => bindExpression(contract, expr)),
732
+ having: ast.having ? bindWhereExprNode(contract, ast.having, namespaceId) : void 0,
733
+ limit: ast.limit,
734
+ offset: ast.offset,
735
+ selectAllIntent: ast.selectAllIntent
736
+ });
737
+ }
738
+ function combineWhereExprs(filters) {
739
+ if (filters.length === 0) return;
740
+ if (filters.length === 1) return filters[0];
741
+ return AndExpr.of(filters);
742
+ }
743
+ function createBoundaryExpr(tableName, entry) {
744
+ return new BinaryExpr(entry.direction === "asc" ? "gt" : "lt", ColumnRef.of(tableName, entry.column), LiteralExpr.of(entry.value));
745
+ }
746
+ function buildLexicographicCursorWhere(tableName, entries) {
747
+ const branches = entries.map((entry, index) => {
748
+ const branchExprs = [];
749
+ for (const prefixEntry of entries.slice(0, index)) branchExprs.push(BinaryExpr.eq(ColumnRef.of(tableName, prefixEntry.column), LiteralExpr.of(prefixEntry.value)));
750
+ branchExprs.push(createBoundaryExpr(tableName, entry));
751
+ if (branchExprs.length === 1) {
752
+ const branch = branchExprs[0];
753
+ assertDefined(branch, "cursor branch contains its boundary expression");
754
+ return branch;
755
+ }
756
+ return AndExpr.of(branchExprs);
757
+ });
758
+ if (branches.length === 1) {
759
+ const branch = branches[0];
760
+ assertDefined(branch, "cursor expression contains its single branch");
761
+ return branch;
762
+ }
763
+ return OrExpr.of(branches);
764
+ }
765
+ function buildCursorWhere(tableName, orderBy, cursor) {
766
+ if (!cursor || !orderBy || orderBy.length === 0) return;
767
+ const entries = [];
768
+ for (const order of orderBy) {
769
+ if (order.expr.kind !== "column-ref") continue;
770
+ const column = order.expr.column;
771
+ const value = cursor[column];
772
+ if (value === void 0) throw ormError("ORM.CURSOR_VALUE_MISSING", `Missing cursor value for orderBy column "${column}"`, { meta: { column } });
773
+ entries.push({
774
+ column,
775
+ direction: order.dir,
776
+ value
777
+ });
778
+ }
779
+ const firstEntry = entries[0];
780
+ if (entries.length === 1 && firstEntry !== void 0) return createBoundaryExpr(tableName, firstEntry);
781
+ return buildLexicographicCursorWhere(tableName, entries);
782
+ }
783
+ function createTableRefRemapper$1(fromTable, toTable) {
784
+ return {
785
+ columnRef: (col) => col.table === fromTable ? ColumnRef.of(toTable, col.column) : col,
786
+ tableSource: (source) => {
787
+ if (source.alias === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
788
+ if (!source.alias && source.name === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
789
+ return source;
790
+ },
791
+ eqColJoinOn: (on) => EqColJoinOn.of(on.left.table === fromTable ? ColumnRef.of(toTable, on.left.column) : on.left, on.right.table === fromTable ? ColumnRef.of(toTable, on.right.column) : on.right)
792
+ };
793
+ }
794
+ function buildStateWhere(contract, tableName, state, options) {
795
+ const filterTableName = options?.filterTableName;
796
+ const cursorWhere = buildCursorWhere(filterTableName ?? tableName, state.orderBy, state.cursor);
797
+ const boundFilters = state.filters.map((filter) => bindWhereExpr(contract, filter, options?.namespaceId));
798
+ const remappedFilters = filterTableName && filterTableName !== tableName ? boundFilters.map((filter) => filter.rewrite(createTableRefRemapper$1(filterTableName, tableName))) : boundFilters;
799
+ const boundCursorWhere = cursorWhere ? bindWhereExpr(contract, cursorWhere, options?.namespaceId) : void 0;
800
+ const remappedCursorWhere = boundCursorWhere && filterTableName && filterTableName !== tableName ? boundCursorWhere.rewrite(createTableRefRemapper$1(filterTableName, tableName)) : boundCursorWhere;
801
+ return combineWhereExprs(remappedCursorWhere ? [...remappedFilters, remappedCursorWhere] : remappedFilters);
802
+ }
803
+ /**
804
+ * Wrap a base SELECT in a `ROW_NUMBER() OVER (PARTITION BY … ORDER BY …) = 1`
805
+ * filter, implementing Prisma-style `.distinct(cols)` semantics: one
806
+ * representative row per `(distinctColumnRefs)` group is kept; the rest
807
+ * are dropped.
808
+ *
809
+ * Picking which row survives in each partition is governed by
810
+ * `rankingOrderBy`. When the caller's `orderBy` doesn't fully order rows
811
+ * within a partition (e.g. user wrote `.distinct('title')` with no
812
+ * `orderBy`, or ties in their ordering), the choice is
813
+ * implementation-defined — matching Prisma's documented nested-distinct
814
+ * behaviour. Callers that want determinism should pass an `orderBy` that
815
+ * is total within each partition.
816
+ *
817
+ * The wrapper forwards every column of `base.projection` through the
818
+ * derived alias, so the wrapper's projection is byte-identical in alias
819
+ * names — making this transparent to any outer query (`json_agg`,
820
+ * correlated subquery, top-level SELECT) that consumes the SELECT.
821
+ */
822
+ function wrapWithRowNumberDedup(options) {
823
+ const { base, distinctColumnRefs, rankingOrderBy, rankedAlias } = options;
824
+ const rnAlias = "__prisma_distinct_rn";
825
+ const effectiveOrderBy = rankingOrderBy.length > 0 ? rankingOrderBy : distinctColumnRefs.map((expr) => OrderByItem.asc(expr));
826
+ const inner = base.withProjection([...base.projection, ProjectionItem.of(rnAlias, WindowFuncExpr.rowNumber({
827
+ partitionBy: distinctColumnRefs,
828
+ orderBy: effectiveOrderBy
829
+ }))]);
830
+ return SelectAst.from(DerivedTableSource.as(rankedAlias, inner)).withProjection(base.projection.map((item) => ProjectionItem.of(item.alias, ColumnRef.of(rankedAlias, item.alias), item.codec))).withWhere(BinaryExpr.eq(ColumnRef.of(rankedAlias, rnAlias), LiteralExpr.of(1)));
831
+ }
832
+ /**
833
+ * FROM source + WHERE for `state.distinct`: wraps in a `ROW_NUMBER`-ranked
834
+ * derived table aliased back to `tableName`, so callers need no rewriting.
835
+ */
836
+ function buildDedupedTableSource(contract, namespaceId, tableName, state, where, wrapProjection, joins) {
837
+ if (!hasEntries(state.distinct)) return {
838
+ source: tableSourceForContract(contract, namespaceId, tableName),
839
+ where
840
+ };
841
+ const distinctColumnRefs = state.distinct.map((column) => ColumnRef.of(tableName, column));
842
+ const rankingOrderBy = hasEntries(state.orderBy) ? state.orderBy : distinctColumnRefs.map((expr) => OrderByItem.asc(expr));
843
+ let inner = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection([...wrapProjection, ProjectionItem.of("__prisma_distinct_rn", WindowFuncExpr.rowNumber({
844
+ partitionBy: distinctColumnRefs,
845
+ orderBy: rankingOrderBy
846
+ }))]);
847
+ if (joins && joins.length > 0) inner = inner.withJoins(joins);
848
+ if (where) inner = inner.withWhere(where);
849
+ return {
850
+ source: DerivedTableSource.as(tableName, inner),
851
+ where: BinaryExpr.eq(ColumnRef.of(tableName, "__prisma_distinct_rn"), LiteralExpr.of(1))
852
+ };
853
+ }
854
+ function buildMtiJoins(contract, namespaceId, polyInfo, variantName, selectedColumnsByTable) {
855
+ const joins = [];
856
+ const projection = [];
857
+ const pkColumn = resolvePrimaryKeyColumn(contract, namespaceId, polyInfo.baseTable);
858
+ const variantsToJoin = variantName ? polyInfo.mtiVariants.filter((v) => v.modelName === variantName) : polyInfo.mtiVariants;
859
+ for (const variant of variantsToJoin) {
860
+ const joinType = variantName ? "inner" : "left";
861
+ const joinOn = EqColJoinOn.of(ColumnRef.of(polyInfo.baseTable, pkColumn), ColumnRef.of(variant.table, pkColumn));
862
+ const join = joinType === "inner" ? JoinAst.inner(tableSourceForContract(contract, namespaceId, variant.table), joinOn) : JoinAst.left(tableSourceForContract(contract, namespaceId, variant.table), joinOn);
863
+ joins.push(join);
864
+ const variantColumns = resolveTableColumns(contract, namespaceId, variant.table);
865
+ const selectedVariantColumns = selectedColumnsByTable?.get(variant.table);
866
+ for (const col of variantColumns) {
867
+ if (col === pkColumn) continue;
868
+ if (selectedColumnsByTable !== void 0 && selectedVariantColumns?.has(col) !== true) continue;
869
+ const alias = `${variant.table}__${col}`;
870
+ projection.push(ProjectionItem.of(alias, ColumnRef.of(variant.table, col), codecRefForStorageColumn(contract.storage, namespaceId, variant.table, col)));
871
+ }
872
+ }
873
+ return {
874
+ joins,
875
+ projection
876
+ };
877
+ }
878
+ function hasEntries(value) {
879
+ return value !== void 0 && value.length > 0;
880
+ }
881
+ /**
882
+ * The rows an aggregate reduces over, one SELECT aliased to `tableName` — an
883
+ * aggregate has no outer level of its own, so where/joins/distinct/orderBy/
884
+ * limit/offset all have to live in this one wrap.
885
+ */
886
+ function buildAggregateInput(contract, namespaceId, tableName, state, modelName, projection) {
887
+ const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
888
+ const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, void 0).joins : [];
889
+ const { source, where: effectiveWhere } = buildDedupedTableSource(contract, namespaceId, tableName, state, buildStateWhere(contract, tableName, state, { namespaceId }), projection, variantJoins);
890
+ let inner = SelectAst.from(source).withProjection(projection);
891
+ if (!hasEntries(state.distinct) && variantJoins.length > 0) inner = inner.withJoins(variantJoins);
892
+ if (effectiveWhere) inner = inner.withWhere(effectiveWhere);
893
+ if (hasEntries(state.distinctOn)) inner = inner.withDistinctOn(state.distinctOn.map((column) => ColumnRef.of(tableName, column)));
894
+ if (hasEntries(state.orderBy)) inner = inner.withOrderBy(state.orderBy);
895
+ if (state.limit !== void 0) inner = inner.withLimit(state.limit);
896
+ if (state.offset !== void 0) inner = inner.withOffset(state.offset);
897
+ return { source: DerivedTableSource.as(tableName, inner) };
898
+ }
899
+ function emptyState() {
900
+ return {
901
+ filters: [],
902
+ includes: [],
903
+ orderBy: void 0,
904
+ cursor: void 0,
905
+ distinct: void 0,
906
+ distinctOn: void 0,
907
+ selectedFields: void 0,
908
+ limit: void 0,
909
+ offset: void 0,
910
+ variantName: void 0,
911
+ annotations: /* @__PURE__ */ new Map()
912
+ };
913
+ }
914
+ function emptyGroupPagingState() {
915
+ return {
916
+ orderBy: [],
917
+ limit: void 0,
918
+ offset: void 0
919
+ };
920
+ }
921
+ function param(codec, value) {
922
+ if (codec === void 0) return ParamRef.of(value);
923
+ return ParamRef.of(value, { codec });
924
+ }
925
+ function paramList(codec, values) {
926
+ return ListExpression.of(values.map((value) => param(codec, value)));
927
+ }
928
+ function scalarComparisonMethod(op) {
929
+ return ((left, codec) => (value) => {
930
+ if (value === null && (op === "eq" || op === "neq")) return op === "eq" ? NullCheckExpr.isNull(left) : NullCheckExpr.isNotNull(left);
931
+ return new BinaryExpr(op, left, param(codec, value));
932
+ });
933
+ }
934
+ function listComparisonMethod(op) {
935
+ return ((left, codec) => (values) => new BinaryExpr(op, left, paramList(codec, values)));
936
+ }
937
+ /**
938
+ * Declares trait requirements and runtime factory for each comparison method.
939
+ *
940
+ * - `traits: []` means "no trait required" — always available
941
+ * - Multi-trait: `traits: ['equality', 'order']` means BOTH traits are required
942
+ */
943
+ const COMPARISON_METHODS_META = {
944
+ eq: {
945
+ traits: ["equality"],
946
+ create: scalarComparisonMethod("eq")
947
+ },
948
+ neq: {
949
+ traits: ["equality"],
950
+ create: scalarComparisonMethod("neq")
951
+ },
952
+ in: {
953
+ traits: ["equality"],
954
+ create: listComparisonMethod("in")
955
+ },
956
+ notIn: {
957
+ traits: ["equality"],
958
+ create: listComparisonMethod("notIn")
959
+ },
960
+ gt: {
961
+ traits: ["order"],
962
+ create: scalarComparisonMethod("gt")
963
+ },
964
+ lt: {
965
+ traits: ["order"],
966
+ create: scalarComparisonMethod("lt")
967
+ },
968
+ gte: {
969
+ traits: ["order"],
970
+ create: scalarComparisonMethod("gte")
971
+ },
972
+ lte: {
973
+ traits: ["order"],
974
+ create: scalarComparisonMethod("lte")
975
+ },
976
+ like: {
977
+ traits: ["textual"],
978
+ create: scalarComparisonMethod("like")
979
+ },
980
+ asc: {
981
+ traits: ["order"],
982
+ create: (left) => () => OrderByItem.asc(left)
983
+ },
984
+ desc: {
985
+ traits: ["order"],
986
+ create: (left) => () => OrderByItem.desc(left)
987
+ },
988
+ isNull: {
989
+ traits: [],
990
+ create: (left) => () => NullCheckExpr.isNull(left)
991
+ },
992
+ isNotNull: {
993
+ traits: [],
994
+ create: (left) => () => NullCheckExpr.isNotNull(left)
995
+ }
996
+ };
997
+ function toAggregateProjection(contract, aggregates, namespaceId, tableName, selector) {
998
+ const { codec, input: inputCodec, lower } = resolveAggregate({
999
+ aggregates,
1000
+ contract,
1001
+ namespaceId,
1002
+ tableName,
1003
+ fn: selector.fn,
1004
+ column: selector.column
1005
+ });
1006
+ const inputExpr = selector.column === void 0 ? void 0 : ColumnRef.of(tableName, selector.column);
1007
+ return {
1008
+ expr: lower !== void 0 ? lower({
1009
+ expr: inputExpr,
1010
+ inputCodec
1011
+ }) : plainAggregateExpr(selector.fn, inputExpr),
1012
+ codec
1013
+ };
1014
+ }
1015
+ function validateGroupedComparable(value) {
1016
+ switch (value.kind) {
1017
+ case "param-ref": throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: value.kind } });
1018
+ case "literal":
1019
+ case "column-ref":
1020
+ case "identifier-ref":
1021
+ case "aggregate":
1022
+ case "operation": return value;
1023
+ case "function-call":
1024
+ case "cast":
1025
+ case "case": throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported comparable kind in grouped having: "${value.kind}"`, { meta: { kind: value.kind } });
1026
+ case "list":
1027
+ if (value.values.some((entry) => entry.kind === "param-ref")) throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: "list" } });
1028
+ return value;
1029
+ default: throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported comparable kind in grouped having: "${value.kind}"`, { meta: { kind: value.kind } });
1030
+ }
1031
+ }
1032
+ function validateGroupedMetricExpr(expr) {
1033
+ if (expr.kind !== "aggregate") throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "groupBy().having() only supports aggregate metric expressions", { meta: { kind: expr.kind } });
1034
+ return expr;
1035
+ }
1036
+ function rejectHavingExpr(expr) {
1037
+ throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", `Unsupported grouped having expression kind "${expr.kind}"`, { meta: { kind: expr.kind } });
1038
+ }
1039
+ function validateGroupedHavingExpr(expr) {
1040
+ return expr.accept({
1041
+ columnRef: rejectHavingExpr,
1042
+ identifierRef: rejectHavingExpr,
1043
+ subquery: rejectHavingExpr,
1044
+ operation: rejectHavingExpr,
1045
+ aggregate: rejectHavingExpr,
1046
+ windowFunc: rejectHavingExpr,
1047
+ functionCall: rejectHavingExpr,
1048
+ cast: rejectHavingExpr,
1049
+ case: rejectHavingExpr,
1050
+ jsonObject: rejectHavingExpr,
1051
+ jsonArrayAgg: rejectHavingExpr,
1052
+ literal: rejectHavingExpr,
1053
+ param() {
1054
+ throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "ParamRef is not supported in grouped having expressions", { meta: { kind: "param-ref" } });
1055
+ },
1056
+ preparedParam() {
1057
+ throw ormError("ORM.HAVING_EXPRESSION_UNSUPPORTED", "PreparedParamRef is not supported in grouped having expressions", { meta: { kind: "prepared-param-ref" } });
1058
+ },
1059
+ list: rejectHavingExpr,
1060
+ and(expr) {
1061
+ return AndExpr.of(expr.exprs.map((child) => validateGroupedHavingExpr(child)));
1062
+ },
1063
+ or(expr) {
1064
+ return OrExpr.of(expr.exprs.map((child) => validateGroupedHavingExpr(child)));
1065
+ },
1066
+ exists: rejectHavingExpr,
1067
+ nullCheck(expr) {
1068
+ return new NullCheckExpr(validateGroupedMetricExpr(expr.expr), expr.isNull);
1069
+ },
1070
+ not(expr) {
1071
+ return new NotExpr(validateGroupedHavingExpr(expr.expr));
1072
+ },
1073
+ binary(expr) {
1074
+ return new BinaryExpr(expr.op, validateGroupedMetricExpr(expr.left), validateGroupedComparable(expr.right));
1075
+ },
1076
+ rawExpr: rejectHavingExpr
1077
+ });
1078
+ }
1079
+ function aggregateInputColumns(tableName, entries, orderBy, groupByColumns = []) {
1080
+ const columns = new Set(groupByColumns);
1081
+ for (const [, selector] of entries) if (selector.column !== void 0) columns.add(selector.column);
1082
+ for (const item of orderBy ?? []) if (item.expr.kind === "column-ref") columns.add(item.expr.column);
1083
+ if (columns.size === 0) return [ProjectionItem.of("__row", LiteralExpr.of(1))];
1084
+ return Array.from(columns, (column) => ProjectionItem.of(column, ColumnRef.of(tableName, column)));
1085
+ }
1086
+ function compileAggregate(contract, aggregates, namespaceId, tableName, state, aggregateSpec, modelName) {
1087
+ const entries = Object.entries(aggregateSpec);
1088
+ if (entries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "aggregate() requires at least one aggregation selector", { meta: {
1089
+ method: "aggregate",
1090
+ namespaceId,
1091
+ tableName
1092
+ } });
1093
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1094
+ const hasPagination = state.limit !== void 0 || state.offset !== void 0;
1095
+ const hasDistinct = state.distinct !== void 0 && state.distinct.length > 0 || state.distinctOn !== void 0 && state.distinctOn.length > 0;
1096
+ if (hasPagination || hasDistinct) {
1097
+ const { source } = buildAggregateInput(contract, namespaceId, tableName, state, modelName, aggregateInputColumns(tableName, entries, state.orderBy));
1098
+ const projection = entries.map(([alias, selector]) => {
1099
+ const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
1100
+ return ProjectionItem.of(alias, expr, codec);
1101
+ });
1102
+ const ast = SelectAst.from(source).withProjection(projection);
1103
+ const { params } = deriveParamsFromAst(ast);
1104
+ return buildOrmQueryPlan(contract, ast, params);
1105
+ }
1106
+ const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1107
+ const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, void 0).joins : [];
1108
+ const where = buildStateWhere(contract, tableName, state, { namespaceId });
1109
+ const projection = entries.map(([alias, selector]) => {
1110
+ const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
1111
+ return ProjectionItem.of(alias, expr, codec);
1112
+ });
1113
+ let ast = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection(projection);
1114
+ if (variantJoins.length > 0) ast = ast.withJoins(variantJoins);
1115
+ if (where) ast = ast.withWhere(where);
1116
+ const { params } = deriveParamsFromAst(ast);
1117
+ return buildOrmQueryPlan(contract, ast, params);
1118
+ }
1119
+ function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, preGroupState, groupByColumns, aggregateSpec, havingExpr, modelName, postGroup = emptyGroupPagingState()) {
1120
+ if (groupByColumns.length === 0) throw ormError("ORM.GROUP_BY_FIELD_MISSING", "groupBy() requires at least one field", { meta: {
1121
+ namespaceId,
1122
+ tableName
1123
+ } });
1124
+ const entries = Object.entries(aggregateSpec);
1125
+ if (entries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "groupBy().aggregate() requires at least one aggregation selector", { meta: {
1126
+ method: "groupBy.aggregate",
1127
+ namespaceId,
1128
+ tableName
1129
+ } });
1130
+ if (preGroupState.distinctOn !== void 0 && preGroupState.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1131
+ const projection = [...groupByColumns.map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column))), ...entries.map(([alias, selector]) => {
1132
+ const { expr, codec } = toAggregateProjection(contract, aggregates, namespaceId, tableName, selector);
1133
+ return ProjectionItem.of(alias, expr, codec);
1134
+ })];
1135
+ const hasPagination = preGroupState.limit !== void 0 || preGroupState.offset !== void 0;
1136
+ const hasDistinct = preGroupState.distinct !== void 0 && preGroupState.distinct.length > 0 || preGroupState.distinctOn !== void 0 && preGroupState.distinctOn.length > 0;
1137
+ const needsInputSelect = hasPagination || hasDistinct;
1138
+ let ast;
1139
+ if (needsInputSelect) {
1140
+ const { source } = buildAggregateInput(contract, namespaceId, tableName, preGroupState, modelName, aggregateInputColumns(tableName, entries, preGroupState.orderBy, groupByColumns));
1141
+ ast = SelectAst.from(source).withProjection(projection).withGroupBy(groupByColumns.map((column) => ColumnRef.of(tableName, column)));
1142
+ } else {
1143
+ const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1144
+ const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, preGroupState.variantName, void 0).joins : [];
1145
+ ast = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection(projection).withGroupBy(groupByColumns.map((column) => ColumnRef.of(tableName, column)));
1146
+ if (variantJoins.length > 0) ast = ast.withJoins(variantJoins);
1147
+ const where = buildStateWhere(contract, tableName, preGroupState, { namespaceId });
1148
+ if (where) ast = ast.withWhere(where);
1149
+ }
1150
+ if (havingExpr) ast = ast.withHaving(validateGroupedHavingExpr(havingExpr));
1151
+ if (postGroup.orderBy.length > 0) ast = ast.withOrderBy(postGroup.orderBy);
1152
+ if (postGroup.limit !== void 0) ast = ast.withLimit(postGroup.limit);
1153
+ if (postGroup.offset !== void 0) ast = ast.withOffset(postGroup.offset);
1154
+ const { params } = deriveParamsFromAst(ast);
1155
+ return buildOrmQueryPlan(contract, ast, params);
1156
+ }
1157
+ function buildReturningColumns(contract, namespaceId, tableName, returningColumns) {
1158
+ return (returningColumns && returningColumns.length > 0 ? [...returningColumns] : resolveTableColumns(contract, namespaceId, tableName)).map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
1159
+ }
1160
+ function toParamAssignments(contract, namespaceId, tableName, values) {
1161
+ const assignments = {};
1162
+ const table = storageTableForContract(contract, namespaceId, tableName);
1163
+ for (const [column, value] of Object.entries(values)) {
1164
+ if (!table.columns[column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${column}" in table "${tableName}"`, { meta: {
1165
+ namespaceId,
1166
+ tableName,
1167
+ column
1168
+ } });
1169
+ const codec = codecRefForStorageColumn(contract.storage, namespaceId, tableName, column);
1170
+ assignments[column] = ParamRef.of(value, {
1171
+ name: column,
1172
+ ...ifDefined("codec", codec)
1173
+ });
1174
+ }
1175
+ return { assignments };
1176
+ }
1177
+ function normalizeInsertRows(contract, namespaceId, tableName, rows) {
1178
+ if (rows.length === 0) throw new InternalError("normalizeInsertRows requires at least one row");
1179
+ const orderedColumns = [];
1180
+ const seenColumns = /* @__PURE__ */ new Set();
1181
+ for (const row of rows) for (const column of Object.keys(row)) {
1182
+ if (seenColumns.has(column)) continue;
1183
+ seenColumns.add(column);
1184
+ orderedColumns.push(column);
1185
+ }
1186
+ const table = storageTableForContract(contract, namespaceId, tableName);
1187
+ return { rows: rows.map((row) => {
1188
+ if (orderedColumns.length === 0) return {};
1189
+ const normalizedRow = {};
1190
+ for (const column of orderedColumns) {
1191
+ if (Object.hasOwn(row, column)) {
1192
+ if (!table.columns[column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${column}" in table "${tableName}"`, { meta: {
1193
+ namespaceId,
1194
+ tableName,
1195
+ column
1196
+ } });
1197
+ const codec = codecRefForStorageColumn(contract.storage, namespaceId, tableName, column);
1198
+ normalizedRow[column] = ParamRef.of(row[column], {
1199
+ name: column,
1200
+ ...ifDefined("codec", codec)
1201
+ });
1202
+ continue;
1203
+ }
1204
+ normalizedRow[column] = new DefaultValueExpr();
1205
+ }
1206
+ return normalizedRow;
1207
+ }) };
1208
+ }
1209
+ function compileInsertReturning(contract, namespaceId, tableName, rows, returningColumns) {
1210
+ const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
1211
+ const ast = InsertAst.into(tableSourceForContract(contract, namespaceId, tableName)).withRows(normalizedRows).withReturning(buildReturningColumns(contract, namespaceId, tableName, returningColumns));
1212
+ const { params } = deriveParamsFromAst(ast);
1213
+ return buildOrmQueryPlan(contract, ast, params);
1214
+ }
1215
+ function compileInsertCount(contract, namespaceId, tableName, rows) {
1216
+ const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
1217
+ const ast = InsertAst.into(tableSourceForContract(contract, namespaceId, tableName)).withRows(normalizedRows);
1218
+ const { params } = deriveParamsFromAst(ast);
1219
+ return buildOrmQueryPlan(contract, ast, params);
1220
+ }
1221
+ function stripUndefinedValues(row) {
805
1222
  const result = {};
806
1223
  for (const [key, value] of Object.entries(row)) if (value !== void 0) result[key] = value;
807
1224
  return result;
808
1225
  }
809
- function createTableRefRemapper$1(fromTable, toTable) {
1226
+ function createTableRefRemapper(fromTable, toTable) {
810
1227
  return {
811
1228
  columnRef: (col) => col.table === fromTable ? ColumnRef.of(toTable, col.column) : col,
812
1229
  tableSource: (source) => {
@@ -824,7 +1241,7 @@ function buildCountMutationWhere(contract, namespaceId, tableName, filters, vari
824
1241
  if (!polyInfo || !variant || variant.strategy !== "mti") return combineWhereExprs(filters);
825
1242
  const pkColumn = resolvePrimaryKeyColumn(contract, namespaceId, tableName);
826
1243
  const baseTableRef = `${tableName}__write_filter`;
827
- const remapper = createTableRefRemapper$1(tableName, baseTableRef);
1244
+ const remapper = createTableRefRemapper(tableName, baseTableRef);
828
1245
  const innerFilters = filters.map((filter) => filter.rewrite(remapper));
829
1246
  const where = combineWhereExprs([BinaryExpr.eq(ColumnRef.of(baseTableRef, pkColumn), ColumnRef.of(tableName, pkColumn)), ...innerFilters]);
830
1247
  const joinOn = EqColJoinOn.of(ColumnRef.of(baseTableRef, pkColumn), ColumnRef.of(variant.table, pkColumn));
@@ -917,137 +1334,6 @@ function augmentSelectionForJoinColumns(selectedFields, requiredColumns) {
917
1334
  hiddenColumns
918
1335
  };
919
1336
  }
920
- function namespaceCoordinateForSource(source) {
921
- return source.kind === "table-source" ? source.namespaceId : void 0;
922
- }
923
- function bindWhereExpr(contract, expr, namespaceId) {
924
- return bindWhereExprNode(contract, expr, namespaceId);
925
- }
926
- function bindWhereExprNode(contract, expr, namespaceId) {
927
- return expr.accept({
928
- columnRef(expr) {
929
- return bindExpression(contract, expr);
930
- },
931
- identifierRef(expr) {
932
- return expr;
933
- },
934
- subquery(expr) {
935
- return bindExpression(contract, expr);
936
- },
937
- operation(expr) {
938
- return bindExpression(contract, expr);
939
- },
940
- aggregate(expr) {
941
- return bindExpression(contract, expr);
942
- },
943
- windowFunc(expr) {
944
- return bindExpression(contract, expr);
945
- },
946
- functionCall(expr) {
947
- return bindExpression(contract, expr);
948
- },
949
- cast(expr) {
950
- return bindExpression(contract, expr);
951
- },
952
- case(expr) {
953
- return bindExpression(contract, expr);
954
- },
955
- jsonObject(expr) {
956
- return bindExpression(contract, expr);
957
- },
958
- jsonArrayAgg(expr) {
959
- return bindExpression(contract, expr);
960
- },
961
- literal(expr) {
962
- return expr;
963
- },
964
- param(expr) {
965
- return expr;
966
- },
967
- preparedParam(expr) {
968
- return expr;
969
- },
970
- list(expr) {
971
- return bindExpression(contract, expr);
972
- },
973
- binary(expr) {
974
- const left = bindExpression(contract, expr.left);
975
- const bindingColumn = left.kind === "column-ref" ? left : void 0;
976
- return new BinaryExpr(expr.op, left, bindComparable(contract, expr.right, bindingColumn, namespaceId));
977
- },
978
- and(expr) {
979
- return AndExpr.of(expr.exprs.map((part) => bindWhereExprNode(contract, part, namespaceId)));
980
- },
981
- or(expr) {
982
- return OrExpr.of(expr.exprs.map((part) => bindWhereExprNode(contract, part, namespaceId)));
983
- },
984
- exists(expr) {
985
- return expr.notExists ? ExistsExpr.notExists(bindSelectAst(contract, expr.subquery)) : ExistsExpr.exists(bindSelectAst(contract, expr.subquery));
986
- },
987
- nullCheck(expr) {
988
- return expr.isNull ? NullCheckExpr.isNull(bindExpression(contract, expr.expr)) : NullCheckExpr.isNotNull(bindExpression(contract, expr.expr));
989
- },
990
- not(expr) {
991
- return new NotExpr(bindWhereExprNode(contract, expr.expr, namespaceId));
992
- },
993
- rawExpr(expr) {
994
- return expr;
995
- }
996
- });
997
- }
998
- function bindComparable(contract, comparable, bindingColumn, namespaceId) {
999
- if (comparable.kind === "param-ref" || bindingColumn === void 0) return comparable.kind === "param-ref" ? comparable : comparable.kind === "literal" || comparable.kind === "list" ? comparable : bindExpression(contract, comparable);
1000
- if (comparable.kind === "literal") return createParamRef(contract, bindingColumn, comparable.value, namespaceId);
1001
- if (comparable.kind === "list") return ListExpression.of(comparable.values.map((value) => value.kind === "literal" ? createParamRef(contract, bindingColumn, value.value, namespaceId) : value));
1002
- return bindExpression(contract, comparable);
1003
- }
1004
- function createParamRef(contract, columnRef, value, namespaceId) {
1005
- const resolved = resolveStorageTable(contract.storage, columnRef.table, namespaceId);
1006
- if (resolved === void 0 || !resolved.table.columns[columnRef.column]) throw ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${columnRef.column}" in table "${columnRef.table}"`, { meta: {
1007
- tableName: columnRef.table,
1008
- column: columnRef.column
1009
- } });
1010
- const codec = codecRefForStorageColumn(contract.storage, resolved.namespaceId, columnRef.table, columnRef.column);
1011
- return ParamRef.of(value, codec ? { codec } : void 0);
1012
- }
1013
- function createExpressionBinder(contract) {
1014
- return { select: (ast) => bindSelectAst(contract, ast) };
1015
- }
1016
- function bindExpression(contract, expr) {
1017
- return expr.rewrite(createExpressionBinder(contract));
1018
- }
1019
- function bindProjectionExpr(contract, expr) {
1020
- return expr.kind === "literal" ? expr : bindExpression(contract, expr);
1021
- }
1022
- function bindOrderByItem(contract, orderItem) {
1023
- return new OrderByItem(bindExpression(contract, orderItem.expr), orderItem.dir);
1024
- }
1025
- function bindJoin(contract, join) {
1026
- const namespaceId = namespaceCoordinateForSource(join.source);
1027
- return new JoinAst(join.joinType, bindFromSource(contract, join.source), join.on.kind === "eq-col-join-on" ? join.on : bindWhereExprNode(contract, join.on, namespaceId), join.lateral);
1028
- }
1029
- function bindFromSource(contract, source) {
1030
- if (source.kind === "table-source") return source;
1031
- if (source.kind === "derived-table-source") return DerivedTableSource.as(source.alias, bindSelectAst(contract, source.query));
1032
- return source;
1033
- }
1034
- function bindSelectAst(contract, ast) {
1035
- const namespaceId = ast.from !== void 0 ? namespaceCoordinateForSource(ast.from) : void 0;
1036
- return new SelectAst({
1037
- ...ast.from !== void 0 ? { from: bindFromSource(contract, ast.from) } : {},
1038
- joins: ast.joins?.map((join) => bindJoin(contract, join)),
1039
- projection: ast.projection.map((projection) => new ProjectionItem(projection.alias, bindProjectionExpr(contract, projection.expr), projection.codec)),
1040
- where: ast.where ? bindWhereExprNode(contract, ast.where, namespaceId) : void 0,
1041
- orderBy: ast.orderBy?.map((orderItem) => bindOrderByItem(contract, orderItem)),
1042
- distinct: ast.distinct,
1043
- distinctOn: ast.distinctOn?.map((expr) => bindExpression(contract, expr)),
1044
- groupBy: ast.groupBy?.map((expr) => bindExpression(contract, expr)),
1045
- having: ast.having ? bindWhereExprNode(contract, ast.having, namespaceId) : void 0,
1046
- limit: ast.limit,
1047
- offset: ast.offset,
1048
- selectAllIntent: ast.selectAllIntent
1049
- });
1050
- }
1051
1337
  /**
1052
1338
  * The rule for which JSON projection variant an include entry carries. Every
1053
1339
  * site that puts a value into a `json_build_object` or a `json_agg` goes
@@ -1098,98 +1384,38 @@ function resolvePolymorphicProjectionSelection(contract, namespaceId, modelName,
1098
1384
  columnToField: getCompleteColumnToFieldMap(contract, namespaceId, variant.modelName)
1099
1385
  }));
1100
1386
  const baseSelectedFields = [];
1101
- const selectedMtiColumnsByTable = /* @__PURE__ */ new Map();
1102
- let hasVariantOwnedSelection = false;
1103
- for (const selectedField of state.selectedFields) {
1104
- const baseColumn = baseFieldToColumn[selectedField] ?? (baseTableColumns.has(selectedField) ? selectedField : void 0);
1105
- if (baseColumn !== void 0) appendUnique(baseSelectedFields, baseColumn);
1106
- let matchedVariantField = false;
1107
- for (const { variant, columnToField } of variantFieldMaps) for (const [column, field] of Object.entries(columnToField)) {
1108
- if (selectedField !== field && selectedField !== column) continue;
1109
- matchedVariantField = true;
1110
- hasVariantOwnedSelection = true;
1111
- if (variant.strategy === "sti") {
1112
- appendUnique(baseSelectedFields, column);
1113
- continue;
1114
- }
1115
- let selectedColumns = selectedMtiColumnsByTable.get(variant.table);
1116
- if (selectedColumns === void 0) {
1117
- selectedColumns = /* @__PURE__ */ new Set();
1118
- selectedMtiColumnsByTable.set(variant.table, selectedColumns);
1119
- }
1120
- selectedColumns.add(column);
1121
- }
1122
- if (baseColumn === void 0 && !matchedVariantField) appendUnique(baseSelectedFields, selectedField);
1123
- }
1124
- return {
1125
- baseSelectedFields,
1126
- selectedMtiColumnsByTable,
1127
- needsHiddenDiscriminator: state.variantName === void 0 && hasVariantOwnedSelection && !baseSelectedFields.includes(polyInfo.discriminatorColumn)
1128
- };
1129
- }
1130
- function buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableRef, needed) {
1131
- if (!needed) return [];
1132
- return [ProjectionItem.of(POLYMORPHIC_DISCRIMINATOR_ALIAS, ColumnRef.of(tableRef, polyInfo.discriminatorColumn), codecRefForStorageColumn(contract.storage, namespaceId, polyInfo.baseTable, polyInfo.discriminatorColumn))];
1133
- }
1134
- function createBoundaryExpr(tableName, entry) {
1135
- return new BinaryExpr(entry.direction === "asc" ? "gt" : "lt", ColumnRef.of(tableName, entry.column), LiteralExpr.of(entry.value));
1136
- }
1137
- function buildLexicographicCursorWhere(tableName, entries) {
1138
- const branches = entries.map((entry, index) => {
1139
- const branchExprs = [];
1140
- for (const prefixEntry of entries.slice(0, index)) branchExprs.push(BinaryExpr.eq(ColumnRef.of(tableName, prefixEntry.column), LiteralExpr.of(prefixEntry.value)));
1141
- branchExprs.push(createBoundaryExpr(tableName, entry));
1142
- if (branchExprs.length === 1) {
1143
- const branch = branchExprs[0];
1144
- assertDefined(branch, "cursor branch contains its boundary expression");
1145
- return branch;
1146
- }
1147
- return AndExpr.of(branchExprs);
1148
- });
1149
- if (branches.length === 1) {
1150
- const branch = branches[0];
1151
- assertDefined(branch, "cursor expression contains its single branch");
1152
- return branch;
1153
- }
1154
- return OrExpr.of(branches);
1155
- }
1156
- function buildCursorWhere(tableName, orderBy, cursor) {
1157
- if (!cursor || !orderBy || orderBy.length === 0) return;
1158
- const entries = [];
1159
- for (const order of orderBy) {
1160
- if (order.expr.kind !== "column-ref") continue;
1161
- const column = order.expr.column;
1162
- const value = cursor[column];
1163
- if (value === void 0) throw ormError("ORM.CURSOR_VALUE_MISSING", `Missing cursor value for orderBy column "${column}"`, { meta: { column } });
1164
- entries.push({
1165
- column,
1166
- direction: order.dir,
1167
- value
1168
- });
1387
+ const selectedMtiColumnsByTable = /* @__PURE__ */ new Map();
1388
+ let hasVariantOwnedSelection = false;
1389
+ for (const selectedField of state.selectedFields) {
1390
+ const baseColumn = baseFieldToColumn[selectedField] ?? (baseTableColumns.has(selectedField) ? selectedField : void 0);
1391
+ if (baseColumn !== void 0) appendUnique(baseSelectedFields, baseColumn);
1392
+ let matchedVariantField = false;
1393
+ for (const { variant, columnToField } of variantFieldMaps) for (const [column, field] of Object.entries(columnToField)) {
1394
+ if (selectedField !== field && selectedField !== column) continue;
1395
+ matchedVariantField = true;
1396
+ hasVariantOwnedSelection = true;
1397
+ if (variant.strategy === "sti") {
1398
+ appendUnique(baseSelectedFields, column);
1399
+ continue;
1400
+ }
1401
+ let selectedColumns = selectedMtiColumnsByTable.get(variant.table);
1402
+ if (selectedColumns === void 0) {
1403
+ selectedColumns = /* @__PURE__ */ new Set();
1404
+ selectedMtiColumnsByTable.set(variant.table, selectedColumns);
1405
+ }
1406
+ selectedColumns.add(column);
1407
+ }
1408
+ if (baseColumn === void 0 && !matchedVariantField) appendUnique(baseSelectedFields, selectedField);
1169
1409
  }
1170
- const firstEntry = entries[0];
1171
- if (entries.length === 1 && firstEntry !== void 0) return createBoundaryExpr(tableName, firstEntry);
1172
- return buildLexicographicCursorWhere(tableName, entries);
1173
- }
1174
- function createTableRefRemapper(fromTable, toTable) {
1175
1410
  return {
1176
- columnRef: (col) => col.table === fromTable ? ColumnRef.of(toTable, col.column) : col,
1177
- tableSource: (source) => {
1178
- if (source.alias === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
1179
- if (!source.alias && source.name === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
1180
- return source;
1181
- },
1182
- eqColJoinOn: (on) => EqColJoinOn.of(on.left.table === fromTable ? ColumnRef.of(toTable, on.left.column) : on.left, on.right.table === fromTable ? ColumnRef.of(toTable, on.right.column) : on.right)
1411
+ baseSelectedFields,
1412
+ selectedMtiColumnsByTable,
1413
+ needsHiddenDiscriminator: state.variantName === void 0 && hasVariantOwnedSelection && !baseSelectedFields.includes(polyInfo.discriminatorColumn)
1183
1414
  };
1184
1415
  }
1185
- function buildStateWhere(contract, tableName, state, options) {
1186
- const filterTableName = options?.filterTableName;
1187
- const cursorWhere = buildCursorWhere(filterTableName ?? tableName, state.orderBy, state.cursor);
1188
- const boundFilters = state.filters.map((filter) => bindWhereExpr(contract, filter, options?.namespaceId));
1189
- const remappedFilters = filterTableName && filterTableName !== tableName ? boundFilters.map((filter) => filter.rewrite(createTableRefRemapper(filterTableName, tableName))) : boundFilters;
1190
- const boundCursorWhere = cursorWhere ? bindWhereExpr(contract, cursorWhere, options?.namespaceId) : void 0;
1191
- const remappedCursorWhere = boundCursorWhere && filterTableName && filterTableName !== tableName ? boundCursorWhere.rewrite(createTableRefRemapper(filterTableName, tableName)) : boundCursorWhere;
1192
- return combineWhereExprs(remappedCursorWhere ? [...remappedFilters, remappedCursorWhere] : remappedFilters);
1416
+ function buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableRef, needed) {
1417
+ if (!needed) return [];
1418
+ return [ProjectionItem.of(POLYMORPHIC_DISCRIMINATOR_ALIAS, ColumnRef.of(tableRef, polyInfo.discriminatorColumn), codecRefForStorageColumn(contract.storage, namespaceId, polyInfo.baseTable, polyInfo.discriminatorColumn))];
1193
1419
  }
1194
1420
  function buildIncludeOrderArtifacts(relationName, rowAlias, childOrderBy) {
1195
1421
  if (!childOrderBy || childOrderBy.length === 0) return {
@@ -1208,35 +1434,6 @@ function buildIncludeOrderArtifacts(relationName, rowAlias, childOrderBy) {
1208
1434
  })
1209
1435
  };
1210
1436
  }
1211
- /**
1212
- * Wrap a base SELECT in a `ROW_NUMBER() OVER (PARTITION BY … ORDER BY …) = 1`
1213
- * filter, implementing Prisma-style `.distinct(cols)` semantics: one
1214
- * representative row per `(distinctColumnRefs)` group is kept; the rest
1215
- * are dropped.
1216
- *
1217
- * Picking which row survives in each partition is governed by
1218
- * `rankingOrderBy`. When the caller's `orderBy` doesn't fully order rows
1219
- * within a partition (e.g. user wrote `.distinct('title')` with no
1220
- * `orderBy`, or ties in their ordering), the choice is
1221
- * implementation-defined — matching Prisma's documented nested-distinct
1222
- * behaviour. Callers that want determinism should pass an `orderBy` that
1223
- * is total within each partition.
1224
- *
1225
- * The wrapper forwards every column of `base.projection` through the
1226
- * derived alias, so the wrapper's projection is byte-identical in alias
1227
- * names — making this transparent to any outer query (`json_agg`,
1228
- * correlated subquery, top-level SELECT) that consumes the SELECT.
1229
- */
1230
- function wrapWithRowNumberDedup(options) {
1231
- const { base, distinctColumnRefs, rankingOrderBy, rankedAlias } = options;
1232
- const rnAlias = "__prisma_distinct_rn";
1233
- const effectiveOrderBy = rankingOrderBy.length > 0 ? rankingOrderBy : distinctColumnRefs.map((expr) => OrderByItem.asc(expr));
1234
- const inner = base.withProjection([...base.projection, ProjectionItem.of(rnAlias, WindowFuncExpr.rowNumber({
1235
- partitionBy: distinctColumnRefs,
1236
- orderBy: effectiveOrderBy
1237
- }))]);
1238
- return SelectAst.from(DerivedTableSource.as(rankedAlias, inner)).withProjection(base.projection.map((item) => ProjectionItem.of(item.alias, ColumnRef.of(rankedAlias, item.alias), item.codec))).withWhere(BinaryExpr.eq(ColumnRef.of(rankedAlias, rnAlias), LiteralExpr.of(1)));
1239
- }
1240
1437
  function localColumnsForRowInclude(include) {
1241
1438
  return include.through?.parentLocalColumns ?? [include.localColumn];
1242
1439
  }
@@ -1304,7 +1501,7 @@ function buildChildPolymorphismJoinsAndProjection(contract, include, childTableA
1304
1501
  hiddenProjection,
1305
1502
  baseSelectedFields: selection.baseSelectedFields
1306
1503
  };
1307
- const remapper = createTableRefRemapper(polyInfo.baseTable, childTableRef);
1504
+ const remapper = createTableRefRemapper$1(polyInfo.baseTable, childTableRef);
1308
1505
  return {
1309
1506
  joins: joins.map((join) => join.rewrite(remapper)),
1310
1507
  projection,
@@ -1368,12 +1565,13 @@ function buildManyToManyJunctionArtifacts(parentLocalRefs, childTableRef, throug
1368
1565
  }
1369
1566
  function buildIncludeChildRowsSelect(contract, aggregates, parentSource, include) {
1370
1567
  const childState = include.nested;
1568
+ if (childState.distinctOn !== void 0 && childState.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1371
1569
  const parentLocalRefs = resolveParentLocalRefs(parentSource, include, localColumnsForRowInclude(include));
1372
1570
  const childSource = resolveChildTableSource(include, parentLocalRefs);
1373
1571
  const childTableAlias = childSource.alias;
1374
1572
  const childTableRef = childSource.tableRef;
1375
1573
  const rowsAlias = `${include.relationName}__rows`;
1376
- const remappedChildOrderBy = childTableAlias && childState.orderBy ? childState.orderBy.map((item) => item.rewrite(createTableRefRemapper(include.relatedTableName, childTableRef))) : childState.orderBy;
1574
+ const remappedChildOrderBy = childTableAlias && childState.orderBy ? childState.orderBy.map((item) => item.rewrite(createTableRefRemapper$1(include.relatedTableName, childTableRef))) : childState.orderBy;
1377
1575
  const { childOrderBy, hiddenOrderProjection, aggregateOrderBy } = buildIncludeOrderArtifacts(include.relationName, rowsAlias, remappedChildOrderBy);
1378
1576
  const childWhere = buildStateWhere(contract, childTableRef, childState, {
1379
1577
  filterTableName: include.relatedTableName,
@@ -1503,8 +1701,8 @@ function buildDistinctNonLeafChildRowsSelect(options) {
1503
1701
  };
1504
1702
  }
1505
1703
  /**
1506
- * Build the inner SELECT for a scalar include reducer (`count` /
1507
- * `sum` / `avg` / `min` / `max`).
1704
+ * Build the inner SELECT for a scalar include reducer (any operation the aggregate registry
1705
+ * contributes).
1508
1706
  *
1509
1707
  * Emits one row containing `json_build_object('value', AGG(...))`
1510
1708
  * over the child relation correlated to the parent via the FK. The
@@ -1513,18 +1711,18 @@ function buildDistinctNonLeafChildRowsSelect(options) {
1513
1711
  * pulls `.value` out).
1514
1712
  *
1515
1713
  * The refine state's pipeline composes through to the aggregate's
1516
- * input set: `where` / `orderBy` / `take` / `skip` / `distinct` shape
1714
+ * input set: `where` / `orderBy` / `limit` / `offset` / `distinct` shape
1517
1715
  * the rows the aggregate sees, matching the natural compositional
1518
1716
  * semantic of
1519
1717
  *
1520
- * `db.User.include('posts', p => p.where(W).take(N).count()) // ≤ N`
1718
+ * `db.User.include('posts', p => p.where(W).limit(N).count()) // ≤ N`
1521
1719
  *
1522
- * When `take` / `skip` / `distinct` is set, the aggregate's input
1720
+ * When `limit` / `offset` / `distinct` is set, the aggregate's input
1523
1721
  * cannot just be the bare correlated table — a top-level `LIMIT` on
1524
1722
  * the aggregating SELECT only trims the (already one-row) output, not
1525
1723
  * the rows being aggregated. We therefore wrap the source in a
1526
1724
  * derived SELECT that materialises the shaped row set, then
1527
- * aggregate over that. `orderBy` alone (no `take` / `skip` /
1725
+ * aggregate over that. `orderBy` alone (no `limit` / `offset` /
1528
1726
  * `distinct`) is dropped at the SQL level since reordering does not
1529
1727
  * change which rows are aggregated.
1530
1728
  */
@@ -1542,6 +1740,7 @@ function buildIncludeChildScalarSelect(contract, aggregates, parentSource, inclu
1542
1740
  const childTableAlias = childSource.alias;
1543
1741
  const childTableRef = childSource.tableRef;
1544
1742
  const state = scalar.state;
1743
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1545
1744
  const childWhere = buildStateWhere(contract, childTableRef, state, {
1546
1745
  filterTableName: include.relatedTableName,
1547
1746
  namespaceId: include.relatedNamespaceId
@@ -1558,7 +1757,7 @@ function buildIncludeChildScalarSelect(contract, aggregates, parentSource, inclu
1558
1757
  const joinExpr = BinaryExpr.eq(ColumnRef.of(childTableRef, include.targetColumn), parentLocalRef);
1559
1758
  whereExpr = childWhere ? AndExpr.of([joinExpr, childWhere]) : joinExpr;
1560
1759
  }
1561
- const remappedOrderBy = childTableAlias && state.orderBy ? state.orderBy.map((item) => item.rewrite(createTableRefRemapper(include.relatedTableName, childTableRef))) : state.orderBy;
1760
+ const remappedOrderBy = childTableAlias && state.orderBy ? state.orderBy.map((item) => item.rewrite(createTableRefRemapper$1(include.relatedTableName, childTableRef))) : state.orderBy;
1562
1761
  const hasPagination = state.limit !== void 0 || state.offset !== void 0;
1563
1762
  const hasDistinct = state.distinct !== void 0 && state.distinct.length > 0 || state.distinctOn !== void 0 && state.distinctOn.length > 0;
1564
1763
  if (!(hasPagination || hasDistinct)) {
@@ -1615,7 +1814,7 @@ function buildIncludeAggregateExpr(scalar, childTableRef, lower, inputCodec) {
1615
1814
  * Row branches reuse the standalone row-include builder; scalar
1616
1815
  * branches reuse `buildIncludeChildScalarSelect` — the `{value: ...}`
1617
1816
  * envelope survives into the combined JSON and the decoder unwraps
1618
- * it per scalar branch. Distinct/take/skip semantics inside a row
1817
+ * it per scalar branch. Distinct/limit/offset semantics inside a row
1619
1818
  * branch fan out naturally because the row builder is invoked with
1620
1819
  * a synthetic IncludeExpr whose `nested` is the branch's state.
1621
1820
  */
@@ -1676,13 +1875,11 @@ function buildCorrelatedIncludeProjection(contract, aggregates, parentSource, in
1676
1875
  }
1677
1876
  function buildSelectAst(contract, tableName, state, options) {
1678
1877
  const namespaceId = options.namespaceId;
1878
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1679
1879
  const projection = [...buildProjection(contract, namespaceId, tableName, state.selectedFields, tableName), ...options.includeProjection ?? []];
1680
- const where = options.where ?? buildStateWhere(contract, tableName, state, { namespaceId });
1681
- const usesRowNumberDistinct = state.distinct !== void 0 && state.distinct.length > 0;
1682
- const fromSource = usesRowNumberDistinct ? DerivedTableSource.as(tableName, buildTopLevelDistinctRankedInner(contract, namespaceId, tableName, state, where)) : tableSourceForContract(contract, namespaceId, tableName);
1880
+ const { source: fromSource, where: effectiveWhere } = buildDedupedTableSource(contract, namespaceId, tableName, state, options.where ?? buildStateWhere(contract, tableName, state, { namespaceId }), resolveTableColumns(contract, namespaceId, tableName).map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column))));
1683
1881
  let ast = SelectAst.from(fromSource).withProjection(projection);
1684
- if (usesRowNumberDistinct) ast = ast.withWhere(BinaryExpr.eq(ColumnRef.of(tableName, "__prisma_distinct_rn"), LiteralExpr.of(1)));
1685
- else if (where) ast = ast.withWhere(where);
1882
+ if (effectiveWhere) ast = ast.withWhere(effectiveWhere);
1686
1883
  if (state.orderBy) ast = ast.withOrderBy(state.orderBy);
1687
1884
  if (state.selectedFields === void 0) ast = ast.withSelectAllIntent({ table: tableName });
1688
1885
  if (state.distinctOn && state.distinctOn.length > 0) ast = ast.withDistinctOn(state.distinctOn.map((column) => ColumnRef.of(tableName, column)));
@@ -1690,197 +1887,70 @@ function buildSelectAst(contract, tableName, state, options) {
1690
1887
  if (state.offset !== void 0) ast = ast.withOffset(state.offset);
1691
1888
  if (options.joins && options.joins.length > 0) ast = ast.withJoins(options.joins);
1692
1889
  return ast;
1693
- }
1694
- function buildTopLevelDistinctRankedInner(contract, namespaceId, tableName, state, where) {
1695
- const distinctColumns = state.distinct;
1696
- if (distinctColumns === void 0 || distinctColumns.length === 0) throw new InternalError("buildTopLevelDistinctRankedInner called without `state.distinct`");
1697
- const allColsProjection = resolveTableColumns(contract, namespaceId, tableName).map((column) => ProjectionItem.of(column, ColumnRef.of(tableName, column)));
1698
- const distinctColumnRefs = distinctColumns.map((column) => ColumnRef.of(tableName, column));
1699
- const rankingOrderBy = state.orderBy && state.orderBy.length > 0 ? state.orderBy : distinctColumnRefs.map((expr) => OrderByItem.asc(expr));
1700
- let inner = SelectAst.from(tableSourceForContract(contract, namespaceId, tableName)).withProjection([...allColsProjection, ProjectionItem.of("__prisma_distinct_rn", WindowFuncExpr.rowNumber({
1701
- partitionBy: distinctColumnRefs,
1702
- orderBy: rankingOrderBy
1703
- }))]);
1704
- if (where) inner = inner.withWhere(where);
1705
- return inner;
1706
- }
1707
- function buildMtiJoins(contract, namespaceId, polyInfo, variantName, selectedColumnsByTable) {
1708
- const joins = [];
1709
- const projection = [];
1710
- const pkColumn = resolvePrimaryKeyColumn(contract, namespaceId, polyInfo.baseTable);
1711
- const variantsToJoin = variantName ? polyInfo.mtiVariants.filter((v) => v.modelName === variantName) : polyInfo.mtiVariants;
1712
- for (const variant of variantsToJoin) {
1713
- const joinType = variantName ? "inner" : "left";
1714
- const joinOn = EqColJoinOn.of(ColumnRef.of(polyInfo.baseTable, pkColumn), ColumnRef.of(variant.table, pkColumn));
1715
- const join = joinType === "inner" ? JoinAst.inner(tableSourceForContract(contract, namespaceId, variant.table), joinOn) : JoinAst.left(tableSourceForContract(contract, namespaceId, variant.table), joinOn);
1716
- joins.push(join);
1717
- const variantColumns = resolveTableColumns(contract, namespaceId, variant.table);
1718
- const selectedVariantColumns = selectedColumnsByTable?.get(variant.table);
1719
- for (const col of variantColumns) {
1720
- if (col === pkColumn) continue;
1721
- if (selectedColumnsByTable !== void 0 && selectedVariantColumns?.has(col) !== true) continue;
1722
- const alias = `${variant.table}__${col}`;
1723
- projection.push(ProjectionItem.of(alias, ColumnRef.of(variant.table, col), codecRefForStorageColumn(contract.storage, namespaceId, variant.table, col)));
1724
- }
1725
- }
1726
- return {
1727
- joins,
1728
- projection
1729
- };
1730
- }
1731
- function compileSelect(contract, namespaceId, tableName, state, modelName) {
1732
- const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1733
- const selection = polyInfo && modelName ? resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state) : void 0;
1734
- const projectionState = selection ? {
1735
- ...state,
1736
- selectedFields: selection.baseSelectedFields
1737
- } : state;
1738
- const mtiArtifacts = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection?.selectedMtiColumnsByTable) : void 0;
1739
- const hiddenProjection = polyInfo && selection ? buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator) : [];
1740
- const ast = buildSelectAst(contract, tableName, {
1741
- ...projectionState,
1742
- includes: []
1743
- }, {
1744
- joins: mtiArtifacts?.joins ?? [],
1745
- includeProjection: [...mtiArtifacts?.projection ?? [], ...hiddenProjection],
1746
- namespaceId
1747
- });
1748
- const { params } = deriveParamsFromAst(ast);
1749
- return buildOrmQueryPlan(contract, ast, params, state.annotations);
1750
- }
1751
- function compileSelectWithIncludes(contract, aggregates, namespaceId, tableName, state, modelName) {
1752
- const includeJoins = [];
1753
- const includeProjection = [];
1754
- const topLevelWhere = buildStateWhere(contract, tableName, state, { namespaceId });
1755
- const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1756
- const selection = polyInfo && modelName ? resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state) : void 0;
1757
- const projectionState = selection ? {
1758
- ...state,
1759
- selectedFields: selection.baseSelectedFields
1760
- } : state;
1761
- if (polyInfo && selection) {
1762
- if (polyInfo.mtiVariants.length > 0) {
1763
- const mtiArtifacts = buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection.selectedMtiColumnsByTable);
1764
- includeJoins.push(...mtiArtifacts.joins);
1765
- includeProjection.push(...mtiArtifacts.projection);
1766
- }
1767
- includeProjection.push(...buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator));
1768
- }
1769
- const parentSource = {
1770
- baseTableName: tableName,
1771
- tableRef: tableName,
1772
- variantColumnsProjected: false
1773
- };
1774
- for (const include of state.includes) {
1775
- const artifact = buildCorrelatedIncludeProjection(contract, aggregates, parentSource, include);
1776
- includeProjection.push(artifact.projection);
1777
- }
1778
- const ast = buildSelectAst(contract, tableName, {
1779
- ...projectionState,
1780
- includes: []
1781
- }, {
1782
- joins: includeJoins,
1783
- includeProjection,
1784
- namespaceId,
1785
- ...ifDefined("where", topLevelWhere)
1786
- });
1787
- const { params } = deriveParamsFromAst(ast);
1788
- return buildOrmQueryPlan(contract, ast, params, state.annotations);
1789
- }
1790
- function queryPlanRows(scope, plan) {
1791
- return scope.query(plan);
1792
- }
1793
- function emptyState() {
1794
- return {
1795
- filters: [],
1796
- includes: [],
1797
- orderBy: void 0,
1798
- cursor: void 0,
1799
- distinct: void 0,
1800
- distinctOn: void 0,
1801
- selectedFields: void 0,
1802
- limit: void 0,
1803
- offset: void 0,
1804
- variantName: void 0,
1805
- annotations: /* @__PURE__ */ new Map()
1806
- };
1807
- }
1808
- function param(codec, value) {
1809
- if (codec === void 0) return ParamRef.of(value);
1810
- return ParamRef.of(value, { codec });
1811
- }
1812
- function paramList(codec, values) {
1813
- return ListExpression.of(values.map((value) => param(codec, value)));
1814
- }
1815
- function scalarComparisonMethod(op) {
1816
- return ((left, codec) => (value) => {
1817
- if (value === null && (op === "eq" || op === "neq")) return op === "eq" ? NullCheckExpr.isNull(left) : NullCheckExpr.isNotNull(left);
1818
- return new BinaryExpr(op, left, param(codec, value));
1819
- });
1820
- }
1821
- function listComparisonMethod(op) {
1822
- return ((left, codec) => (values) => new BinaryExpr(op, left, paramList(codec, values)));
1823
- }
1824
- /**
1825
- * Declares trait requirements and runtime factory for each comparison method.
1826
- *
1827
- * - `traits: []` means "no trait required" — always available
1828
- * - Multi-trait: `traits: ['equality', 'order']` means BOTH traits are required
1829
- */
1830
- const COMPARISON_METHODS_META = {
1831
- eq: {
1832
- traits: ["equality"],
1833
- create: scalarComparisonMethod("eq")
1834
- },
1835
- neq: {
1836
- traits: ["equality"],
1837
- create: scalarComparisonMethod("neq")
1838
- },
1839
- in: {
1840
- traits: ["equality"],
1841
- create: listComparisonMethod("in")
1842
- },
1843
- notIn: {
1844
- traits: ["equality"],
1845
- create: listComparisonMethod("notIn")
1846
- },
1847
- gt: {
1848
- traits: ["order"],
1849
- create: scalarComparisonMethod("gt")
1850
- },
1851
- lt: {
1852
- traits: ["order"],
1853
- create: scalarComparisonMethod("lt")
1854
- },
1855
- gte: {
1856
- traits: ["order"],
1857
- create: scalarComparisonMethod("gte")
1858
- },
1859
- lte: {
1860
- traits: ["order"],
1861
- create: scalarComparisonMethod("lte")
1862
- },
1863
- like: {
1864
- traits: ["textual"],
1865
- create: scalarComparisonMethod("like")
1866
- },
1867
- asc: {
1868
- traits: ["order"],
1869
- create: (left) => () => OrderByItem.asc(left)
1870
- },
1871
- desc: {
1872
- traits: ["order"],
1873
- create: (left) => () => OrderByItem.desc(left)
1874
- },
1875
- isNull: {
1876
- traits: [],
1877
- create: (left) => () => NullCheckExpr.isNull(left)
1878
- },
1879
- isNotNull: {
1880
- traits: [],
1881
- create: (left) => () => NullCheckExpr.isNotNull(left)
1890
+ }
1891
+ function compileSelect(contract, namespaceId, tableName, state, modelName) {
1892
+ if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
1893
+ const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1894
+ const selection = polyInfo && modelName ? resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state) : void 0;
1895
+ const projectionState = selection ? {
1896
+ ...state,
1897
+ selectedFields: selection.baseSelectedFields
1898
+ } : state;
1899
+ const mtiArtifacts = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection?.selectedMtiColumnsByTable) : void 0;
1900
+ const hiddenProjection = polyInfo && selection ? buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator) : [];
1901
+ const ast = buildSelectAst(contract, tableName, {
1902
+ ...projectionState,
1903
+ includes: []
1904
+ }, {
1905
+ joins: mtiArtifacts?.joins ?? [],
1906
+ includeProjection: [...mtiArtifacts?.projection ?? [], ...hiddenProjection],
1907
+ namespaceId
1908
+ });
1909
+ const { params } = deriveParamsFromAst(ast);
1910
+ return buildOrmQueryPlan(contract, ast, params, state.annotations);
1911
+ }
1912
+ function compileSelectWithIncludes(contract, aggregates, namespaceId, tableName, state, modelName) {
1913
+ const includeJoins = [];
1914
+ const includeProjection = [];
1915
+ const topLevelWhere = buildStateWhere(contract, tableName, state, { namespaceId });
1916
+ const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
1917
+ const selection = polyInfo && modelName ? resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state) : void 0;
1918
+ const projectionState = selection ? {
1919
+ ...state,
1920
+ selectedFields: selection.baseSelectedFields
1921
+ } : state;
1922
+ if (polyInfo && selection) {
1923
+ if (polyInfo.mtiVariants.length > 0) {
1924
+ const mtiArtifacts = buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection.selectedMtiColumnsByTable);
1925
+ includeJoins.push(...mtiArtifacts.joins);
1926
+ includeProjection.push(...mtiArtifacts.projection);
1927
+ }
1928
+ includeProjection.push(...buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator));
1882
1929
  }
1883
- };
1930
+ const parentSource = {
1931
+ baseTableName: tableName,
1932
+ tableRef: tableName,
1933
+ variantColumnsProjected: false
1934
+ };
1935
+ for (const include of state.includes) {
1936
+ const artifact = buildCorrelatedIncludeProjection(contract, aggregates, parentSource, include);
1937
+ includeProjection.push(artifact.projection);
1938
+ }
1939
+ const ast = buildSelectAst(contract, tableName, {
1940
+ ...projectionState,
1941
+ includes: []
1942
+ }, {
1943
+ joins: includeJoins,
1944
+ includeProjection,
1945
+ namespaceId,
1946
+ ...ifDefined("where", topLevelWhere)
1947
+ });
1948
+ const { params } = deriveParamsFromAst(ast);
1949
+ return buildOrmQueryPlan(contract, ast, params, state.annotations);
1950
+ }
1951
+ function queryPlanRows(scope, plan) {
1952
+ return scope.query(plan);
1953
+ }
1884
1954
  function dispatchCollectionRows(options) {
1885
1955
  const { context, runtime, state, tableName, modelName, namespaceId } = options;
1886
1956
  const { contract } = context;
@@ -1892,22 +1962,18 @@ function dispatchWithIncludes(options) {
1892
1962
  const { context, runtime, state, tableName, modelName, namespaceId } = options;
1893
1963
  const { contract } = context;
1894
1964
  const generator = async function* () {
1895
- const { scope, release } = await acquireRuntimeScope(runtime);
1896
- try {
1897
- const parentRowsRaw = await queryPlanRows(scope, compileSelectWithIncludes(contract, context.aggregateDescriptors, namespaceId, tableName, state, modelName)).toArray();
1898
- if (parentRowsRaw.length === 0) return;
1899
- const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
1900
- const parentRows = parentRowsRaw.map((row) => {
1901
- return {
1902
- raw: row,
1903
- mapped: polyInfo ? mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, row, state.variantName) : mapStorageRowToModelFields(contract, namespaceId, modelName, row)
1904
- };
1905
- });
1906
- for (const parent of parentRows) for (const include of state.includes) parent.mapped[include.relationName] = await decodeIncludePayload(contract, context, include, parent.raw[include.relationName]);
1907
- for (const row of parentRows) yield blindCast(row.mapped);
1908
- } finally {
1909
- if (release) await release();
1910
- }
1965
+ const compiled = compileSelectWithIncludes(contract, context.aggregateDescriptors, namespaceId, tableName, state, modelName);
1966
+ const parentRowsRaw = await queryPlanRows(runtime, compiled).toArray();
1967
+ if (parentRowsRaw.length === 0) return;
1968
+ const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
1969
+ const parentRows = parentRowsRaw.map((row) => {
1970
+ return {
1971
+ raw: row,
1972
+ mapped: polyInfo ? mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, row, state.variantName) : mapStorageRowToModelFields(contract, namespaceId, modelName, row)
1973
+ };
1974
+ });
1975
+ for (const parent of parentRows) for (const include of state.includes) parent.mapped[include.relationName] = await decodeIncludePayload(contract, context, include, parent.raw[include.relationName]);
1976
+ for (const row of parentRows) yield blindCast(row.mapped);
1911
1977
  };
1912
1978
  return new AsyncIterableResult(generator());
1913
1979
  }
@@ -1981,11 +2047,9 @@ function buildIdentityInFilter(contract, namespaceId, tableName, identityColumns
1981
2047
  *
1982
2048
  * Scalar leaves arrive wrapped in a `{ value: <primitive> }` JSON
1983
2049
  * envelope (see `buildIncludeChildScalarSelect`); the branch below
1984
- * unwraps that envelope and passes the value straight through. The
1985
- * empty-relation default is driven by SQL semantics, not the decoder:
1986
- * `COUNT(*)` over an empty input set is `0`; `SUM` / `AVG` / `MIN` /
1987
- * `MAX` over an empty input set are SQL `NULL`, which surfaces as
1988
- * `null` in TS — the documented contract for those reducers.
2050
+ * unwraps that envelope and passes the value straight through. The empty-relation value reads off
2051
+ * the operation's declared row via `emptyAggregateResult`: `null` where the row is nullable,
2052
+ * otherwise the row's declared empty value (so `count()` is `0`).
1989
2053
  *
1990
2054
  * Combine descriptors arrive as a JSON object keyed by branch name;
1991
2055
  * each branch is dispatched to the row or scalar decoder per its
@@ -2100,10 +2164,7 @@ function wrapIncludedDecodeFailure(error, ref, codecId) {
2100
2164
  * On a parent with zero matching child rows the correlated subquery
2101
2165
  * still produces one row (aggregates collapse the empty input to a
2102
2166
  * single row), so the combine envelope here is always present in the
2103
- * read path. The
2104
- * mutation read-back's `assignEmptyMutationIncludes` writes the empty
2105
- * per-branch shape directly to `parent.mapped[relationName]` for any
2106
- * parent absent from the read-back result and never enters the decoder,
2167
+ * read path. Mutation read-back goes through the same read dispatch,
2107
2168
  * so a missing or non-object envelope here is always a planner/decoder
2108
2169
  * bug — `parseCombineEnvelope` throws loudly rather than papering over
2109
2170
  * it with an empty shape.
@@ -2143,8 +2204,7 @@ function describeEnvelopeShape(value) {
2143
2204
  *
2144
2205
  * Contract: the envelope is always either
2145
2206
  * - a `{ value: <primitive> }` JSON object (the SQL path), or
2146
- * - `null` / `undefined` (the mutation read-back's empty-include
2147
- * short-circuit, for a parent absent from the read-back result).
2207
+ * - `null` / `undefined` (no row reached the decoder), answered with `emptyAggregateResult`.
2148
2208
  *
2149
2209
  * Any other shape — array, primitive, string that JSON-parses to
2150
2210
  * non-object — indicates a planner / decoder bug, so we throw
@@ -2255,224 +2315,78 @@ function dispatchSplitMutationRows(options) {
2255
2315
  const mapped = mapStorageRow(rawRow);
2256
2316
  if (hiddenColumns.length > 0) stripHiddenMappedFields(contract, namespaceId, modelName, mapped, hiddenColumns);
2257
2317
  yield mapRow(mapped);
2258
- }
2259
- };
2260
- return new AsyncIterableResult(generator());
2261
- }
2262
- async function executeMutationReturningSingleRow(options) {
2263
- const { context, runtime, compiled, tableName, modelName, namespaceId, variantName, includes, selectedFields, hiddenColumns, mapRow, operation, onMissingRowMessage } = options;
2264
- const { contract } = context;
2265
- const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, variantName);
2266
- if (includes.length === 0) {
2267
- const first = (await queryPlanRows(runtime, compiled).toArray())[0];
2268
- if (!first) return null;
2269
- const mapped = mapStorageRow(first);
2270
- if (hiddenColumns.length > 0) stripHiddenMappedFields(contract, namespaceId, modelName, mapped, hiddenColumns);
2271
- return mapRow(mapped);
2272
- }
2273
- const identityRows = await queryPlanRows(runtime, compiled).toArray();
2274
- if (identityRows.length === 0) return null;
2275
- for await (const row of reloadMutationRowsByIdentities({
2276
- context,
2277
- runtime,
2278
- tableName,
2279
- modelName,
2280
- namespaceId,
2281
- identityRows,
2282
- selectedFields,
2283
- includes
2284
- })) return row;
2285
- throw ormError("ORM.MUTATION_ROW_MISSING", onMissingRowMessage, { meta: {
2286
- operation,
2287
- model: modelName,
2288
- tableName
2289
- } });
2290
- }
2291
- function and(...exprs) {
2292
- return AndExpr.of(exprs);
2293
- }
2294
- function or(...exprs) {
2295
- return OrExpr.of(exprs);
2296
- }
2297
- function not(expr) {
2298
- return expr.not();
2299
- }
2300
- function all() {
2301
- return AndExpr.true();
2302
- }
2303
- function shorthandToWhereExpr(context, namespaceId, modelName, filters) {
2304
- const contract = context.contract;
2305
- const tableName = resolveModelTableName(contract, namespaceId, modelName);
2306
- const fieldToColumn = getFieldToColumnMap(contract, namespaceId, modelName);
2307
- const exprs = [];
2308
- for (const [fieldName, value] of Object.entries(filters)) {
2309
- if (value === void 0) continue;
2310
- const columnName = fieldToColumn[fieldName] ?? fieldName;
2311
- const left = ColumnRef.of(tableName, columnName);
2312
- if (value === null) {
2313
- exprs.push(NullCheckExpr.isNull(left));
2314
- continue;
2315
- }
2316
- assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName);
2317
- exprs.push(BinaryExpr.eq(left, LiteralExpr.of(value)));
2318
- }
2319
- if (exprs.length === 0) return;
2320
- return exprs.length === 1 ? exprs[0] : and(...exprs);
2321
- }
2322
- function assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName) {
2323
- const fieldType = modelOf(context.contract, namespaceId, modelName)?.fields?.[fieldName]?.type;
2324
- const codecId = fieldType?.kind === "scalar" ? fieldType.codecId : void 0;
2325
- if (!(codecId ? context.codecDescriptors.descriptorFor(codecId)?.traits ?? [] : []).includes("equality")) throw ormError("ORM.FILTER_UNSUPPORTED", `Shorthand filter on "${modelName}.${fieldName}": field does not support equality comparisons`, { meta: {
2326
- model: modelName,
2327
- field: fieldName,
2328
- trait: "equality"
2329
- } });
2330
- }
2331
- var GroupedCollection = class GroupedCollection {
2332
- ctx;
2333
- contract;
2334
- modelName;
2335
- tableName;
2336
- namespaceId;
2337
- baseFilters;
2338
- groupByFields;
2339
- groupByColumns;
2340
- havingFilters;
2341
- constructor(ctx, modelName, options) {
2342
- this.ctx = ctx;
2343
- this.contract = ctx.context.contract;
2344
- this.modelName = modelName;
2345
- this.tableName = options.tableName;
2346
- this.namespaceId = options.namespaceId;
2347
- this.baseFilters = options.baseFilters;
2348
- this.groupByFields = options.groupByFields;
2349
- this.groupByColumns = options.groupByColumns;
2350
- this.havingFilters = options.havingFilters;
2351
- }
2352
- having(predicate) {
2353
- const havingExpr = predicate(createHavingBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName, this.tableName));
2354
- return new GroupedCollection(this.ctx, this.modelName, {
2355
- tableName: this.tableName,
2356
- namespaceId: this.namespaceId,
2357
- baseFilters: this.baseFilters,
2358
- groupByFields: this.groupByFields,
2359
- groupByColumns: this.groupByColumns,
2360
- havingFilters: [...this.havingFilters, havingExpr]
2361
- });
2362
- }
2363
- /**
2364
- * Read terminal: run a grouped aggregate query.
2365
- *
2366
- * Accepts an optional `configure` callback that receives a
2367
- * `MetaBuilder<'read'>` for attaching typed annotations.
2368
- * Annotations are merged into the compiled plan's `meta.annotations`.
2369
- */
2370
- async aggregate(fn, configure) {
2371
- const aggregateSpec = fn(createAggregateBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName));
2372
- const aggregateEntries = Object.entries(aggregateSpec);
2373
- if (aggregateEntries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "groupBy().aggregate() requires at least one aggregation selector", { meta: {
2374
- method: "groupBy.aggregate",
2375
- model: this.modelName
2376
- } });
2377
- for (const [alias, selector] of aggregateEntries) if (!isAggregateSelector(selector)) throw ormError("ORM.AGGREGATE_SELECTOR_INVALID", `groupBy().aggregate() selector "${alias}" is invalid`, { meta: {
2378
- method: "groupBy.aggregate",
2379
- model: this.modelName,
2380
- alias
2381
- } });
2382
- let annotationsMap;
2383
- if (configure !== void 0) {
2384
- const meta = createMetaBuilder("read", "groupBy.aggregate");
2385
- configure(meta);
2386
- if (meta.annotations.size > 0) annotationsMap = meta.annotations;
2387
- }
2388
- const compiled = mergeAnnotations(compileGroupedAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.tableName, this.baseFilters, this.groupByColumns, aggregateSpec, combineWhereExprs(this.havingFilters)), annotationsMap);
2389
- return (await queryPlanRows(this.ctx.runtime, compiled).toArray()).map((row) => {
2390
- const mapped = mapStorageRowToModelFields(this.contract, this.namespaceId, this.modelName, row);
2391
- for (const [alias] of aggregateEntries) mapped[alias] = row[alias];
2392
- return mapped;
2393
- });
2394
- }
2395
- };
2396
- /**
2397
- * The having metric methods, one per operation the registry contributes —
2398
- * the runtime mirror of the contract's emitted aggregate map, which is what
2399
- * types the surface as {@link HavingBuilder}. HAVING compares the value
2400
- * inside the database, so only an operation's plain `AggregateExpr` form is
2401
- * sound here: an operation outside the SQL aggregate alphabet exists only in
2402
- * its descriptor-lowered form — a rendering for the driver boundary — and is
2403
- * refused. The typed surface already excludes it; the runtime refusal covers
2404
- * dynamic invocation.
2405
- */
2406
- function createHavingBuilder(contract, aggregates, namespaceId, modelName, tableName) {
2407
- const fieldToColumn = getFieldToColumnMap(contract, namespaceId, modelName);
2408
- const builder = {};
2409
- for (const operation of aggregateOperationNames(aggregates)) builder[operation] = (field) => {
2410
- if (!isAggregateFn(operation)) throw ormError("ORM.AGGREGATE_PROJECTION_ONLY", `Aggregate operation '${operation}' is projection-only: it has no plain SQL form for HAVING, ORDER BY, or comparison positions.`, {
2411
- why: "An operation outside the SQL aggregate alphabet reaches SQL only through its descriptor's lowering hook — a rendering for the driver boundary. HAVING and ORDER BY compare the value inside the database, where that rendering would change SQL semantics.",
2412
- fix: `Project '${operation}' in a select and filter or order on the projected value, or use an operation from the SQL aggregate alphabet.`,
2413
- meta: { operation }
2414
- });
2415
- return createHavingComparisonMethods(new AggregateExpr(operation, field === void 0 ? void 0 : ColumnRef.of(tableName, fieldToColumn[field] ?? field)));
2416
- };
2417
- return blindCast(builder);
2418
- }
2419
- function createHavingComparisonMethods(metric) {
2420
- const buildBinaryExpr = (op, value) => new BinaryExpr(op, metric, LiteralExpr.of(value));
2421
- return {
2422
- eq(value) {
2423
- return buildBinaryExpr("eq", value);
2424
- },
2425
- neq(value) {
2426
- return buildBinaryExpr("neq", value);
2427
- },
2428
- gt(value) {
2429
- return buildBinaryExpr("gt", value);
2430
- },
2431
- lt(value) {
2432
- return buildBinaryExpr("lt", value);
2433
- },
2434
- gte(value) {
2435
- return buildBinaryExpr("gte", value);
2436
- },
2437
- lte(value) {
2438
- return buildBinaryExpr("lte", value);
2439
- }
2440
- };
2441
- }
2442
- function createIncludeScalar(fn, state, column) {
2443
- return {
2444
- kind: "includeScalar",
2445
- fn,
2446
- state,
2447
- ...column !== void 0 ? { column } : {}
2318
+ }
2448
2319
  };
2320
+ return new AsyncIterableResult(generator());
2449
2321
  }
2450
- function createIncludeCombine(branches) {
2451
- return {
2452
- kind: "includeCombine",
2453
- branches
2454
- };
2322
+ async function executeMutationReturningSingleRow(options) {
2323
+ const { context, runtime, compiled, tableName, modelName, namespaceId, variantName, includes, selectedFields, hiddenColumns, mapRow, operation, onMissingRowMessage } = options;
2324
+ const { contract } = context;
2325
+ const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, variantName);
2326
+ if (includes.length === 0) {
2327
+ const first = (await queryPlanRows(runtime, compiled).toArray())[0];
2328
+ if (!first) return null;
2329
+ const mapped = mapStorageRow(first);
2330
+ if (hiddenColumns.length > 0) stripHiddenMappedFields(contract, namespaceId, modelName, mapped, hiddenColumns);
2331
+ return mapRow(mapped);
2332
+ }
2333
+ const identityRows = await queryPlanRows(runtime, compiled).toArray();
2334
+ if (identityRows.length === 0) return null;
2335
+ for await (const row of reloadMutationRowsByIdentities({
2336
+ context,
2337
+ runtime,
2338
+ tableName,
2339
+ modelName,
2340
+ namespaceId,
2341
+ identityRows,
2342
+ selectedFields,
2343
+ includes
2344
+ })) return row;
2345
+ throw ormError("ORM.MUTATION_ROW_MISSING", onMissingRowMessage, { meta: {
2346
+ operation,
2347
+ model: modelName,
2348
+ tableName
2349
+ } });
2455
2350
  }
2456
- function isIncludeScalar(value) {
2457
- if (typeof value !== "object" || value === null) return false;
2458
- const candidate = value;
2459
- return candidate.kind === "includeScalar" && typeof candidate.fn === "string" && isCollectionState(candidate.state);
2351
+ function and(...exprs) {
2352
+ return AndExpr.of(exprs);
2460
2353
  }
2461
- function isIncludeCombine(value) {
2462
- if (typeof value !== "object" || value === null) return false;
2463
- const candidate = value;
2464
- if (candidate.kind !== "includeCombine") return false;
2465
- if (typeof candidate.branches !== "object" || candidate.branches === null) return false;
2466
- return true;
2354
+ function or(...exprs) {
2355
+ return OrExpr.of(exprs);
2467
2356
  }
2468
- function isCollectionStateCarrier(value) {
2469
- if (typeof value !== "object" || value === null) return false;
2470
- return isCollectionState(value.state);
2357
+ function not(expr) {
2358
+ return expr.not();
2471
2359
  }
2472
- function isCollectionState(value) {
2473
- if (typeof value !== "object" || value === null) return false;
2474
- const candidate = value;
2475
- return Array.isArray(candidate.filters) && Array.isArray(candidate.includes);
2360
+ function all() {
2361
+ return AndExpr.true();
2362
+ }
2363
+ function shorthandToWhereExpr(context, namespaceId, modelName, filters) {
2364
+ const contract = context.contract;
2365
+ const tableName = resolveModelTableName(contract, namespaceId, modelName);
2366
+ const fieldToColumn = getFieldToColumnMap(contract, namespaceId, modelName);
2367
+ const exprs = [];
2368
+ for (const [fieldName, value] of Object.entries(filters)) {
2369
+ if (value === void 0) continue;
2370
+ const columnName = fieldToColumn[fieldName] ?? fieldName;
2371
+ const left = ColumnRef.of(tableName, columnName);
2372
+ if (value === null) {
2373
+ exprs.push(NullCheckExpr.isNull(left));
2374
+ continue;
2375
+ }
2376
+ assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName);
2377
+ exprs.push(BinaryExpr.eq(left, LiteralExpr.of(value)));
2378
+ }
2379
+ if (exprs.length === 0) return;
2380
+ return exprs.length === 1 ? exprs[0] : and(...exprs);
2381
+ }
2382
+ function assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName) {
2383
+ const fieldType = modelOf(context.contract, namespaceId, modelName)?.fields?.[fieldName]?.type;
2384
+ const codecId = fieldType?.kind === "scalar" ? fieldType.codecId : void 0;
2385
+ if (!(codecId ? context.codecDescriptors.descriptorFor(codecId)?.traits ?? [] : []).includes("equality")) throw ormError("ORM.FILTER_UNSUPPORTED", `Shorthand filter on "${modelName}.${fieldName}": field does not support equality comparisons`, { meta: {
2386
+ model: modelName,
2387
+ field: fieldName,
2388
+ trait: "equality"
2389
+ } });
2476
2390
  }
2477
2391
  function hasThrough$1(relation) {
2478
2392
  return relation.through !== void 0;
@@ -2786,6 +2700,200 @@ function firstTargetColumn(contract, relation) {
2786
2700
  if (!firstField) return;
2787
2701
  return resolveFieldToColumn(contract, relation.toNamespace, relation.to, firstField);
2788
2702
  }
2703
+ var GroupedCollection = class GroupedCollection {
2704
+ ctx;
2705
+ contract;
2706
+ modelName;
2707
+ tableName;
2708
+ namespaceId;
2709
+ preGroupState;
2710
+ groupByFields;
2711
+ groupByColumns;
2712
+ havingFilters;
2713
+ postGroup;
2714
+ constructor(ctx, modelName, options) {
2715
+ this.ctx = ctx;
2716
+ this.contract = ctx.context.contract;
2717
+ this.modelName = modelName;
2718
+ this.tableName = options.tableName;
2719
+ this.namespaceId = blindCast(options.namespaceId);
2720
+ this.preGroupState = options.preGroupState;
2721
+ this.groupByFields = options.groupByFields;
2722
+ this.groupByColumns = options.groupByColumns;
2723
+ this.havingFilters = options.havingFilters;
2724
+ this.postGroup = options.postGroup;
2725
+ }
2726
+ #clone(overrides) {
2727
+ return blindCast(new GroupedCollection(this.ctx, this.modelName, {
2728
+ tableName: this.tableName,
2729
+ namespaceId: this.namespaceId,
2730
+ preGroupState: this.preGroupState,
2731
+ groupByFields: this.groupByFields,
2732
+ groupByColumns: this.groupByColumns,
2733
+ havingFilters: this.havingFilters,
2734
+ postGroup: this.postGroup,
2735
+ ...overrides
2736
+ }));
2737
+ }
2738
+ having(predicate) {
2739
+ const havingExpr = predicate(createHavingBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName, this.tableName));
2740
+ return this.#clone({ havingFilters: [...this.havingFilters, havingExpr] });
2741
+ }
2742
+ /**
2743
+ * Append an `ORDER BY` clause on the grouped rows themselves — orders by
2744
+ * group key. Ordering by an aggregate alias needs a builder surface over
2745
+ * the aliases and isn't supported here. Unlocks post-group `limit(...)` /
2746
+ * `offset(...)`, which page a group order that would otherwise be undefined.
2747
+ */
2748
+ orderBy(selection) {
2749
+ const selectors = Array.isArray(selection) ? selection : [selection];
2750
+ if (selectors.length === 0) throw ormError("ORM.ARGUMENT_INVALID", `orderBy() for model "${this.modelName}" requires at least one selector`, { meta: {
2751
+ method: "orderBy",
2752
+ model: this.modelName
2753
+ } });
2754
+ const accessor = createModelAccessor(this.ctx.context, this.namespaceId, this.modelName);
2755
+ const nextOrders = selectors.map((selector) => selector(accessor));
2756
+ return this.#clone({ postGroup: {
2757
+ ...this.postGroup,
2758
+ orderBy: [...this.postGroup.orderBy, ...nextOrders]
2759
+ } });
2760
+ }
2761
+ /**
2762
+ * Apply `LIMIT n` to the grouped rows. Replaces any previous post-group
2763
+ * limit. Requires a prior `orderBy(...)` — a database may return groups in
2764
+ * any order, so "the first n groups" is undefined without one.
2765
+ */
2766
+ limit(n) {
2767
+ return this.#clone({ postGroup: {
2768
+ ...this.postGroup,
2769
+ limit: n
2770
+ } });
2771
+ }
2772
+ /**
2773
+ * Apply `OFFSET n` to the grouped rows. Replaces any previous post-group
2774
+ * offset. Requires a prior `orderBy(...)`, same as `limit(...)` — both
2775
+ * pagination methods need a deterministic group order.
2776
+ */
2777
+ offset(n) {
2778
+ return this.#clone({ postGroup: {
2779
+ ...this.postGroup,
2780
+ offset: n
2781
+ } });
2782
+ }
2783
+ /**
2784
+ * Read terminal: run a grouped aggregate query.
2785
+ *
2786
+ * Accepts an optional `configure` callback that receives a
2787
+ * `MetaBuilder<'read'>` for attaching typed annotations.
2788
+ * Annotations are merged into the compiled plan's `meta.annotations`.
2789
+ */
2790
+ async aggregate(fn, configure) {
2791
+ const aggregateSpec = fn(createAggregateBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName));
2792
+ const aggregateEntries = Object.entries(aggregateSpec);
2793
+ if (aggregateEntries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "groupBy().aggregate() requires at least one aggregation selector", { meta: {
2794
+ method: "groupBy.aggregate",
2795
+ model: this.modelName
2796
+ } });
2797
+ for (const [alias, selector] of aggregateEntries) if (!isAggregateSelector(selector)) throw ormError("ORM.AGGREGATE_SELECTOR_INVALID", `groupBy().aggregate() selector "${alias}" is invalid`, { meta: {
2798
+ method: "groupBy.aggregate",
2799
+ model: this.modelName,
2800
+ alias
2801
+ } });
2802
+ let annotationsMap;
2803
+ if (configure !== void 0) {
2804
+ const meta = createMetaBuilder("read", "groupBy.aggregate");
2805
+ configure(meta);
2806
+ if (meta.annotations.size > 0) annotationsMap = meta.annotations;
2807
+ }
2808
+ const compiled = mergeAnnotations(compileGroupedAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.tableName, this.preGroupState, this.groupByColumns, aggregateSpec, combineWhereExprs(this.havingFilters), this.modelName, this.postGroup), annotationsMap);
2809
+ return (await queryPlanRows(this.ctx.runtime, compiled).toArray()).map((row) => {
2810
+ const mapped = mapStorageRowToModelFields(this.contract, this.namespaceId, this.modelName, row);
2811
+ for (const [alias] of aggregateEntries) mapped[alias] = row[alias];
2812
+ return blindCast(mapped);
2813
+ });
2814
+ }
2815
+ };
2816
+ /**
2817
+ * The having metric methods, one per operation the registry contributes —
2818
+ * the runtime mirror of the contract's emitted aggregate map, which is what
2819
+ * types the surface as {@link HavingBuilder}. HAVING compares the value
2820
+ * inside the database, so only an operation's plain `AggregateExpr` form is
2821
+ * sound here: an operation outside the SQL aggregate alphabet exists only in
2822
+ * its descriptor-lowered form — a rendering for the driver boundary — and is
2823
+ * refused. The typed surface already excludes it; the runtime refusal covers
2824
+ * dynamic invocation.
2825
+ */
2826
+ function createHavingBuilder(contract, aggregates, namespaceId, modelName, tableName) {
2827
+ const fieldToColumn = getFieldToColumnMap(contract, namespaceId, modelName);
2828
+ const builder = {};
2829
+ for (const operation of aggregateOperationNames(aggregates)) builder[operation] = (field) => {
2830
+ if (!isAggregateFn(operation)) throw ormError("ORM.AGGREGATE_PROJECTION_ONLY", `Aggregate operation '${operation}' is projection-only: it has no plain SQL form for HAVING, ORDER BY, or comparison positions.`, {
2831
+ why: "An operation outside the SQL aggregate alphabet reaches SQL only through its descriptor's lowering hook — a rendering for the driver boundary. HAVING and ORDER BY compare the value inside the database, where that rendering would change SQL semantics.",
2832
+ fix: `Project '${operation}' in a select and filter or order on the projected value, or use an operation from the SQL aggregate alphabet.`,
2833
+ meta: { operation }
2834
+ });
2835
+ return createHavingComparisonMethods(new AggregateExpr(operation, field === void 0 ? void 0 : ColumnRef.of(tableName, fieldToColumn[field] ?? field)));
2836
+ };
2837
+ return blindCast(builder);
2838
+ }
2839
+ function createHavingComparisonMethods(metric) {
2840
+ const buildBinaryExpr = (op, value) => new BinaryExpr(op, metric, LiteralExpr.of(value));
2841
+ return {
2842
+ eq(value) {
2843
+ return buildBinaryExpr("eq", value);
2844
+ },
2845
+ neq(value) {
2846
+ return buildBinaryExpr("neq", value);
2847
+ },
2848
+ gt(value) {
2849
+ return buildBinaryExpr("gt", value);
2850
+ },
2851
+ lt(value) {
2852
+ return buildBinaryExpr("lt", value);
2853
+ },
2854
+ gte(value) {
2855
+ return buildBinaryExpr("gte", value);
2856
+ },
2857
+ lte(value) {
2858
+ return buildBinaryExpr("lte", value);
2859
+ }
2860
+ };
2861
+ }
2862
+ function createIncludeScalar(fn, state, column) {
2863
+ return {
2864
+ kind: "includeScalar",
2865
+ fn,
2866
+ state,
2867
+ ...column !== void 0 ? { column } : {}
2868
+ };
2869
+ }
2870
+ function createIncludeCombine(branches) {
2871
+ return {
2872
+ kind: "includeCombine",
2873
+ branches
2874
+ };
2875
+ }
2876
+ function isIncludeScalar(value) {
2877
+ if (typeof value !== "object" || value === null) return false;
2878
+ const candidate = value;
2879
+ return candidate.kind === "includeScalar" && typeof candidate.fn === "string" && isCollectionState(candidate.state);
2880
+ }
2881
+ function isIncludeCombine(value) {
2882
+ if (typeof value !== "object" || value === null) return false;
2883
+ const candidate = value;
2884
+ if (candidate.kind !== "includeCombine") return false;
2885
+ if (typeof candidate.branches !== "object" || candidate.branches === null) return false;
2886
+ return true;
2887
+ }
2888
+ function isCollectionStateCarrier(value) {
2889
+ if (typeof value !== "object" || value === null) return false;
2890
+ return isCollectionState(value.state);
2891
+ }
2892
+ function isCollectionState(value) {
2893
+ if (typeof value !== "object" || value === null) return false;
2894
+ const candidate = value;
2895
+ return Array.isArray(candidate.filters) && Array.isArray(candidate.includes);
2896
+ }
2789
2897
  function createRelationMutator() {
2790
2898
  return {
2791
2899
  create(data) {
@@ -3463,34 +3571,6 @@ var CollectionImpl = class CollectionImpl {
3463
3571
  variantName
3464
3572
  });
3465
3573
  }
3466
- /**
3467
- * Eagerly load a related model. The relation appears on every
3468
- * returned row under its declared name; to-one relations are mapped
3469
- * to a single object (or `null`), to-many relations to an array.
3470
- *
3471
- * An optional refinement callback receives a child collection that
3472
- * can be further constrained, projected, ordered, paginated, or
3473
- * reduced to scalars via `count()`/`sum()`/etc. or to multiple
3474
- * sub-aggregates via `combine()`.
3475
- *
3476
- * ```typescript
3477
- * // Simple include — every user comes back with its posts array:
3478
- * const users = await db.orm.User.include('posts').all();
3479
- *
3480
- * // Refine the related collection:
3481
- * const withRecent = await db.orm.User.include('posts', (posts) =>
3482
- * posts.where({ published: true }).orderBy((p) => p.createdAt.desc()).take(5),
3483
- * ).all();
3484
- *
3485
- * // Reduce a to-many relation to a scalar value:
3486
- * const withCounts = await db.orm.User.include('posts', (posts) => posts.count()).all();
3487
- *
3488
- * // Multiple sub-views via combine():
3489
- * const overview = await db.orm.User.include('posts', (posts) =>
3490
- * posts.combine({ recent: posts.take(3), total: posts.count() }),
3491
- * ).all();
3492
- * ```
3493
- */
3494
3574
  include(relationName, refineFn) {
3495
3575
  const relation = resolveIncludeRelation(this.contract, this.namespaceId, this.modelName, relationName, this.state.variantName);
3496
3576
  let nestedState = emptyState();
@@ -3594,10 +3674,11 @@ var CollectionImpl = class CollectionImpl {
3594
3674
  return new GroupedCollection(this.ctx, this.modelName, {
3595
3675
  tableName: this.tableName,
3596
3676
  namespaceId: this.namespaceId,
3597
- baseFilters: this.state.filters,
3677
+ preGroupState: this.state,
3598
3678
  groupByFields: [...fields],
3599
3679
  groupByColumns,
3600
- havingFilters: []
3680
+ havingFilters: [],
3681
+ postGroup: emptyGroupPagingState()
3601
3682
  });
3602
3683
  }
3603
3684
  /**
@@ -3610,7 +3691,7 @@ var CollectionImpl = class CollectionImpl {
3610
3691
  * ```typescript
3611
3692
  * const users = await db.orm.User.include('posts', (posts) =>
3612
3693
  * posts.combine({
3613
- * recent: posts.where({ published: true }).take(3),
3694
+ * recent: posts.where({ published: true }).limit(3),
3614
3695
  * total: posts.count(),
3615
3696
  * averageViews: posts.avg('views'),
3616
3697
  * }),
@@ -3652,14 +3733,14 @@ var CollectionImpl = class CollectionImpl {
3652
3733
  * ```typescript
3653
3734
  * const page1 = await db.orm.Post
3654
3735
  * .orderBy((p) => p.createdAt.desc())
3655
- * .take(20)
3736
+ * .limit(20)
3656
3737
  * .all();
3657
3738
  *
3658
3739
  * const last = page1[page1.length - 1]!;
3659
3740
  * const page2 = await db.orm.Post
3660
3741
  * .orderBy((p) => p.createdAt.desc())
3661
3742
  * .cursor({ createdAt: last.createdAt })
3662
- * .take(20)
3743
+ * .limit(20)
3663
3744
  * .all();
3664
3745
  * ```
3665
3746
  */
@@ -3689,6 +3770,8 @@ var CollectionImpl = class CollectionImpl {
3689
3770
  * prior `orderBy(...)`; replaces any previous `distinct(...)` /
3690
3771
  * `distinctOn(...)` selection.
3691
3772
  *
3773
+ * Requires the `postgres.distinctOn` capability.
3774
+ *
3692
3775
  * ```typescript
3693
3776
  * // Latest post per user:
3694
3777
  * const latestPerUser = await db.orm.Post
@@ -3698,6 +3781,7 @@ var CollectionImpl = class CollectionImpl {
3698
3781
  * ```
3699
3782
  */
3700
3783
  distinctOn(...fields) {
3784
+ assertDistinctOnCapability(this.contract, "distinctOn");
3701
3785
  const distinctOnFields = mapFieldsToColumns(this.contract, this.namespaceId, this.modelName, fields);
3702
3786
  return this.#clone({
3703
3787
  distinct: void 0,
@@ -3708,10 +3792,10 @@ var CollectionImpl = class CollectionImpl {
3708
3792
  * Apply `LIMIT n`. Replaces any previous limit set on this collection.
3709
3793
  *
3710
3794
  * ```typescript
3711
- * const firstTen = await db.orm.User.orderBy((u) => u.id.asc()).take(10).all();
3795
+ * const firstTen = await db.orm.User.orderBy((u) => u.id.asc()).limit(10).all();
3712
3796
  * ```
3713
3797
  */
3714
- take(n) {
3798
+ limit(n) {
3715
3799
  return this.#clone({ limit: n });
3716
3800
  }
3717
3801
  /**
@@ -3720,12 +3804,12 @@ var CollectionImpl = class CollectionImpl {
3720
3804
  * ```typescript
3721
3805
  * const page2 = await db.orm.User
3722
3806
  * .orderBy((u) => u.id.asc())
3723
- * .skip(10)
3724
- * .take(10)
3807
+ * .offset(10)
3808
+ * .limit(10)
3725
3809
  * .all();
3726
3810
  * ```
3727
3811
  */
3728
- skip(n) {
3812
+ offset(n) {
3729
3813
  return this.#clone({ offset: n });
3730
3814
  }
3731
3815
  /**
@@ -3738,15 +3822,9 @@ var CollectionImpl = class CollectionImpl {
3738
3822
  * whichever fits the caller. A single result can only be consumed
3739
3823
  * once.
3740
3824
  *
3741
- * Streaming is the default and the expected execution model. The
3742
- * only scenarios that fall back to buffering internally before
3743
- * yielding are drivers that cannot expose a cursor to the
3744
- * underlying database, and — for queries with `include(...)` —
3745
- * targets whose SQL dialect supports neither lateral joins nor
3746
- * correlated subqueries (so child rows cannot be stitched in a
3747
- * single streaming query). These are implementation details below
3748
- * the public API; the iteration shape itself is genuinely
3749
- * streaming whenever the driver and plan allow it.
3825
+ * Queries without `include(...)` stream rows as the driver yields them (drivers that cannot
3826
+ * expose a cursor buffer internally first). Queries with `include(...)` read the whole parent
3827
+ * result set into memory before yielding the first row.
3750
3828
  *
3751
3829
  * ```typescript
3752
3830
  * // Thenable — collect to an array:
@@ -3773,7 +3851,7 @@ var CollectionImpl = class CollectionImpl {
3773
3851
  return this.#withAnnotationsFromMeta(configure, "all").#dispatch();
3774
3852
  }
3775
3853
  async first(filter, configure) {
3776
- return (await (filter === void 0 ? this : typeof filter === "function" ? this.where(filter) : this.where(filter)).take(1).#withAnnotationsFromMeta(configure, "first").#dispatch().toArray())[0] ?? null;
3854
+ return (await (filter === void 0 ? this : typeof filter === "function" ? this.where(filter) : this.where(filter)).limit(1).#withAnnotationsFromMeta(configure, "first").#dispatch().toArray())[0] ?? null;
3777
3855
  }
3778
3856
  /**
3779
3857
  * Read terminal: run an aggregate query (count, sum, avg, min, max)
@@ -3809,7 +3887,7 @@ var CollectionImpl = class CollectionImpl {
3809
3887
  alias
3810
3888
  } });
3811
3889
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "read", "aggregate");
3812
- const compiled = mergeAnnotations(compileAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.tableName, this.state.filters, aggregateSpec), annotationsMap);
3890
+ const compiled = mergeAnnotations(compileAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.tableName, this.state, aggregateSpec, this.modelName), annotationsMap);
3813
3891
  const row = (await queryPlanRows(this.ctx.runtime, compiled).toArray())[0] ?? {};
3814
3892
  const result = {};
3815
3893
  for (const [alias, selector] of entries) result[alias] = row[alias] ?? this.#emptyAggregateValue(selector);
@@ -4137,12 +4215,13 @@ var CollectionImpl = class CollectionImpl {
4137
4215
  * Requires a prior `.where(...)` — calling `update(...)` on an
4138
4216
  * unfiltered collection is a type error.
4139
4217
  *
4140
- * Related rows can be created or relinked through relation
4141
- * callbacks on parent/child-owned relations (one-to-one or
4142
- * one-to-many). The callback receives a mutator exposing
4143
- * `create(...)`, `connect(...)`, and `disconnect(...)`. Nested
4144
- * updates against existing related rows, and many-to-many relations
4145
- * as nested-mutation targets, are not supported through this API.
4218
+ * Related rows can be created, linked, or unlinked through relation callbacks on any relation:
4219
+ * to-one (1:1, N:1), to-many (1:N), and many-to-many (N:M, written through the junction table).
4220
+ * The callback receives a mutator exposing `create(...)`, `connect(...)`, and `disconnect(...)`.
4221
+ * A to-one `disconnect()` clears the foreign key; a to-many `disconnect()` with no criteria
4222
+ * unlinks every related row; an N:M `disconnect()` requires criteria. N:M `create`/`connect` are
4223
+ * unavailable when the junction has required columns the relation API cannot populate. Nested
4224
+ * updates against existing related rows are not supported through this API.
4146
4225
  *
4147
4226
  * ```typescript
4148
4227
  * // Update one row by id:
@@ -4164,9 +4243,9 @@ var CollectionImpl = class CollectionImpl {
4164
4243
  *
4165
4244
  * Note: when the input contains nested-mutation callbacks, the
4166
4245
  * operation is executed as a graph of internal queries via
4167
- * `withMutationScope`. In that path, annotations apply to the logical
4168
- * `update()` call but do not currently flow into each constituent SQL
4169
- * statement issued for the related rows.
4246
+ * `withMutationScope`. In that path the `configure` callback still runs, so `meta.annotate`
4247
+ * validation applies, but the recorded annotations are discarded: neither the nested
4248
+ * statements nor the read-back query carry them.
4170
4249
  */
4171
4250
  async update(data, configure) {
4172
4251
  assertReturningCapability(this.contract, "update()");
@@ -4573,7 +4652,7 @@ var CollectionImpl = class CollectionImpl {
4573
4652
  * compiled plan is post-wrapped via `mergeAnnotations` instead.
4574
4653
  * Read terminals `all` and `first` populate `state.annotations`
4575
4654
  * via `#withAnnotationsFromMeta` instead; `aggregate` uses this
4576
- * post-wrap path because its compile function doesn't take `state`.
4655
+ * post-wrap path because `compileAggregate` does not forward `state.annotations` into the plan.
4577
4656
  * The meta builder's `annotate` method enforces applicability at the
4578
4657
  * type level and at runtime.
4579
4658
  */