gemi 0.54.3 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/index.js +2 -2
- package/dist/app/index.js.map +1 -1
- package/dist/broadcasting/index.js +1 -1
- package/dist/bun/plugin.js +2 -2
- package/dist/bun/plugin.js.map +1 -1
- package/dist/bun/preload.js +2 -2
- package/dist/bun/preload.js.map +2 -2
- package/dist/{chunk-0weeq0ke.js → chunk-01am9k5v.js} +2 -2
- package/dist/{chunk-0weeq0ke.js.map → chunk-01am9k5v.js.map} +1 -1
- package/dist/chunk-02gdzs5t.js +4 -0
- package/dist/{chunk-4qkzdyj7.js.map → chunk-02gdzs5t.js.map} +1 -1
- package/dist/{chunk-71m47kad.js → chunk-1pwwrpa3.js} +2 -2
- package/dist/{chunk-71m47kad.js.map → chunk-1pwwrpa3.js.map} +2 -2
- package/dist/{chunk-h7mcwfg5.js → chunk-1zfsgffv.js} +4 -4
- package/dist/{chunk-h7mcwfg5.js.map → chunk-1zfsgffv.js.map} +2 -2
- package/dist/{chunk-kz39hphm.js → chunk-31kcf7dq.js} +3 -3
- package/dist/{chunk-kz39hphm.js.map → chunk-31kcf7dq.js.map} +1 -1
- package/dist/chunk-33wjsw4r.js +66 -0
- package/dist/{chunk-tpyhhdq5.js.map → chunk-33wjsw4r.js.map} +4 -54
- package/dist/{chunk-50vm7x98.js → chunk-3e88tyee.js} +3 -3
- package/dist/{chunk-50vm7x98.js.map → chunk-3e88tyee.js.map} +1 -1
- package/dist/{chunk-xxw0gz4q.js → chunk-3y75q5a2.js} +2 -2
- package/dist/{chunk-xxw0gz4q.js.map → chunk-3y75q5a2.js.map} +1 -1
- package/dist/chunk-4qwwy968.js +4 -0
- package/dist/{chunk-1snh7yc4.js.map → chunk-4qwwy968.js.map} +2 -2
- package/dist/{chunk-1sh6kqjn.js → chunk-4t80js0n.js} +3 -3
- package/dist/{chunk-1sh6kqjn.js.map → chunk-4t80js0n.js.map} +1 -1
- package/dist/chunk-4xx78ba9.js +4 -0
- package/dist/{chunk-r9z5rrk0.js.map → chunk-4xx78ba9.js.map} +2 -2
- package/dist/{chunk-g5tj10p8.js → chunk-4yafsffx.js} +2 -2
- package/dist/{chunk-g5tj10p8.js.map → chunk-4yafsffx.js.map} +1 -1
- package/dist/{chunk-gn9zjgep.js → chunk-5ad8era8.js} +2 -2
- package/dist/{chunk-gn9zjgep.js.map → chunk-5ad8era8.js.map} +1 -1
- package/dist/{chunk-3bw1jk21.js → chunk-62723jyy.js} +1 -1
- package/dist/chunk-62ke19q4.js +13 -0
- package/dist/chunk-62ke19q4.js.map +222 -0
- package/dist/{chunk-004bcmsa.js → chunk-64s1pzz1.js} +2 -2
- package/dist/{chunk-004bcmsa.js.map → chunk-64s1pzz1.js.map} +1 -1
- package/dist/{chunk-dwx2y7br.js → chunk-699z6d8y.js} +4 -4
- package/dist/{chunk-dwx2y7br.js.map → chunk-699z6d8y.js.map} +2 -2
- package/dist/{chunk-4zmcbmf9.js → chunk-77xj0dgc.js} +2 -2
- package/dist/{chunk-4zmcbmf9.js.map → chunk-77xj0dgc.js.map} +1 -1
- package/dist/{chunk-bb3zvxsf.js → chunk-8k1zqrvh.js} +3 -3
- package/dist/{chunk-bb3zvxsf.js.map → chunk-8k1zqrvh.js.map} +1 -1
- package/dist/{chunk-9nskvzpv.js → chunk-98a576s9.js} +3 -3
- package/dist/{chunk-9nskvzpv.js.map → chunk-98a576s9.js.map} +1 -1
- package/dist/{chunk-cz3szqhq.js → chunk-9c89q2mz.js} +3 -3
- package/dist/{chunk-cz3szqhq.js.map → chunk-9c89q2mz.js.map} +1 -1
- package/dist/chunk-9r0sb4zn.js +5 -0
- package/dist/{chunk-efsk1wy0.js.map → chunk-9r0sb4zn.js.map} +2 -2
- package/dist/chunk-9r1atj8w.js +6 -0
- package/dist/{chunk-p8fm3tjy.js.map → chunk-9r1atj8w.js.map} +2 -2
- package/dist/chunk-b50zmz3t.js +5 -0
- package/dist/{chunk-113khwbw.js.map → chunk-b50zmz3t.js.map} +1 -1
- package/dist/chunk-cn2r5jfj.js +5 -0
- package/dist/{chunk-dxw8k6f1.js.map → chunk-cn2r5jfj.js.map} +2 -2
- package/dist/{chunk-nncwsdzz.js → chunk-ct274qts.js} +2 -2
- package/dist/{chunk-nncwsdzz.js.map → chunk-ct274qts.js.map} +1 -1
- package/dist/{chunk-jp4pf3yt.js → chunk-d36dfqxw.js} +4 -4
- package/dist/{chunk-jp4pf3yt.js.map → chunk-d36dfqxw.js.map} +2 -2
- package/dist/chunk-dzzmqv0j.js +5 -0
- package/dist/{chunk-f13f68c0.js.map → chunk-dzzmqv0j.js.map} +2 -2
- package/dist/{chunk-f418jh9k.js → chunk-ejrcyzx8.js} +2 -2
- package/dist/{chunk-f418jh9k.js.map → chunk-ejrcyzx8.js.map} +1 -1
- package/dist/chunk-enhkf60v.js +9 -0
- package/dist/chunk-enhkf60v.js.map +12 -0
- package/dist/{chunk-n1tkn8gv.js → chunk-eqrd31ye.js} +2 -2
- package/dist/{chunk-n1tkn8gv.js.map → chunk-eqrd31ye.js.map} +1 -1
- package/dist/{chunk-k14dmqwh.js → chunk-f9mfw82d.js} +3 -3
- package/dist/{chunk-k14dmqwh.js.map → chunk-f9mfw82d.js.map} +1 -1
- package/dist/{chunk-kv2ep453.js → chunk-g30q4n5y.js} +18 -19
- package/dist/{chunk-kv2ep453.js.map → chunk-g30q4n5y.js.map} +4 -8
- package/dist/chunk-gasdfwva.js +4 -0
- package/dist/{chunk-c0wcsmpj.js.map → chunk-gasdfwva.js.map} +2 -2
- package/dist/{chunk-c22vcxty.js → chunk-gzdf2025.js} +2 -2
- package/dist/{chunk-c22vcxty.js.map → chunk-gzdf2025.js.map} +2 -2
- package/dist/{chunk-ms8qd7da.js → chunk-h3mwgbg7.js} +3 -3
- package/dist/{chunk-ms8qd7da.js.map → chunk-h3mwgbg7.js.map} +1 -1
- package/dist/{chunk-6j1z2cqt.js → chunk-hs5v3eqj.js} +2 -2
- package/dist/{chunk-6j1z2cqt.js.map → chunk-hs5v3eqj.js.map} +1 -1
- package/dist/chunk-javjeayw.js +5 -0
- package/dist/{chunk-jdgvdddd.js.map → chunk-javjeayw.js.map} +2 -2
- package/dist/chunk-jdj7k3r9.js +4 -0
- package/dist/{chunk-hk067634.js.map → chunk-jdj7k3r9.js.map} +2 -2
- package/dist/chunk-kgg1eqne.js +4 -0
- package/dist/{chunk-hrrmxreg.js.map → chunk-kgg1eqne.js.map} +2 -2
- package/dist/{chunk-7f5ad759.js → chunk-kgmr9qxx.js} +2 -2
- package/dist/{chunk-7f5ad759.js.map → chunk-kgmr9qxx.js.map} +1 -1
- package/dist/{chunk-pgjk5ft3.js → chunk-kry5vwam.js} +3 -3
- package/dist/{chunk-pgjk5ft3.js.map → chunk-kry5vwam.js.map} +1 -1
- package/dist/{chunk-r06rxn19.js → chunk-m0ggfy1m.js} +3 -3
- package/dist/{chunk-r06rxn19.js.map → chunk-m0ggfy1m.js.map} +1 -1
- package/dist/{chunk-bzhtymvv.js → chunk-npg72mez.js} +2 -2
- package/dist/{chunk-bzhtymvv.js.map → chunk-npg72mez.js.map} +1 -1
- package/dist/chunk-pvdbrt4z.js +5 -0
- package/dist/chunk-pvdbrt4z.js.map +13 -0
- package/dist/{chunk-e3mggavt.js → chunk-q0waxxz5.js} +2 -2
- package/dist/{chunk-e3mggavt.js.map → chunk-q0waxxz5.js.map} +1 -1
- package/dist/chunk-rgb69nh1.js +4 -0
- package/dist/{chunk-s6e7cvek.js.map → chunk-rgb69nh1.js.map} +2 -2
- package/dist/{chunk-jjvnmyw4.js → chunk-rjxdc0xh.js} +2 -2
- package/dist/{chunk-jjvnmyw4.js.map → chunk-rjxdc0xh.js.map} +2 -2
- package/dist/{chunk-sqp7kn7h.js → chunk-rsdg619q.js} +3 -3
- package/dist/{chunk-sqp7kn7h.js.map → chunk-rsdg619q.js.map} +1 -1
- package/dist/chunk-tja0c815.js +5 -0
- package/dist/{chunk-2pt6kyn9.js.map → chunk-tja0c815.js.map} +2 -2
- package/dist/{chunk-agabw2w1.js → chunk-tkdxv6cq.js} +2 -2
- package/dist/{chunk-agabw2w1.js.map → chunk-tkdxv6cq.js.map} +1 -1
- package/dist/chunk-tmnhkphv.js +19 -0
- package/dist/chunk-tmnhkphv.js.map +60 -0
- package/dist/{chunk-w6gb9gc5.js → chunk-v06qcyj5.js} +3 -3
- package/dist/{chunk-w6gb9gc5.js.map → chunk-v06qcyj5.js.map} +1 -1
- package/dist/{chunk-9taz1h3t.js → chunk-v6v6sem5.js} +3 -3
- package/dist/{chunk-9taz1h3t.js.map → chunk-v6v6sem5.js.map} +1 -1
- package/dist/{chunk-f4e7fh95.js → chunk-v7y8zm61.js} +3 -3
- package/dist/{chunk-f4e7fh95.js.map → chunk-v7y8zm61.js.map} +2 -2
- package/dist/{chunk-85av4ncy.js → chunk-vkngcrzq.js} +2 -2
- package/dist/{chunk-85av4ncy.js.map → chunk-vkngcrzq.js.map} +1 -1
- package/dist/chunk-w9k9s4wh.js +4 -0
- package/dist/{chunk-jb2nst6v.js.map → chunk-w9k9s4wh.js.map} +2 -2
- package/dist/chunk-wgpa04jb.js +5 -0
- package/dist/{chunk-6rhebm18.js.map → chunk-wgpa04jb.js.map} +2 -2
- package/dist/chunk-x14sk95v.js +9 -0
- package/dist/{chunk-k8endm5j.js.map → chunk-x14sk95v.js.map} +6 -6
- package/dist/chunk-xjy5apyr.js +4 -0
- package/dist/{chunk-07t0dmdg.js.map → chunk-xjy5apyr.js.map} +2 -2
- package/dist/{chunk-fcqc3e3r.js → chunk-xnytbrda.js} +2 -2
- package/dist/{chunk-fcqc3e3r.js.map → chunk-xnytbrda.js.map} +1 -1
- package/dist/chunk-y9fp58bg.js +4 -0
- package/dist/{chunk-br8ten26.js.map → chunk-y9fp58bg.js.map} +2 -2
- package/dist/{chunk-jb022m7n.js → chunk-yf8kxjr2.js} +2 -2
- package/dist/{chunk-jb022m7n.js.map → chunk-yf8kxjr2.js.map} +1 -1
- package/dist/config/index.js +1 -1
- package/dist/console/run.js +2 -2
- package/dist/console/run.js.map +1 -1
- package/dist/container/index.js +2 -2
- package/dist/container/index.js.map +1 -1
- package/dist/database/DatabaseManager.d.ts.map +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/email/index.js +2 -2
- package/dist/email/index.js.map +1 -1
- package/dist/facades/Storage.d.ts +1 -1
- package/dist/facades/Storage.d.ts.map +1 -1
- package/dist/facades/index.js +2 -2
- package/dist/facades/index.js.map +1 -1
- package/dist/foundation/index.js +2 -2
- package/dist/foundation/index.js.map +1 -1
- package/dist/http/index.js +2 -2
- package/dist/http/index.js.map +1 -1
- package/dist/i18n/dictionaryRuntime.js +2 -2
- package/dist/i18n/dictionaryRuntime.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/kernel/index.js +2 -2
- package/dist/kernel/index.js.map +2 -2
- package/dist/orm/compile/relation-count.d.ts.map +1 -1
- package/dist/orm/corpus.d.ts.map +1 -1
- package/dist/orm/dialect/index.d.ts +32 -1
- package/dist/orm/dialect/index.d.ts.map +1 -1
- package/dist/orm/dialect/postgres.d.ts +14 -0
- package/dist/orm/dialect/postgres.d.ts.map +1 -1
- package/dist/orm/dialect/sqlite.d.ts +31 -0
- package/dist/orm/dialect/sqlite.d.ts.map +1 -1
- package/dist/orm/index.js +3 -3
- package/dist/orm/index.js.map +5 -5
- package/dist/orm/policy.d.ts.map +1 -1
- package/dist/orm/relation-filters.d.ts +24 -0
- package/dist/orm/relation-filters.d.ts.map +1 -1
- package/dist/orm/types.d.ts +129 -40
- package/dist/orm/types.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +2 -2
- package/dist/services/email/drivers/ResendDriver.d.ts.map +1 -1
- package/dist/services/file-storage/drivers/S3Driver.d.ts +24 -1
- package/dist/services/file-storage/drivers/S3Driver.d.ts.map +1 -1
- package/dist/services/image-optimization/drivers/SharpDriver.d.ts.map +1 -1
- package/dist/services/index.js +9 -18
- package/dist/services/index.js.map +5 -99
- package/dist/services/rate-limiter/drivers/RedisRateLimiterDriver.d.ts.map +1 -1
- package/dist/services/redis/RedisManager.d.ts +19 -2
- package/dist/services/redis/RedisManager.d.ts.map +1 -1
- package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
- package/dist/support/index.js +2 -2
- package/dist/support/index.js.map +1 -1
- package/dist/support/sharp.d.ts +21 -0
- package/dist/support/sharp.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-07t0dmdg.js +0 -4
- package/dist/chunk-113khwbw.js +0 -5
- package/dist/chunk-1snh7yc4.js +0 -4
- package/dist/chunk-2pt6kyn9.js +0 -5
- package/dist/chunk-4qkzdyj7.js +0 -4
- package/dist/chunk-6rhebm18.js +0 -5
- package/dist/chunk-br8ten26.js +0 -4
- package/dist/chunk-c0wcsmpj.js +0 -4
- package/dist/chunk-dxw8k6f1.js +0 -5
- package/dist/chunk-efsk1wy0.js +0 -5
- package/dist/chunk-f13f68c0.js +0 -5
- package/dist/chunk-hk067634.js +0 -4
- package/dist/chunk-hrrmxreg.js +0 -4
- package/dist/chunk-jb2nst6v.js +0 -4
- package/dist/chunk-jdgvdddd.js +0 -5
- package/dist/chunk-k8endm5j.js +0 -9
- package/dist/chunk-p8fm3tjy.js +0 -6
- package/dist/chunk-r9z5rrk0.js +0 -4
- package/dist/chunk-s6e7cvek.js +0 -4
- package/dist/chunk-tpyhhdq5.js +0 -81
- package/dist/chunk-zckj6bs6.js +0 -9
- package/dist/chunk-zckj6bs6.js.map +0 -12
- /package/dist/{chunk-3bw1jk21.js.map → chunk-62723jyy.js.map} +0 -0
package/dist/orm/index.js.map
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"import type { SqlDialect } from \"../dialect\";\nimport { MalformedRelationError } from \"../errors\";\nimport type { ModelSchema, RelationSchema } from \"../schema\";\nimport { relatedSchema, resolveLink } from \"./plan-relations\";\n\n/**\n * The three pieces every correlated subquery over a relation needs, for both\n * kinds of relation.\n *\n * Three call sites now build one: `exists` for a relation filter, `count(*)` for\n * `_count`, and a scalar for an `orderBy`. Each had its own copy of \"resolve the\n * link, quote the two key columns, write the correlation\" — and each refused\n * implicit many-to-many separately, with its own message, because the m-n shape\n * needs a *second* table in the subquery and none of them had anywhere to put\n * it.\n *\n * That is what this exists for. The join table is a difference in the subquery's\n * `from` clause and nowhere else, so hoisting the `from` and the correlation out\n * of the three callers makes m-n a property of one function rather than a\n * capability each caller has to grow.\n *\n * Direct foreign key:\n *\n * from \"Account\" as \"_r0\" where \"_r0\".\"userId\" = \"User\".\"id\"\n *\n * Implicit many-to-many:\n *\n * from \"Tag\" as \"_r0\"\n * join \"_PostToTag\" as \"_r0j\" on \"_r0j\".\"B\" = \"_r0\".\"id\"\n * where \"_r0j\".\"A\" = \"Post\".\"id\"\n *\n * The child is aliased in both cases, even when nothing is ambiguous — a\n * self-relation puts the same table on both sides and the subquery's own `from`\n * would shadow the outer one, so the correlation would compare a row to itself.\n * Aliasing conditionally would put the dangerous case on the rarely-taken branch.\n */\n\nexport interface Correlated {\n /** The related model's schema, resolved through the registry. */\n child: ModelSchema;\n /** Everything after `from `, including the join table when there is one. */\n source: string;\n /** The predicate tying the subquery to the outer row. */\n correlation: string;\n /** Prefix for the child's own columns — `\"_r0\".`. */\n qualifier: string;\n}\n\nexport function correlate(\n parent: ModelSchema,\n relation: RelationSchema,\n dialect: SqlDialect,\n /** Distinct per nesting level or per term; the caller owns uniqueness. */\n alias: string,\n /** How the outer row is named: the parent's table, or an enclosing alias. */\n parentQualifier: string,\n /**\n * The caller's operation, so a refused link names where it came from.\n * Required for the same reason `resolveLink`'s is — see the note there.\n */\n operation: string,\n): Correlated {\n const child = relatedSchema(parent, relation);\n // Throws for a self-referential implicit m-n, where the artifact cannot say\n // which join column is which end. That refusal is the planner's and predates\n // this; it is reached here rather than duplicated.\n const link = resolveLink(parent, child, relation, operation);\n\n const quoted = dialect.quoteIdent(alias);\n const qualifier = `${quoted}.`;\n\n /**\n * One equality per joined field, `and`ed.\n *\n * This is the whole of the composite-relation change for three of the four\n * correlated surfaces — a relation filter, a `_count` and an `orderBy` all\n * build their subquery here — which is the payoff for hoisting the\n * correlation into one function rather than leaving three copies of it.\n */\n const correlation = link.parentFields\n .map((parentField, index) => {\n const childKey = `${qualifier}${dialect.quoteIdent(\n column(child, relation, link.childFields[index]),\n )}`;\n const parentKey = `${parentQualifier}${dialect.quoteIdent(\n column(parent, relation, parentField),\n )}`;\n return `${childKey} = ${parentKey}`;\n })\n .join(\" and \");\n\n if (!link.join) {\n return {\n child,\n source: `${dialect.quoteIdent(child.table)} as ${quoted}`,\n correlation,\n qualifier,\n };\n }\n\n // A join table always has exactly two columns, so the m-n branch below stays\n // single-field by construction rather than by assumption.\n const childKey = `${qualifier}${dialect.quoteIdent(\n column(child, relation, link.childFields[0]),\n )}`;\n const parentKey = `${parentQualifier}${dialect.quoteIdent(\n column(parent, relation, link.parentFields[0]),\n )}`;\n\n // The join table gets the child's alias with a `j`, so two nested m-n filters\n // cannot collide any more than their children can.\n const joinAlias = dialect.quoteIdent(`${alias}j`);\n\n return {\n child,\n source:\n `${dialect.quoteIdent(child.table)} as ${quoted} ` +\n `join ${dialect.quoteIdent(link.join.table)} as ${joinAlias} ` +\n `on ${joinAlias}.${dialect.quoteIdent(link.join.childColumn)} = ${childKey}`,\n correlation: `${joinAlias}.${dialect.quoteIdent(link.join.parentColumn)} = ${parentKey}`,\n qualifier,\n };\n}\n\nfunction column(\n schema: ModelSchema,\n relation: RelationSchema,\n name: string,\n): string {\n const field = schema.fields[name];\n if (!field) {\n throw new MalformedRelationError(\n schema.name,\n relation.name,\n `it joins on '${name}', which is not a field on ${schema.name}.`,\n );\n }\n return field.column;\n}\n",
|
|
6
6
|
"import { UnsupportedQueryError } from \"../errors\";\nimport type { ModelSchema } from \"../schema\";\n\n/**\n * Where a refusal came from: the caller's model and operation, and the argument\n * path inside them.\n *\n * A triple rather than a string, because the string was doing three jobs and\n * getting two of them wrong. Nested callers passed\n * `` `${operation}.${relation.name}.${key}` `` as the *operation*, so a\n * `User.update` with a bad nested key reported\n * `(Account.update.accounts.disconnect)` — the child's model, and an operation\n * that is not one of the thirteen. `UnsupportedQueryError` documents those\n * fields as structured and inspectable; an application branching on\n * `error.operation` got something that can never match.\n *\n * Same defect #79 made `resolveLink`'s `operation` required for, and #85 was\n * filed about, one layer down. See #108.\n */\nexport interface RefusalOrigin {\n /** The model whose arguments these are — the *caller's*, not the child's. */\n model: string;\n /** The operation the caller wrote. */\n operation: string;\n /** The argument path, e.g. `data.accounts.disconnect.where`. */\n argument: string;\n}\n\n/**\n * Which declared unique key a `where` names — the `@id`, a single-field\n * `@unique`, or a composite `@@unique` in Prisma's compound form\n * (`{ username_provider: { username, provider } }`).\n *\n * Shared by every operation Prisma types with a `WhereUniqueInput`: the four\n * `findUnique*` reads, and — from iteration 4 — `update`, `delete` and\n * `upsert`. Writes need the *identity* of the matched key rather than just a\n * yes, because `upsert` compiles it into an `on conflict (...)` target, so this\n * returns the group instead of asserting.\n *\n * It runs once per argument *shape*, in the compiler, never per call. The\n * alternative is a `delete` that silently removes the first of several matches.\n *\n * Note this checks that a unique key is *present*, not that nothing else is:\n * since Prisma 5 a `WhereUniqueInput` may carry extra non-unique filters\n * alongside the key, and they narrow further rather than breaking uniqueness.\n */\nexport function matchUniqueKey(\n schema: ModelSchema,\n where: unknown,\n op: RefusalOrigin,\n): string[] {\n const candidates = uniqueKeys(schema);\n\n if (typeof where !== \"object\" || where === null || Array.isArray(where)) {\n throw missingUnique(schema, op, candidates);\n }\n\n const keys = Object.keys(where as Record<string, unknown>).filter(\n (key) => (where as Record<string, unknown>)[key] !== undefined,\n );\n\n for (const candidate of candidates) {\n if (candidate.length === 1 && keys.includes(candidate[0])) return candidate;\n // Prisma's compound form: one key named after the fields joined by `_`.\n if (candidate.length > 1 && keys.includes(candidate.join(\"_\"))) {\n return candidate;\n }\n }\n\n throw missingUnique(schema, op, candidates);\n}\n\nexport function assertUniqueWhere(\n schema: ModelSchema,\n where: unknown,\n op: string,\n): void {\n matchUniqueKey(schema, where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n}\n\nexport function uniqueKeys(schema: ModelSchema): string[][] {\n const keys: string[][] = [];\n if (schema.primaryKey.length > 0) keys.push(schema.primaryKey);\n for (const group of schema.uniques) keys.push(group);\n return keys;\n}\n\nfunction missingUnique(\n schema: ModelSchema,\n op: RefusalOrigin,\n candidates: string[][],\n): UnsupportedQueryError {\n const shown = candidates\n // A compound key is shown in Prisma's own spelling — `tenantId_code` — so\n // the name in the message is the one the caller has to type.\n .map((group) => (group.length === 1 ? group[0] : group.join(\"_\")))\n .join(\", \");\n\n // The *child* is named in the message, because it is whose keys these are —\n // that half was always the useful one. What moves is which model and\n // operation the structured fields report.\n const nested = op.argument.startsWith(\"data.\");\n const instead = nested\n ? `Name it by one of those, or reach it through the ${schema.name} model ` +\n `directly.`\n : `Use ${op.operation === \"delete\" || op.operation === \"update\" ? `${op.operation}Many` : \"findFirst\"} ` +\n `to query on anything else.`;\n\n return new UnsupportedQueryError(\n op.argument,\n op.model,\n op.operation,\n `${schema.name} needs a unique field here. It declares: ${shown}. ${instead}`,\n );\n}\n",
|
|
7
7
|
"import type { SqlDialect } from \"../dialect\";\nimport { jsonNullKind } from \"../json-null\";\nimport type { FieldSchema } from \"../schema\";\nimport { type Binder, type Fragment, param } from \"./fragment\";\n\n/**\n * Binds a field's value, letting the dialect add a cast to the placeholder.\n *\n * Only `Json` on Postgres needs one today, and the reason is the whole of #209.\n * Bun serialises a JS value bound to a `jsonb` parameter, so an object arrives\n * correctly and a bare number arrives as `integer` and is rejected. Serialising\n * first does not help on its own — the string is then serialised again and the\n * column ends up holding the jsonb *string* `\"42\"`, which is the silent\n * mis-store the refusal existed to prevent. Measured against Postgres 16:\n *\n * values ($1) 42 integer vs jsonb\n * values ($1::jsonb) \"42\" jsonb_typeof -> string\n * values (to_jsonb($1)) {a:1} could not determine polymorphic type\n * values ($1::text::jsonb) \"42\" jsonb_typeof -> number\n *\n * The last is the only form that carries all six shapes, so it is the one the\n * dialect asks for.\n *\n * **A site that does not use this keeps today's behaviour**, which is the point\n * of putting the serialisation here rather than in `encode`. Moving it into\n * `encode` would serialise at every binding site whether or not that site\n * emitted the cast — and a site that serialises without casting is exactly the\n * mis-store above, arrived at silently. Here, a binding site nobody converted\n * still binds raw: objects work, a bare number is still refused, and the\n * failure stays loud.\n */\nexport function fieldParam(\n field: FieldSchema,\n dialect: SqlDialect,\n binder: Binder,\n): Fragment {\n const cast = dialect.castParameter(field);\n if (!cast) return param(binder);\n\n return param((args, context) => {\n const value = binder(args, context);\n // `null` stays SQL NULL rather than becoming the JSON value `null`:\n // `JSON.stringify(null)` is `\"null\"`, and `'null'::jsonb` is a jsonb null,\n // which is a different thing from an absent value and would diverge from\n // Prisma on every nullable Json column.\n if (value === null || value === undefined) return null;\n\n // Prisma's sentinels, which serialise to `{}` if left to `JSON.stringify`.\n // `'null'::text::jsonb` is the JSON value; a bound `null` is SQL NULL.\n const kind = jsonNullKind(value);\n if (kind === \"db\") return null;\n if (kind === \"json\") return \"null\";\n // `AnyNull` is a question rather than a value — see `json-null.ts`. Every\n // path that could carry one has already answered it: the filter compiles it\n // to `is null or = 'null'`, and the write refuses it where the schema and\n // operation are in scope to say so. Reaching here means one of those was\n // missed, and the alternative to throwing is the `{}` mis-store of #259\n // arrived at a second way. Not an `InvalidArgumentError`: this reports an\n // ORM bug, not a caller's.\n if (kind === \"any\") {\n throw new Error(\n \"gemi ORM bug: Prisma.AnyNull reached the parameter binder. It is a \" +\n \"filter operand only, and both the filter and write paths are \" +\n \"supposed to have handled it before this point.\",\n );\n }\n\n return JSON.stringify(value);\n }, cast);\n}\n",
|
|
8
|
-
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownFieldError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport {\n isOperatorForm,\n relationFilterOperators,\n} from \"../relation-filters\";\nimport type { FieldSchema, ModelSchema, RelationSchema } from \"../schema\";\nimport { type Correlated, correlate } from \"./correlate\";\nimport { uniqueKeys } from \"./unique\";\nimport {\n type Binder,\n type Fragment,\n concat,\n joinFragments,\n param,\n sql,\n} from \"./fragment\";\nimport { JSON_NULL, type JsonNullKind, jsonNullKind } from \"../json-null\";\nimport { fieldParam } from \"./cast\";\n\n/**\n * `where` -> a boolean expression, recursively.\n *\n * The shape here is the thing every later iteration extends, so it is worth\n * stating: this is a recursive function over the argument tree returning\n * `Fragment`s, with binders carrying paths into that tree. It is never string\n * concatenation with a parameter counter in an outer scope, and it never\n * branches on the dialect's *name* — where the dialects genuinely differ in\n * structure (`in`, `like`), the work is delegated to the dialect interface.\n *\n * Semantics are Prisma's, verified by running Prisma against SQLite and reading\n * the SQL it emits rather than by reasoning about the docs:\n *\n * | Prisma | SQL |\n * | --- | --- |\n * | `{ f: null }` | `f is null` |\n * | `{ f: { equals: null }}`| `f is null` |\n * | `{ f: { not: null } }` | `f is not null` |\n * | `{ f: { not: v } }` | `f <> ?` |\n * | `{ f: { in: [] } }` | `false` |\n * | `{ AND: [] }` | `true` |\n * | `{ OR: [] }` | `false` |\n * | `{ NOT: { a, b } }` | `not (a = ? and b = ?)` |\n *\n * Returns `null` when the object contributes no predicate at all, so the caller\n * can omit the clause rather than emit `where true`.\n */\nexport function compileWhere(\n schema: ModelSchema,\n where: unknown,\n context: WhereContext,\n /**\n * Re-locates this same object inside the argument tree at bind time.\n * Compilation reads the object it was handed; binding has to find it again in\n * whatever the caller passes. Explicit rather than assuming `args.where`, so\n * the nested `where`s inside an `include` tree can reuse this unchanged.\n */\n locate: (args: any) => any,\n): Fragment | null {\n if (where === undefined || where === null) return null;\n\n if (typeof where !== \"object\" || Array.isArray(where)) {\n throw new InvalidArgumentError(\n \"where\",\n schema.name,\n context.operation,\n \"Expected an object.\",\n );\n }\n\n const predicates: Fragment[] = [];\n\n // Sorted, not insertion-ordered: the plan cache canonicalises key order when\n // it builds the cache key, so two argument objects that differ only in key\n // order share one entry — and must therefore compile to the same SQL text.\n for (const key of Object.keys(where as Record<string, unknown>).sort()) {\n const value = (where as Record<string, unknown>)[key];\n // Prisma treats an explicit `undefined` as \"not provided\". Matching that\n // matters: it is how conditional filters are written in application code.\n if (value === undefined) continue;\n\n const at = (args: any) => locate(args)?.[key];\n\n if (key === \"AND\" || key === \"OR\") {\n const combined = compileGroup(schema, value, context, at, key);\n if (combined) predicates.push(combined);\n continue;\n }\n\n if (key === COMPOSITE_IN) {\n predicates.push(compileCompositeIn(schema, value, context, at));\n continue;\n }\n\n if (key === \"NOT\") {\n const negated = compileGroup(schema, value, context, at, \"AND\");\n // `NOT` of nothing is vacuously true, so it contributes no predicate.\n // The operand is always parenthesised: `not a = ?` happens to parse the\n // way we mean on both dialects, but relying on `not` binding looser than\n // every comparison it might wrap is not a property worth depending on.\n if (negated) predicates.push(concat(sql(\"not \"), parenthesize(negated)));\n continue;\n }\n\n if (key in schema.relations) {\n const filter = compileRelationFilter(\n schema,\n schema.relations[key],\n value,\n context,\n at,\n );\n if (filter) predicates.push(filter);\n continue;\n }\n\n const field = schema.fields[key];\n if (!field) {\n // Prisma exposes a composite `@@unique([a, b])` as one key named `a_b`,\n // holding an object of its members. It is the only `where` key that is\n // not a field, a relation or a combinator, and `findUnique` on a model\n // like the template's `SocialAccount` cannot be expressed without it.\n const compound = compileCompoundKey(schema, key, value, context, at);\n if (compound) {\n predicates.push(compound);\n continue;\n }\n throw new UnknownFieldError(key, schema.name, Object.keys(schema.fields));\n }\n\n predicates.push(compileFieldFilter(schema, field, value, context, at));\n }\n\n if (predicates.length === 0) return null;\n if (predicates.length === 1) return predicates[0];\n return group(predicates, \" and \");\n}\n\nexport interface WhereContext {\n dialect: SqlDialect;\n operation: string;\n /**\n * Prefix for every column this `where` names — `\"User\".` — set only when the\n * statement has more than one table in scope.\n *\n * That happens when a relation strategy folds children in with a lateral join\n * (iteration 9): the subquery introduces a second scope and a bare `\"id\"`\n * becomes ambiguous. It is the table's own name rather than an invented alias,\n * because Postgres lets a lateral subquery reference the outer table by name.\n *\n * Absent otherwise, and absence is the common case — so a query with no folded\n * relation emits byte-identical SQL to what it did before this existed, which\n * is what keeps invariant 2 and every compiler text assertion untouched.\n */\n qualifier?: string;\n /**\n * How many relation-filter subqueries enclose this one. Zero at the root.\n *\n * It exists only to name the child alias — `_r0`, `_r1` — and the aliases only\n * have to be distinct from the ones *enclosing* them, not from their siblings:\n * each `exists (…)` is its own scope, so two relation filters at the same level\n * cannot see each other. Depth is therefore sufficient, and it keeps the SQL\n * text a pure function of the argument shape, which a counter threaded through\n * compilation would not be.\n */\n relationDepth?: number;\n}\n\n/**\n * `where: { accounts: { some: { … } } }` -> `exists (select 1 from \"Account\" …)`.\n *\n * A correlated subquery rather than a join, for the reason iteration 3 gave when\n * it deferred this: a join against a to-many multiplies the parent rows and then\n * needs a `distinct` to put them back, which changes the row count of the outer\n * query for a filter that should only ever *remove* rows. `exists` cannot.\n *\n * ### The child is always aliased\n *\n * Even when the tables differ and nothing is ambiguous. A self-relation —\n * `Employee.manager` — puts the same table on both sides, and there the\n * subquery's own `from` shadows the outer one, so the correlation silently\n * compares a row to itself. Aliasing conditionally would mean the dangerous case\n * is the one that takes the rarely-exercised branch; aliasing always means the\n * self-relation is compiled by the same code as everything else.\n *\n * The outer side is qualified by table name (or by the enclosing alias, when this\n * filter is itself nested), which is what makes the correlation refer outwards.\n * That needs nothing from the outer statement — `from \"User\"` puts `\"User\"` in\n * scope as a qualifier whether or not any other column uses one — so a query with\n * a relation filter leaves the rest of its SQL byte-identical.\n */\nfunction compileRelationFilter(\n schema: ModelSchema,\n relation: RelationSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment | null {\n // Shape before environment: `readOperators` only reads the relation's own\n // `kind`, so a malformed filter is reported as one even when the registry is\n // empty. The other order let a missing `register` call mask a plain typo.\n const operators = relationFilterOperators(relation.kind);\n const requested = readOperators(schema, relation, value, operators, context);\n\n const depth = context.relationDepth ?? 0;\n\n const dialect = context.dialect;\n // At depth 0 the outer scope is the queried table; deeper, it is the alias of\n // the subquery this one sits inside. `context.qualifier` already holds the\n // right answer in both cases when something set it — the lateral strategy does\n // at the root — so it wins, and the table name is the fallback.\n const parentQualifier =\n context.qualifier ?? `${dialect.quoteIdent(schema.table)}.`;\n\n const source = correlate(\n schema,\n relation,\n dialect,\n `_r${depth}`,\n parentQualifier,\n context.operation,\n );\n const child = source.child;\n const correlation = sql(source.correlation);\n\n const inner: WhereContext = {\n ...context,\n qualifier: source.qualifier,\n relationDepth: depth + 1,\n };\n\n const parts: Fragment[] = [];\n\n for (const operator of operators) {\n if (!(operator in requested)) continue;\n\n const argument = requested[operator];\n const at = (args: any) => requested.direct ? locate(args) : locate(args)?.[operator];\n\n // `is: null` / a bare `null` on a to-one: \"there is no related row\". Prisma\n // spells the opposite `isNot: null`.\n if (argument === null) {\n parts.push(existence(source, correlation, null, operator === \"is\"));\n continue;\n }\n\n const condition = compileWhere(child, argument, inner, at);\n\n if (operator === \"every\") {\n // `every` is \"no child fails it\", not \"some child passes it\" — the two\n // differ on a parent with no children at all, which `every` matches and\n // `some` does not. An empty `every: {}` therefore constrains nothing.\n if (!condition) continue;\n parts.push(\n existence(\n source,\n correlation,\n concat(sql(\"not \"), parenthesize(condition)),\n true,\n ),\n );\n continue;\n }\n\n const negate = operator === \"none\" || operator === \"isNot\";\n parts.push(existence(source, correlation, condition, negate));\n }\n\n if (parts.length === 0) return null;\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** `exists (select 1 from \"Child\" as \"_r0\" where <correlation> [and <rest>])`. */\nfunction existence(\n source: Correlated,\n correlation: Fragment,\n rest: Fragment | null,\n negated: boolean,\n): Fragment {\n const parts: Fragment[] = [\n sql(`${negated ? \"not \" : \"\"}exists (select 1 from ${source.source} where `),\n correlation,\n ];\n\n if (rest) parts.push(sql(\" and \"), rest);\n parts.push(sql(\")\"));\n\n return concat(...parts);\n}\n\n/**\n * Which operators a relation filter asked for, with Prisma's shorthands folded\n * into the same shape.\n *\n * A to-one accepts the filter directly — `where: { user: { email } }` means\n * `is` — and accepts `null` for \"no related row\". A to-many does not: Prisma\n * requires one of `some` / `every` / `none`, because a bare object there has no\n * unambiguous reading.\n */\nfunction readOperators(\n schema: ModelSchema,\n relation: RelationSchema,\n value: unknown,\n operators: readonly string[],\n context: WhereContext,\n): Record<string, unknown> & { direct?: boolean } {\n const path = `where.${relation.name}`;\n const many = relation.kind === \"many\";\n\n if (value === null) {\n if (many) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n context.operation,\n `${relation.name} is a to-many relation, so null is not a filter for ` +\n `it. Use { none: {} } for \"has no related rows\".`,\n );\n }\n return { is: null, direct: true };\n }\n\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new InvalidArgumentError(\n path,\n schema.name,\n context.operation,\n many\n ? `Expected an object holding ${operators.join(\", \")}.`\n : `Expected an object, or null.`,\n );\n }\n\n if (isOperatorForm(value as object, operators)) {\n return value as Record<string, unknown>;\n }\n\n if (many) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n context.operation,\n `Expected one of ${operators.join(\", \")}. A to-many relation has no ` +\n `single reading of a bare filter — { some: … } and { every: … } mean ` +\n `different things.`,\n );\n }\n\n // The to-one shorthand. Marked so the binder path stays on the object the\n // caller wrote rather than descending into an `is` key that is not there.\n return { is: value, direct: true };\n}\n\n\n/**\n * `{ username_provider: { username, provider } }` -> `username = ? and\n * provider = ?`.\n *\n * Returns `null` when `key` names no declared composite unique, so the caller\n * can fall through to reporting an unknown field.\n */\nfunction compileCompoundKey(\n schema: ModelSchema,\n key: string,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment | null {\n // `uniqueKeys`, not `schema.uniques` — the primary key is a unique key, and a\n // compound `@@id` lives only in `schema.primaryKey`. Searching `uniques`\n // alone made the two halves of this disagree: `matchUniqueKey` accepted\n // `tenantId_code` (it asks `uniqueKeys`, which includes the primary key), so\n // the operation compiled, and then this returned `null` and the caller\n // reported an unknown field. Both spellings failed and each error pointed at\n // the other.\n //\n // Invisible until now because the template's only compound key is\n // `SocialAccount`'s `@@unique([username, provider])`. A compound `@@id` — a\n // join table, or any tenant-scoped `@@id([tenantId, id])` — was unreachable\n // by key at all.\n const members = uniqueKeys(schema).find(\n (group) => group.length > 1 && group.join(\"_\") === key,\n );\n if (!members) return null;\n\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new InvalidArgumentError(\n `where.${key}`,\n schema.name,\n context.operation,\n `Expected an object holding ${members.join(\" and \")}.`,\n );\n }\n\n const supplied = value as Record<string, unknown>;\n const parts: Fragment[] = [];\n\n for (const member of members) {\n // Every member is required: a composite key is only unique as a whole, so\n // a partial one would quietly become a non-unique lookup.\n if (supplied[member] === undefined) {\n throw new UnsupportedQueryError(\n `where.${key}`,\n schema.name,\n context.operation,\n `Missing '${member}'. A composite key needs all of ${members.join(\", \")}.`,\n );\n }\n\n parts.push(\n compileFieldFilter(\n schema,\n schema.fields[member],\n supplied[member],\n context,\n (args) => locate(args)?.[member],\n ),\n );\n }\n\n return parts.length === 1 ? parts[0] : group(parts, \" and \");\n}\n\n/** `AND` / `OR`, accepting Prisma's array form and its single-object form. */\nfunction compileGroup(\n schema: ModelSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n joiner: \"AND\" | \"OR\",\n): Fragment | null {\n const parts: Fragment[] = [];\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const compiled = compileWhere(\n schema,\n value[i],\n context,\n (args) => locate(args)?.[i],\n );\n if (compiled) parts.push(compiled);\n }\n } else {\n const compiled = compileWhere(schema, value, context, locate);\n if (compiled) parts.push(compiled);\n }\n\n if (parts.length === 0) {\n // Prisma: an empty `AND` is vacuously true and contributes nothing; an empty\n // `OR` matches nothing at all. Verified against the SQL Prisma emits — it\n // produces `1=1` and `1=0` respectively.\n return joiner === \"AND\" ? null : FALSE;\n }\n if (parts.length === 1) return parts[0];\n return group(parts, joiner === \"AND\" ? \" and \" : \" or \");\n}\n\n/**\n * Boolean literals rather than `1=0` (which is what Prisma emits): they carry\n * the same meaning on both dialects and keep the invariant that no digit ever\n * reaches the SQL text outside an identifier, which is an actual test.\n */\nconst FALSE: Fragment = sql(\"false\");\n\nfunction group(parts: Fragment[], separator: string): Fragment {\n return concat(sql(\"(\"), joinFragments(parts, separator), sql(\")\"));\n}\n\n/**\n * Wraps a fragment in parentheses unless it already is one. `group` is the only\n * thing that emits a leading `(`, and it always closes it, so the check is\n * exact — and it keeps `not (...)` from stuttering into `not ((...))`.\n */\nfunction parenthesize(fragment: Fragment): Fragment {\n return fragment.text.startsWith(\"(\") ? fragment : group([fragment], \"\");\n}\n\n/** Every operator Prisma allows on a scalar field. */\nconst OPERATORS = new Set([\n \"equals\",\n \"not\",\n \"in\",\n \"notIn\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"mode\",\n]);\n\nconst COMPARISONS: Record<string, string> = {\n lt: \"<\",\n lte: \"<=\",\n gt: \">\",\n gte: \">=\",\n};\n\n/**\n * The internal key a batched relation loader uses to match a **tuple** of\n * columns against a list of tuples — the composite-relation counterpart of\n * `in`, and the reason #97 exists.\n *\n * **`$`-prefixed because a Prisma field cannot be.** Field names match\n * `[A-Za-z][A-Za-z0-9_]*`, so this cannot collide with a column, which a\n * `__`-prefixed name could not promise.\n *\n * It is not part of the public argument grammar, and that is **enforced rather\n * than asserted**. This branch sits above the field lookup, so a caller writing\n * the key by hand used to be honoured — not an injection, since the fields are\n * resolved against the schema and the values are bound, but an undocumented\n * input surface with none of the operand validation its neighbours have. The\n * operand now has to carry {@link PLANNER}, a module-private `Symbol` an\n * application cannot reach, exactly as `markPreScoped` and `markOrmAuthored`\n * gate their own claims.\n */\nexport const COMPOSITE_IN = \"$compositeIn\";\n\n/**\n * Marks a composite-`in` operand as the planner's own.\n *\n * A `Symbol`, so it is invisible to `Object.entries` — which means it does not\n * reach the plan key, where it would be noise, and cannot be written in JSON by\n * a caller who has seen the key name in a stack trace.\n */\nconst PLANNER = Symbol(\"gemi.orm.compositeInFromPlanner\");\n\n/** `{ fields: [\"a\", \"b\"], values: [[1, \"x\"], [2, \"y\"]] }`. */\ninterface CompositeInOperand {\n fields: string[];\n values: unknown[][];\n}\n\nexport function plannerCompositeIn(\n fields: string[],\n values: unknown[][],\n): Record<string, unknown> {\n return { [PLANNER]: true, fields, values };\n}\n\n/**\n * `(a, b) in (…)`, in whichever form the dialect can bind.\n *\n * Only ever reached on a dialect whose `canBindCompositeIn` said yes for these\n * column types — `plan-relations.ts` asks before it emits this key, and keeps\n * the portable `OR` of `AND`s otherwise. So there is no fallback here: arriving\n * with a dialect that cannot express it is a bug in that decision, not a shape\n * to degrade.\n */\nfunction compileCompositeIn(\n schema: ModelSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n const fields = assertCompositeInOperand(schema, operand, context);\n\n const resolved = fields.map((name) => {\n const field = schema.fields[name];\n if (!field) {\n throw new UnknownFieldError(name, schema.name, Object.keys(schema.fields));\n }\n return field;\n });\n\n const columns = resolved.map(\n (field) =>\n `${context.qualifier ?? \"\"}${dialect.quoteIdent(field.column)}`,\n );\n\n return dialect.compositeIn(\n columns,\n resolved.map((field) => field.type),\n (args) => (locate(args) as CompositeInOperand).values,\n );\n}\n\n/**\n * The operand's shape, checked at **plan** time.\n *\n * Every other operand in this file is validated here rather than left to fail\n * at bind time — `assertCreateManyOperand`'s note says why: a refusal that\n * arrives later has to unwind work that should never have started. This one\n * was the exception, and it showed: `{ $compositeIn: null }` raised a raw\n * `TypeError` from a destructure, and `{ fields: [\"id\"] }` with no `values` at\n * all compiled clean and deferred its failure to bind time.\n */\nfunction assertCompositeInOperand(\n schema: ModelSchema,\n operand: unknown,\n context: WhereContext,\n): string[] {\n /**\n * A caller's key gets the **unknown-key treatment**, which is what the\n * original comment promised and what every other key it is not a field for\n * already gets. `UnsupportedQueryError` would render \"does not support\n * '$compositeIn' *yet*\" — a promise about a key that is deliberately not in\n * the grammar and never will be. That word has now been corrected once each\n * on #82 and #88; this is the third time it has been raised, which is enough\n * to stop treating it as a wording nit and use the error that is simply\n * accurate: `$compositeIn` is not a field on this model.\n */\n const notAField = (): never => {\n throw new UnknownFieldError(\n COMPOSITE_IN,\n schema.name,\n Object.keys(schema.fields),\n );\n };\n\n if (typeof operand !== \"object\" || operand === null || Array.isArray(operand)) {\n return notAField();\n }\n\n if ((operand as Record<symbol, unknown>)[PLANNER] !== true) {\n return notAField();\n }\n\n /**\n * Below here the operand *is* the planner's, so a bad shape is this ORM's bug\n * rather than a caller's — and `UnsupportedQueryError` is the right class for\n * it: an internal invariant that does not hold is genuinely something the\n * ORM does not support, and \"yet\" is the honest word for a state it should\n * not be in.\n */\n const refuse = (detail: string): never => {\n throw new UnsupportedQueryError(\n COMPOSITE_IN,\n schema.name,\n context.operation,\n detail,\n );\n };\n\n const { fields, values } = operand as CompositeInOperand;\n\n // Below here the operand *is* the planner's, so these are its bugs rather\n // than a caller's — worth catching at compile time for the same reason, and\n // worth a different sentence because the audience is different.\n if (!Array.isArray(fields) || fields.length === 0) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with no fields.`);\n }\n if (!fields.every((name) => typeof name === \"string\")) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with a non-string field.`);\n }\n if (!Array.isArray(values)) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with no values.`);\n }\n if (!values.every((tuple) => Array.isArray(tuple) && tuple.length === fields.length)) {\n return refuse(\n `the planner built a '${COMPOSITE_IN}' whose tuples do not all have ` +\n `${fields.length} value(s).`,\n );\n }\n\n return fields;\n}\n\n/**\n * The filters Prisma applies to a **scalar list** — `tags String[]`.\n *\n * A different set on a different left-hand side, which is why it is a branch\n * rather than four more entries in `OPERATORS`: `contains` on a `String` asks\n * about a substring, and on a `String[]` there is no such question — the one\n * Prisma spells is `has`. Sharing the table would have made every scalar\n * operator compile against an array column and answer something.\n *\n * A tuple for the same reason {@link JSON_FILTER_NAMES} is one: `ListFilter` in\n * `../types` said in a comment that it mirrors this list, and a comment is not\n * something the compiler checks.\n */\nconst LIST_FILTER_NAMES = [\n \"equals\",\n \"has\",\n \"hasEvery\",\n \"hasSome\",\n \"isEmpty\",\n] as const;\n\n/** One of {@link LIST_FILTER_NAMES}. `ListFilter` maps over this. */\nexport type ListFilterName = (typeof LIST_FILTER_NAMES)[number];\n\nconst LIST_FILTERS: ReadonlySet<string> = new Set(LIST_FILTER_NAMES);\n\n/**\n * `where: { tags: { has: \"urgent\" } }`.\n *\n * **The dialect answers first**, before any operand is looked at, because on\n * SQLite the answer is \"not this column, on this database, ever\" rather than\n * \"not this filter\". That refusal used to live in the generator (#300) and\n * could not stay there: the generated artifact is dialect-agnostic on purpose,\n * so refusing a scalar list at generation refused it for Postgres too — and\n * refused the *whole artifact*, since one `String[]` anywhere threw before any\n * model was emitted.\n */\nfunction compileListFilter(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n assertListDialect(schema, field, `where.${field.name}`, context.operation, dialect);\n\n // **A bare array is not shorthand for `equals` here**, and that is the one\n // place a list deliberately reads differently from a scalar — where\n // `{ email: \"a@b\" }` means `equals`, `{ tags: [\"a\"] }` means nothing.\n //\n // Not a judgement call: Prisma refuses it, measured against a generated 6.19\n // client — *\"Argument `strings`: Invalid value provided. Expected\n // StringNullableListFilter, provided (String).\"* Accepting it would make gemi\n // a silent superset of Prisma on the one dialect where a differential test\n // could otherwise check every other answer, which is the trade this project\n // has declined every time it has come up.\n //\n // The asymmetry that surprises: the same bare array *is* accepted as a\n // **write** value — `data: { tags: [\"a\"] }` is valid Prisma and valid here.\n // Filter and value are different positions and Prisma treats them\n // differently; so does this.\n if (Array.isArray(value)) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, and a bare array is not a filter on ` +\n `one — Prisma rejects it here too. Say which comparison you mean: ` +\n `{ ${field.name}: { equals: [...] } } for the whole list, or ` +\n `{ ${field.name}: { hasEvery: [...] } } for \"contains all of these\". ` +\n `A bare array *is* accepted as a value in \\`data\\`.`,\n );\n }\n\n if (!isFilterObject(value)) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list. Expected an object holding ` +\n `${[...LIST_FILTERS].sort().join(\", \")}; received ` +\n `${value === null ? \"null\" : typeof value}.`,\n );\n }\n\n const filter = value as Record<string, unknown>;\n const parts: Fragment[] = [];\n\n // Sorted, for the reason `compileWhere` sorts: the plan cache canonicalises\n // key order, so two objects differing only in it must compile alike.\n for (const key of Object.keys(filter).sort()) {\n const operand = filter[key];\n if (operand === undefined) continue;\n\n if (!LIST_FILTERS.has(key)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, and a list filter takes ` +\n `${[...LIST_FILTERS].sort().join(\", \")}. The scalar operators — ` +\n `${[...OPERATORS].sort().join(\", \")} — apply to a single value and ` +\n `Prisma does not offer them here.`,\n );\n }\n\n const at = (args: any) => locate(args)?.[key];\n parts.push(listComparison(schema, field, column, key, operand, context, at));\n }\n\n // An empty filter object constrains nothing, which is what the scalar path\n // does with `{}` too.\n if (parts.length === 0) return sql(\"true\");\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** One list filter key. */\nfunction listComparison(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n key: string,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n if (key === \"equals\") {\n return listEquals(schema, field, column, operand, context, locate);\n }\n\n if (key === \"isEmpty\") {\n if (typeof operand !== \"boolean\") {\n throw new InvalidArgumentError(\n `where.${field.name}.isEmpty`,\n schema.name,\n context.operation,\n `Expected true or false, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n return dialect.listIsEmpty(column, operand);\n }\n\n if (key === \"has\") {\n // One **element**, so it binds as one — through the element's own field, so\n // a `Json[]` gets #209's `::text::jsonb` on the placeholder and the\n // serialisation that has to travel with it. Binding it as a list instead\n // would produce an array literal on the left of `= any(...)`, and binding\n // it with no cast answers *false* on a `Json[]` rather than raising.\n const element = elementOf(field);\n return dialect.listHas(\n column,\n fieldParam(element, dialect, encoded(element, dialect, locate)),\n );\n }\n\n // `hasEvery` / `hasSome` — both take a list, and both have a defined answer\n // for an empty one: `@> '{}'` is true of every row and `&& '{}'` of none,\n // which is what Prisma means by \"contains all of nothing\" and \"shares one\n // element with nothing\".\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected an array, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n\n const values = fieldParam(field, dialect, encoded(field, dialect, locate));\n return key === \"hasEvery\"\n ? dialect.listHasEvery(column, values)\n : dialect.listHasSome(column, values);\n}\n\n/** `\"tags\" = $1` — whole-list equality, which is order-sensitive in SQL. */\nfunction listEquals(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n // A list column cannot be null in Prisma — `String[]?` is refused at schema\n // validation — but `equals: null` is still in the generated filter type, and\n // a column written by something other than Prisma can hold NULL. Same\n // reading as everywhere else: `= NULL` matches nothing, `is null` is meant.\n if (operand === null) return sql(`${column} is null`);\n\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.equals`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, so it compares against an array. ` +\n `Received ${typeof operand}. For \"is this element present\", use ` +\n `{ ${field.name}: { has: … } }.`,\n );\n }\n\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, encoded(field, dialect, locate)),\n );\n}\n\n/**\n * The same field, seen as **one element of itself**.\n *\n * `type` already carries the element type — that is the whole reason `isList`\n * is a flag beside it rather than a `ScalarType` constructor — so dropping the\n * flag is the entire conversion, and `encode`, `decode` and `castParameter` all\n * read it as the scalar they were written for.\n */\nfunction elementOf(field: FieldSchema): FieldSchema {\n return { ...field, isList: false };\n}\n\n/**\n * Refuses a scalar list on a dialect that has no array type, naming it.\n *\n * Shared by the read and write paths, and it says more than \"unsupported\"\n * because the reader's likeliest next question is whether they did something\n * wrong. They did not: Prisma refuses the *column* on SQLite, so a schema that\n * declares one was generated against Postgres and this process is pointed at a\n * database that could not hold it either.\n */\nexport function assertListDialect(\n schema: ModelSchema,\n field: FieldSchema,\n argument: string,\n operation: string,\n dialect: SqlDialect,\n): void {\n if (dialect.listFilters.size > 0) return;\n\n throw new UnsupportedQueryError(\n argument,\n schema.name,\n operation,\n `'${field.name}' is a scalar list, and ${dialect.name} has no array type ` +\n `to hold one. Prisma refuses the column itself on ${dialect.name} — ` +\n `\"the current connector does not support lists of primitive types\" — so ` +\n `this is a difference between the databases rather than a gap in the ` +\n `ORM. The generated artifact is dialect-agnostic, which is why this ` +\n `surfaces here rather than at \\`prisma generate\\`: the schema was ` +\n `generated against Postgres and DATABASE_URL names a ${dialect.name} ` +\n `database, which has no '${field.column}' column either. It works on ` +\n `postgres.`,\n );\n}\n\n/**\n * The filters Prisma applies to a value extracted from a JSON path.\n *\n * **A tuple, and the caller-facing type is a mapped type over it.**\n * `JsonPathFilter` in `../types` used to spell these ten names a second time,\n * in a file that neither imports this one nor is imported by it, so the two\n * lists could differ with no compile error, no failing test and no diff a\n * reviewer would flag. That is the mechanism behind #326, #333, #336 and #337 —\n * the compiler accepting something the type refuses to describe — and #336 was\n * the worst of them because the undescribed filter was silently absorbed as an\n * `equals` shorthand rather than refused.\n *\n * Deriving the type from this list makes the drift a compile error at the call\n * sites instead of something the next reviewer has to notice.\n */\nconst JSON_FILTER_NAMES = [\n \"equals\",\n \"not\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n] as const;\n\n/** One of {@link JSON_FILTER_NAMES}. `JsonPathFilter` maps over this. */\nexport type JsonFilterName = (typeof JSON_FILTER_NAMES)[number];\n\nconst JSON_FILTERS: ReadonlySet<string> = new Set(JSON_FILTER_NAMES);\n\n/**\n * `where: { metadata: { path: …, equals: … } }`.\n *\n * **Two dialects, two path grammars, and that is Prisma's split rather than\n * this ORM's.** Measured on both through a generated client: Postgres takes\n * `path: [\"a\", \"b\"]` and refuses a string; SQLite takes `path: \"$.a.b\"` and\n * refuses an array. So the argument is dialect-specific before it arrives here,\n * and `jsonPathSyntax` is what lets the check say which form *this* database\n * wants instead of failing inside the driver.\n *\n * **The path is bound, never interpolated.** This is the one place a caller's\n * value decides part of an expression's meaning, which makes it the obvious\n * place to break invariant 2 by accident. Neither dialect needs it in the text:\n * Postgres's `#>` takes a `text[]` parameter and SQLite's `json_extract` takes\n * a string, so the whole feature fits inside the existing rule.\n *\n * The operator set is the dialect's too. Prisma refuses `array_contains` and\n * the numeric comparisons on SQLite — *\"Unknown argument\"* — so refusing them\n * here is matching it, not falling short: implementing them would make gemi\n * answer a query the oracle cannot, which is precisely where a differential\n * test stops being able to check anything.\n */\nfunction compileJsonFilter(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n filter: Record<string, unknown>,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n if (field.type !== \"Json\") {\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A 'path' filter reads inside a JSON document, and '${field.name}' is ` +\n `a ${field.type} column.`,\n );\n }\n\n assertPathShape(schema, field, filter.path, context);\n\n const path: Binder = (args) => locate(args)?.path;\n // **An `undefined` operand is an absent one**, which is the rule the scalar\n // operator loop already follows (`if (operand === undefined …) continue`) and\n // the rule the dispatch above follows for `path` itself\n // (`filter.path !== undefined`). Building `applied` from `Object.keys` alone\n // made this branch the one place that broke it: a filter assembled from a\n // form or a query string carries `equals: undefined` for the field nobody\n // filled in, and that compiled to `= NULL` — a predicate no row can satisfy —\n // where the same query with the key simply omitted got the bare-path refusal\n // below.\n //\n // Prisma answers both spellings identically. Measured on a generated 6.19.2\n // client against Postgres: `{ path: [\"a\"], equals: undefined }` and\n // `{ path: [\"a\"] }` both raise P2019 *\"A JSON path cannot be set without a\n // scalar filter.\"*, and `{ path: [\"a\"], equals: 1, gt: undefined }` compiles\n // the `equals` alone.\n //\n // **This is also what makes the plan cache safe here**, which is the stronger\n // reason and the one a reader will otherwise have to re-derive.\n // `canonicalShape` drops `undefined` members, so the two spellings were\n // already *one* cache key — measured:\n //\n // planKey(postgres, \"User\", \"findMany\", { where: { metadata: { path: [\"a\"] } } })\n // planKey(postgres, \"User\", \"findMany\", { where: { metadata: { path: [\"a\"], equals: undefined } } })\n // both -> postgres:batched:User:findMany:{where:{metadata:{path:[string]}}}\n //\n // while they compiled to two different things, a refusal and a `= NULL` plan.\n // Whichever compiled first decided for the other, so a bare `path` arriving\n // second was served the never-true plan instead of the refusal it raises\n // cold. Both throw now, so there is nothing left for the shared key to\n // collide on.\n const applied = Object.keys(filter)\n .filter((key) => key !== \"path\" && filter[key] !== undefined)\n .sort();\n\n if (applied.length === 0) {\n // Prisma: \"A JSON path cannot be set without a scalar filter.\" Reproduced\n // because the alternative is an extraction with nothing to compare it to,\n // which compiles to a value in a predicate position on one dialect and to\n // an error on the other.\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A 'path' needs a filter beside it — ${[...JSON_FILTERS].sort().join(\", \")}. ` +\n `Prisma refuses a bare path too.`,\n );\n }\n\n const parts: Fragment[] = [];\n\n for (const key of applied) {\n if (!JSON_FILTERS.has(key)) {\n throw new UnsupportedQueryError(\n `${field.name}.${key}`,\n schema.name,\n context.operation,\n `A JSON path filter takes ${[...JSON_FILTERS].sort().join(\", \")}.`,\n );\n }\n\n if (!dialect.jsonFilters.has(key)) {\n throw new UnsupportedQueryError(\n `${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${key}' on a JSON path is not available on ${dialect.name}. Prisma ` +\n `refuses it here too, so this is a difference between the databases ` +\n `rather than a gap in the ORM. It works on postgres.`,\n );\n }\n\n const operand = filter[key];\n\n // **The sentinels have to be refused here, and only here.**\n //\n // `compileFieldFilter` refuses a bare sentinel above this branch, and\n // refuses `AnyNull` under a non-`equals`/`not` operator in the scalar key\n // loop below it. A `path` filter sits between the two and reaches neither,\n // so before this check a sentinel inside a JSON filter went straight to the\n // binder: Postgres compared against the literal text `Prisma.DbNull` and\n // SQLite bound the sentinel object. Zero rows, no error — the failure class\n // #259 and #266 exist to close, arrived at from the one direction nothing\n // was watching.\n //\n // Refused rather than mapped. The scalar path *can* answer these because it\n // compiles them against the column, where SQL NULL and the JSON value\n // `null` are distinguishable. An extracted value has already lost that\n // distinction — `#>>` yields NULL both for an absent key and for a JSON\n // null — so answering here would mean picking one meaning and being\n // silently wrong about the other.\n const sentinel = jsonNullKind(operand);\n if (sentinel) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `${sentinelName(sentinel)} is not a filter on an extracted JSON ` +\n `value: the extraction yields NULL for an absent key and for a JSON ` +\n `null alike, so the distinction the sentinel exists to make is ` +\n `already gone. Filter the column itself — ` +\n `{ ${field.name}: { equals: ${sentinelName(sentinel)} } } — or test ` +\n `the path against the value you mean.`,\n );\n }\n\n // The same shape one level down: `{ path: …, equals: { not: DbNull } }`.\n if (carriesAnyNull(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Prisma.AnyNull cannot be reached through a JSON path, for the same ` +\n `reason the other two cannot: the extracted value does not ` +\n `distinguish an absent key from a JSON null.`,\n );\n }\n\n assertJsonOperand(key, operand, schema, field, context);\n\n parts.push(\n jsonComparison(key, column, path, field, dialect, (args) =>\n locate(args)?.[key],\n ),\n );\n }\n\n return parts.length === 1\n ? parts[0]\n : group(parts, \" and \");\n}\n\n/**\n * What each JSON filter will accept as its operand.\n *\n * Three defects, all of them the shape the scalar path is already careful about\n * and all silent:\n *\n * - **The string filters had no non-string guard.** Their scalar siblings\n * refuse one, with a comment explaining that `String(null)` makes the\n * pattern `%null%` — \"a query that runs and returns the wrong rows\".\n * `string_contains: null` compiled to `like NULL`, which matches nothing\n * and raises nothing; `string_contains: 5` compiled to `%5%`. Prisma raises\n * for both.\n *\n * - **`equals` / `not` accepted a non-scalar.** On Postgres the comparison\n * binds `String(raw)` because `#>>` yields text, so `equals: { b: 1 }` bound\n * the string `\"[object Object]\"` and matched nothing.\n *\n * - **`null` fell between the two.** The string branch refuses a non-string\n * and the object branch tests `operand !== null` first, so `equals: null`\n * reached the binder and compiled to `= NULL` — see the guard below.\n *\n * The last two are a **refusal rather than an implementation**, deliberately.\n * Prisma does accept an object or an array there, and answering it properly\n * means the `#>` + `::jsonb` form `array_contains` already uses — which is\n * Postgres-only, so implementing it would give SQLite either a second wrong\n * answer or a silent divergence. Refusing names the limitation on both\n * dialects, which is what this file does everywhere else it cannot answer.\n * `array_contains` is exempt from the object rule because containment is\n * precisely the operator that takes a document — but not from the `null` one,\n * because a bound SQL NULL is not a JSON `null` on either side of `@>`.\n */\nfunction assertJsonOperand(\n key: string,\n operand: unknown,\n schema: ModelSchema,\n field: FieldSchema,\n context: WhereContext,\n): void {\n const stringly =\n key === \"string_contains\" ||\n key === \"string_starts_with\" ||\n key === \"string_ends_with\";\n\n if (stringly && typeof operand !== \"string\") {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected a string, received ${\n operand === null ? \"null\" : typeof operand\n }. Prisma raises here too — without this the pattern becomes ` +\n `'%${String(operand)}%', which runs and returns the wrong rows.`,\n );\n }\n\n // **`null` is refused under every path operator, and it is a refusal rather\n // than a gap.**\n //\n // Measured on a generated 6.19.2 client against Postgres, with query-event\n // logging and the rows read back: Prisma extracts with `#>` and compares as\n // `jsonb`, so `{ path: [\"a\"], equals: null }` asks for the JSON value `null`\n // and returns the rows that hold one — the same SQL and the same rows as\n // `equals: Prisma.JsonNull`. gemi extracts with `#>>`, which yields *text*,\n // and NULL for an absent key and for a JSON null alike. That collapse is\n // exactly why the sentinels are refused a few lines above, and it leaves this\n // operand nothing to mean.\n //\n // Left alone it reached the binder and compiled to `(\"metadata\" #>> $1) = $2`\n // bound to NULL — `= NULL` is NULL rather than true on both dialects, so the\n // query ran, raised nothing, and matched no row where Prisma matched some.\n // The `string_contains` guard above names that failure in this file's own\n // words, \"runs and returns the wrong rows\"; only the arithmetic differs.\n //\n // `array_contains` is included rather than exempt, **and its mechanism is a\n // different one**. It takes the `#>` form, so the text collapse above does\n // not apply to it — but `jsonArrayContains` binds the operand raw, so `null`\n // arrives as SQL NULL and `x @> NULL` is NULL too. Prisma binds it as the\n // JSON value and runs a real containment test. The message below branches for\n // that reason: telling an `array_contains` caller about `#>>` would name a\n // mechanism this operator does not have, and pointing them at\n // `{ equals: Prisma.JsonNull }` would answer a containment question with an\n // equality on the column.\n //\n // Answering any of them properly means the `#> … ::jsonb` form on Postgres\n // and `json_type` on SQLite, which is a second implementation of the same\n // operator per dialect rather than a guard — the same reason the object\n // operand below is refused instead of compiled.\n if (operand === null) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n key === \"array_contains\"\n ? `null cannot be tested for containment through a JSON path: the ` +\n `operand binds as SQL NULL rather than as the JSON value, and ` +\n `'x @> NULL' is NULL rather than true — the query would run and ` +\n `match nothing. Prisma binds it as the JSON value and runs a real ` +\n `containment test; gemi does not yet. A null *inside* the document ` +\n `is an ordinary value and still compiles: ` +\n `{ ${field.name}: { path: […], array_contains: [null] } }.`\n : `null cannot be compared through a JSON path: the extraction yields ` +\n `SQL NULL for an absent key and for a JSON null alike, and the ` +\n `comparison against it is NULL rather than true — the query would ` +\n `run and match nothing. Prisma reads it as the JSON value null and ` +\n `does answer it; gemi does not yet. Filter the column itself — ` +\n `{ ${field.name}: { equals: Prisma.JsonNull } } — or test the path ` +\n `against the value you mean.`,\n );\n }\n\n if (key === \"array_contains\" || stringly) return;\n\n // `equals`, `not`, and the four numeric comparisons all compare an extracted\n // scalar against one bound value. No `!== null` here: `typeof null` is\n // `\"object\"`, and the guard above has already refused it with its own reason.\n if (typeof operand === \"object\") {\n throw new UnsupportedQueryError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${key}' on a JSON path compares the extracted value as a scalar, so ` +\n `an object or array operand cannot be expressed — it would bind as ` +\n `'${String(operand)}' and match nothing. Prisma accepts one here; ` +\n `gemi does not yet. Use array_contains for containment, or narrow the ` +\n `path until it names a scalar.`,\n );\n }\n}\n\n/** The comparison for one JSON filter key. */\nfunction jsonComparison(\n key: string,\n column: string,\n path: Binder,\n field: FieldSchema,\n dialect: SqlDialect,\n value: Binder,\n): Fragment {\n if (key === \"array_contains\") {\n return dialect.jsonArrayContains(column, path, value);\n }\n\n // The string filters compare *text*, so they need the text-returning\n // extraction; everything else compares the value.\n const stringly =\n key === \"string_contains\" ||\n key === \"string_starts_with\" ||\n key === \"string_ends_with\";\n\n const extracted = dialect.jsonExtract(column, path, true);\n\n if (stringly) {\n const wrap =\n key === \"string_contains\"\n ? (text: string) => `%${text}%`\n : key === \"string_starts_with\"\n ? (text: string) => `${text}%`\n : (text: string) => `%${text}`;\n\n return concat(\n sql(\"(\"),\n extracted,\n sql(\") like \"),\n param((args, context) => {\n const raw = value(args, context);\n return raw === null || raw === undefined ? null : wrap(String(raw));\n }),\n );\n }\n\n const operator =\n key === \"equals\" ? \"=\" : key === \"not\" ? \"<>\" : COMPARISONS[key];\n\n // `#>>` and `json_extract` both yield text, so a numeric comparison has to\n // compare numbers rather than their spellings — otherwise \"10\" < \"9\". The\n // cast is structural, never a value.\n const numeric = key !== \"equals\" && key !== \"not\";\n const lhs = numeric\n ? concat(sql(\"cast((\"), extracted, sql(\") as real)\"))\n : concat(sql(\"(\"), extracted, sql(\")\"));\n\n return concat(\n lhs,\n sql(` ${operator} `),\n param((args, context) => {\n const raw = value(args, context);\n if (raw === null || raw === undefined) return null;\n if (numeric) return Number(raw);\n // Text on Postgres, native on SQLite — see `jsonComparesAsText`. The\n // wrong one returns no rows on one dialect and raises on the other.\n return dialect.jsonComparesAsText ? String(raw) : raw;\n }),\n );\n}\n\n/** The path is a string on SQLite and an array of string keys on Postgres. */\nfunction assertPathShape(\n schema: ModelSchema,\n field: FieldSchema,\n path: unknown,\n context: WhereContext,\n): void {\n const { dialect } = context;\n const wanted = dialect.jsonPathSyntax === \"array\" ? \"array\" : \"jsonpath\";\n const got = Array.isArray(path) ? \"array\" : typeof path === \"string\" ? \"jsonpath\" : \"other\";\n\n // **The empty path is refused on both dialects, and it is not the same\n // mistake as a wrong shape.** `[]` on Postgres extracts the whole document —\n // `[].every` is vacuously true, so it used to pass this check — and `\"\"` on\n // SQLite raises inside `json_extract` at execution time. Neither is a path,\n // and a caller who wrote one meant to write something. Refused with its own\n // sentence rather than the grammar message below, which would tell them to\n // use the form they already used.\n const empty =\n (Array.isArray(path) && path.length === 0) || path === \"\";\n if (empty) {\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A JSON path cannot be empty. ${\n dialect.jsonPathSyntax === \"array\"\n ? `On ${dialect.name} an empty array selects the whole document, ` +\n `which is a filter on the column rather than on a path — write ` +\n `{ ${field.name}: { equals: … } } if that is what you meant.`\n : `On ${dialect.name} an empty string raises inside json_extract.`\n }`,\n );\n }\n\n if (got === wanted) {\n if (wanted !== \"array\") return;\n\n // **Every segment is a string, and the number that used to be allowed here\n // was a superset of the oracle.** Prisma's generated `path` on Postgres is\n // `string[]`, and its client refuses a number at run time as well as at\n // compile time — measured on 6.19.2: `path: [\"items\", 0]` answers\n // *\"Argument `path`: Invalid value provided. Expected String, provided\n // Int.\"* before any SQL is built.\n //\n // Refused rather than kept, because this file already states the rule that\n // decides it: answering a query the oracle cannot express is \"precisely\n // where a differential test stops being able to check anything\"\n // (`compileJsonFilter`'s docblock, on the SQLite operators). Nothing is\n // lost — `[\"items\", \"0\"]` reaches the same array element, since `#>` takes\n // a `text[]` and the segment arrives as text either way. Measured: both\n // spellings bind `[\"items\", \"0\"]` and return the same row on Prisma, and\n // gemi's binder already stringifies through the `text[]` cast.\n //\n // Its own sentence rather than the grammar message below, which would tell\n // a caller who wrote an array to write an array.\n const offending = (path as unknown[]).findIndex(\n (part) => typeof part !== \"string\",\n );\n if (offending === -1) return;\n\n // `a ${typeof part}` alone reads as \"a undefined\" / \"a object\" for every\n // segment but the number, so the description is spelled out. And the array\n // index sentence is advice for one mistake in particular — a caller who\n // wrote `null` did not write an index — so it is gated on the number\n // rather than emitted for everything.\n const part = (path as unknown[])[offending];\n const described =\n part === null\n ? \"null\"\n : part === undefined\n ? \"undefined\"\n : Array.isArray(part)\n ? \"an array\"\n : typeof part === \"object\"\n ? \"an object\"\n : `a ${typeof part}`;\n\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A JSON path is an array of strings, and path[${offending}] is ` +\n `${described}. ` +\n (typeof part === \"number\"\n ? `An array index is a key too — write [\"items\", \"0\"] rather than ` +\n `[\"items\", 0]; it reaches the same element, because ` +\n `${dialect.name} takes the path as text. Prisma's path is ` +\n `string[] and its client refuses a number here too.`\n : `Prisma's path is string[] too.`),\n );\n }\n\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n dialect.jsonPathSyntax === \"array\"\n ? `On ${dialect.name} a JSON path is an array of keys — [\"a\", \"b\"] — ` +\n `not a JSONPath string. Prisma splits them the same way, and refuses ` +\n `the other form on each database.`\n : `On ${dialect.name} a JSON path is a JSONPath string — \"$.a.b\" — not ` +\n `an array of keys. Prisma splits them the same way, and refuses the ` +\n `other form on each database.`,\n );\n}\n\nfunction compileFieldFilter(\n schema: ModelSchema,\n field: FieldSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n const column = `${context.qualifier ?? \"\"}${dialect.quoteIdent(field.column)}`;\n\n // A bare `Prisma.DbNull` is **not** shorthand for `equals`, and Prisma refuses\n // it: `where: { settings: Prisma.DbNull }` is an invalid invocation there,\n // spelled out under the offending key. Both sentinels are objects with no\n // enumerable properties, so left alone they read as an operator map holding\n // no operators — which compiles to `true`, and answered \"every row\" to a\n // question about the null ones.\n //\n // Refused rather than interpreted, because guessing which of the two nulls a\n // caller meant is the whole thing the sentinels exist to stop, and because\n // matching Prisma means matching its refusals as well as its results.\n const sentinel = jsonNullKind(value);\n if (sentinel) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `${sentinelName(sentinel)} is not a filter on ` +\n `its own — Prisma rejects it here too. Write it as an explicit ` +\n `comparison: { ${field.name}: { equals: ${sentinelName(sentinel)} } }.`,\n );\n }\n\n // A scalar list takes a different operator set on a different left-hand side,\n // so the whole operand belongs to that branch — the same shape the `path`\n // check below has for a JSON document. Placed *above* the bare-value\n // shorthand because on a list the bare form is an **array**, which\n // `isFilterObject` reports as a value and would send to the scalar `equals`\n // with no dialect check and no operand validation.\n if (field.isList) {\n return compileListFilter(schema, field, column, value, context, locate);\n }\n\n // A bare value is shorthand for `equals`. A `Date` is a value, not a filter\n // object, even though `typeof` cannot tell them apart.\n if (!isFilterObject(value)) {\n return equals(column, field, value, dialect, locate);\n }\n\n const filter = value as Record<string, unknown>;\n const keys = Object.keys(filter).sort();\n\n // A `path` turns the whole operand into a JSON filter, whose operators are a\n // different set from the scalar ones and whose left-hand side is an\n // extraction rather than a column.\n if (filter.path !== undefined) {\n return compileJsonFilter(schema, field, column, filter, context, locate);\n }\n\n // Prisma-only, and only meaningful next to a string operator. Read here so it\n // does not get treated as an operator in its own right.\n const insensitive = filter.mode === \"insensitive\";\n if (filter.mode !== undefined && filter.mode !== \"default\") {\n if (!insensitive) {\n throw new InvalidArgumentError(\n `mode: ${JSON.stringify(filter.mode)}`,\n schema.name,\n context.operation,\n `Prisma takes 'default' or 'insensitive'.`,\n );\n }\n if (!dialect.supportsInsensitiveMode) {\n throw new UnsupportedQueryError(\n \"mode: \\\"insensitive\\\"\",\n schema.name,\n context.operation,\n `The ${dialect.name} dialect cannot express it — Prisma rejects it ` +\n `here too. Note SQLite's LIKE is already case-insensitive for ASCII.`,\n );\n }\n }\n\n const parts: Fragment[] = [];\n\n for (const key of keys) {\n const operand = filter[key];\n if (operand === undefined || key === \"mode\") continue;\n\n if (!OPERATORS.has(key)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `A scalar filter takes ${[...OPERATORS].sort().join(\", \")}.`,\n );\n }\n\n // `AnyNull` asks for both nulls at once, which only `equals` and `not` can\n // express. Under any other operator it has no meaning — Prisma's own\n // `JsonNullableFilter` admits it in exactly those two positions — and left\n // alone it would reach the binder, where it is an ORM bug by construction.\n // Refused here, where the field and operation are in scope to name it,\n // rather than at the backstop that would report it as ours.\n if (key !== \"equals\" && key !== \"not\" && carriesAnyNull(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Prisma.AnyNull means 'either kind of null', which only 'equals' and ` +\n `'not' can express. Write { ${field.name}: { equals: Prisma.AnyNull } }, ` +\n `or name the one you mean with Prisma.DbNull or Prisma.JsonNull.`,\n );\n }\n\n const at = (args: any) => locate(args)?.[key];\n\n switch (key) {\n case \"equals\":\n parts.push(equals(column, field, operand, dialect, at));\n break;\n\n case \"not\":\n parts.push(\n compileNot(schema, field, operand, context, at, column),\n );\n break;\n\n case \"in\":\n case \"notIn\":\n parts.push(\n inList(schema, column, field, operand, context, at, key === \"notIn\"),\n );\n break;\n\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\":\n parts.push(\n concat(\n sql(`${column} ${COMPARISONS[key]} `),\n fieldParam(field, dialect, encoded(field, dialect, at)),\n ),\n );\n break;\n\n case \"contains\":\n case \"startsWith\":\n case \"endsWith\":\n // Prisma raises \"Argument `contains` must not be null\" — verified.\n // Without this, `String(null)` makes the pattern `%null%`, which is a\n // query that runs and returns the wrong rows. The types catch the\n // static case but not a value that arrives dynamically.\n if (typeof operand !== \"string\") {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected a string, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n if (field.type !== \"String\") {\n throw new UnsupportedQueryError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${field.name}' is a ${field.type}, and ${key} only applies to strings.`,\n );\n }\n parts.push(dialect.like(column, insensitive, likePattern(key, at)));\n break;\n }\n }\n\n if (parts.length === 0) return sql(\"true\");\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** How a sentinel is spelled in a message, so an error can be pasted back as code. */\nfunction sentinelName(kind: JsonNullKind): string {\n return `Prisma.${kind === \"db\" ? \"DbNull\" : kind === \"json\" ? \"JsonNull\" : \"AnyNull\"}`;\n}\n\n/**\n * Whether an operand is `AnyNull`, or a list holding one.\n *\n * The list case is the reachable one: `in: [Prisma.AnyNull]` type-checks\n * nowhere in Prisma, but nothing stops it being written in JavaScript, and\n * `inList` would bind it as an ordinary value.\n */\nfunction carriesAnyNull(operand: unknown): boolean {\n if (jsonNullKind(operand) === \"any\") return true;\n return Array.isArray(operand) && operand.some((item) => jsonNullKind(item) === \"any\");\n}\n\n/** `not` is a whole nested filter, not just a value — `not: { in: [...] }`. */\nfunction compileNot(\n schema: ModelSchema,\n field: FieldSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n column: string,\n): Fragment {\n // `DbNull` is the sentinel spelling of the same question, so it takes the\n // same branch — see `equals`.\n if (operand === null || jsonNullKind(operand) === \"db\") {\n return sql(`${column} is not null`);\n }\n\n // `JsonNull` does not: it asks about a stored JSON *value*, so negating it is\n // a value comparison. Handled here rather than by delegating, because the\n // delegate refuses a bare sentinel — correctly, since Prisma does — and this\n // one did not arrive bare. `{ not: Prisma.JsonNull }` is a valid Prisma\n // filter and has to stay one.\n if (jsonNullKind(operand) === \"json\") {\n return concat(\n sql(\"not \"),\n parenthesize(equals(column, field, operand, context.dialect, locate)),\n );\n }\n\n // `not: AnyNull` is \"neither kind of null\", so it negates the union `equals`\n // builds. Safe to negate directly because that predicate is total — see the\n // note there — so no row falls through on NULL the way `not (col = value)`\n // would.\n if (jsonNullKind(operand) === \"any\") {\n return concat(\n sql(\"not \"),\n parenthesize(equals(column, field, operand, context.dialect, locate)),\n );\n }\n\n if (!isFilterObject(operand)) {\n return concat(\n sql(`${column} <> `),\n fieldParam(field, context.dialect, encoded(field, context.dialect, locate)),\n );\n }\n\n // `not: { in: [...] }` and the rest compile to `not (<positive form>)`.\n // Prisma emits `not in` directly, which is a different *text* but the same\n // predicate: both yield NULL — and so exclude the row — when the column is\n // NULL. The contract is equal results, not equal SQL.\n const inner = compileFieldFilter(schema, field, operand, context, locate);\n return concat(sql(\"not \"), parenthesize(inner));\n}\n\nfunction equals(\n column: string,\n field: FieldSchema,\n operand: unknown,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Fragment {\n // `= ?` with a null parameter matches nothing in SQL, where Prisma means\n // `is null`. This is the difference that would silently return wrong rows.\n //\n // `Prisma.DbNull` means the same thing on a `Json` column and arrives as a\n // sentinel object rather than as `null`, so it reached the parameter path\n // below and compiled to `= ?` — matching nothing, whatever the table held.\n // Its sibling `JsonNull` is a genuine *value* comparison and belongs there:\n // the column holds the JSON `null`, and `= 'null'` is how you find it.\n if (operand === null || jsonNullKind(operand) === \"db\") {\n return sql(`${column} is null`);\n }\n\n // `AnyNull` is the union of the other two, and the only operand here that is\n // not a single comparison. Both halves are needed: the column being SQL NULL\n // and the column holding the JSON value `null` are different rows, and this\n // is the one filter that asks for both.\n //\n // No three-valued-logic trap in the `or`. `is null` is never NULL, and when\n // the column is non-NULL the second half is a proper boolean — so the\n // predicate is total, which is what makes negating it in `compileNot` safe.\n if (jsonNullKind(operand) === \"any\") {\n return group(\n [sql(`${column} is null`), jsonNullComparison(column, field, dialect)],\n \" or \",\n );\n }\n\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, encoded(field, dialect, locate)),\n );\n}\n\n/**\n * `<column> = <the JSON value null>`, as a bound parameter.\n *\n * The literal is the compiler's, not the caller's, so there is no argument to\n * read it out of — but it stays a parameter rather than being written into the\n * text, because invariant 2 admits no exception for a value the compiler\n * happens to know. It is also what keeps the dialects' encoders as the single\n * authority on how a JSON null is spelled: `'null'` on SQLite, `'null'::text::jsonb`\n * on Postgres, decided by `fieldParam` and `castParameter` rather than here.\n */\nfunction jsonNullComparison(\n column: string,\n field: FieldSchema,\n dialect: SqlDialect,\n): Fragment {\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, () => dialect.encode(JSON_NULL, field)),\n );\n}\n\nfunction inList(\n schema: ModelSchema,\n column: string,\n field: FieldSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n negated: boolean,\n): Fragment {\n const { dialect } = context;\n\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${negated ? \"notIn\" : \"in\"}`,\n schema.name,\n context.operation,\n \"Expected an array.\",\n );\n }\n\n // `x in ()` is a syntax error, and Prisma emits a constant-false predicate\n // for it. `not in ()` is vacuously true by the same logic.\n if (operand.length === 0) return negated ? sql(\"true\") : FALSE;\n\n return dialect.inList(column, negated, operand.length, (args) => {\n const values = locate(args) as unknown[];\n return values.map((value) => dialect.encode(value, field));\n });\n}\n\n/**\n * Prisma does **not** escape `%` or `_` inside the value — verified by reading\n * the parameters it binds: `contains: \"50%_x\"` binds `\"%50%_x%\"`. So a user\n * string containing a wildcard really does act as a wildcard.\n *\n * That is a footgun, but the contract this ORM signs is differential equality\n * with Prisma, and escaping here would break it on every such query. Matching\n * Prisma and saying so is the honest option; diverging quietly is not.\n */\nfunction likePattern(\n operator: \"contains\" | \"startsWith\" | \"endsWith\",\n locate: (args: any) => any,\n): Binder {\n return (args) => {\n const value = String(locate(args));\n if (operator === \"contains\") return `%${value}%`;\n if (operator === \"startsWith\") return `${value}%`;\n return `%${value}`;\n };\n}\n\nfunction encoded(\n field: FieldSchema,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Binder {\n return (args) => dialect.encode(locate(args), field);\n}\n\n/**\n * True for `{ contains: ... }`, false for a plain value. A `Date` is a value\n * even though it is an object, and so is a `Uint8Array` for a `Bytes` column.\n */\nfunction isFilterObject(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !ArrayBuffer.isView(value)\n );\n}\n",
|
|
8
|
+
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownFieldError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport {\n isOperatorForm,\n relationFilterOperators,\n} from \"../relation-filters\";\nimport type { FieldSchema, ModelSchema, RelationSchema } from \"../schema\";\nimport { type Correlated, correlate } from \"./correlate\";\nimport { uniqueKeys } from \"./unique\";\nimport {\n type Binder,\n type Fragment,\n concat,\n joinFragments,\n param,\n sql,\n} from \"./fragment\";\nimport { JSON_NULL, type JsonNullKind, jsonNullKind } from \"../json-null\";\nimport { fieldParam } from \"./cast\";\n\n/**\n * `where` -> a boolean expression, recursively.\n *\n * The shape here is the thing every later iteration extends, so it is worth\n * stating: this is a recursive function over the argument tree returning\n * `Fragment`s, with binders carrying paths into that tree. It is never string\n * concatenation with a parameter counter in an outer scope, and it never\n * branches on the dialect's *name* — where the dialects genuinely differ in\n * structure (`in`, `like`), the work is delegated to the dialect interface.\n *\n * Semantics are Prisma's, verified by running Prisma against SQLite and reading\n * the SQL it emits rather than by reasoning about the docs:\n *\n * | Prisma | SQL |\n * | --- | --- |\n * | `{ f: null }` | `f is null` |\n * | `{ f: { equals: null }}`| `f is null` |\n * | `{ f: { not: null } }` | `f is not null` |\n * | `{ f: { not: v } }` | `f <> ?` |\n * | `{ f: { in: [] } }` | `false` |\n * | `{ AND: [] }` | `true` |\n * | `{ OR: [] }` | `false` |\n * | `{ NOT: { a, b } }` | `not (a = ? and b = ?)` |\n *\n * Returns `null` when the object contributes no predicate at all, so the caller\n * can omit the clause rather than emit `where true`.\n */\nexport function compileWhere(\n schema: ModelSchema,\n where: unknown,\n context: WhereContext,\n /**\n * Re-locates this same object inside the argument tree at bind time.\n * Compilation reads the object it was handed; binding has to find it again in\n * whatever the caller passes. Explicit rather than assuming `args.where`, so\n * the nested `where`s inside an `include` tree can reuse this unchanged.\n */\n locate: (args: any) => any,\n): Fragment | null {\n if (where === undefined || where === null) return null;\n\n if (typeof where !== \"object\" || Array.isArray(where)) {\n throw new InvalidArgumentError(\n \"where\",\n schema.name,\n context.operation,\n \"Expected an object.\",\n );\n }\n\n const predicates: Fragment[] = [];\n\n // Sorted, not insertion-ordered: the plan cache canonicalises key order when\n // it builds the cache key, so two argument objects that differ only in key\n // order share one entry — and must therefore compile to the same SQL text.\n for (const key of Object.keys(where as Record<string, unknown>).sort()) {\n const value = (where as Record<string, unknown>)[key];\n // Prisma treats an explicit `undefined` as \"not provided\". Matching that\n // matters: it is how conditional filters are written in application code.\n if (value === undefined) continue;\n\n const at = (args: any) => locate(args)?.[key];\n\n if (key === \"AND\" || key === \"OR\") {\n const combined = compileGroup(schema, value, context, at, key);\n if (combined) predicates.push(combined);\n continue;\n }\n\n if (key === COMPOSITE_IN) {\n predicates.push(compileCompositeIn(schema, value, context, at));\n continue;\n }\n\n if (key === \"NOT\") {\n const negated = compileGroup(schema, value, context, at, \"AND\");\n // `NOT` of nothing is vacuously true, so it contributes no predicate.\n // The operand is always parenthesised: `not a = ?` happens to parse the\n // way we mean on both dialects, but relying on `not` binding looser than\n // every comparison it might wrap is not a property worth depending on.\n if (negated) predicates.push(concat(sql(\"not \"), parenthesize(negated)));\n continue;\n }\n\n if (key in schema.relations) {\n const filter = compileRelationFilter(\n schema,\n schema.relations[key],\n value,\n context,\n at,\n );\n if (filter) predicates.push(filter);\n continue;\n }\n\n const field = schema.fields[key];\n if (!field) {\n // Prisma exposes a composite `@@unique([a, b])` as one key named `a_b`,\n // holding an object of its members. It is the only `where` key that is\n // not a field, a relation or a combinator, and `findUnique` on a model\n // like the template's `SocialAccount` cannot be expressed without it.\n const compound = compileCompoundKey(schema, key, value, context, at);\n if (compound) {\n predicates.push(compound);\n continue;\n }\n throw new UnknownFieldError(key, schema.name, Object.keys(schema.fields));\n }\n\n predicates.push(compileFieldFilter(schema, field, value, context, at));\n }\n\n if (predicates.length === 0) return null;\n if (predicates.length === 1) return predicates[0];\n return group(predicates, \" and \");\n}\n\nexport interface WhereContext {\n dialect: SqlDialect;\n operation: string;\n /**\n * Prefix for every column this `where` names — `\"User\".` — set only when the\n * statement has more than one table in scope.\n *\n * That happens when a relation strategy folds children in with a lateral join\n * (iteration 9): the subquery introduces a second scope and a bare `\"id\"`\n * becomes ambiguous. It is the table's own name rather than an invented alias,\n * because Postgres lets a lateral subquery reference the outer table by name.\n *\n * Absent otherwise, and absence is the common case — so a query with no folded\n * relation emits byte-identical SQL to what it did before this existed, which\n * is what keeps invariant 2 and every compiler text assertion untouched.\n */\n qualifier?: string;\n /**\n * How many relation-filter subqueries enclose this one. Zero at the root.\n *\n * It exists only to name the child alias — `_r0`, `_r1` — and the aliases only\n * have to be distinct from the ones *enclosing* them, not from their siblings:\n * each `exists (…)` is its own scope, so two relation filters at the same level\n * cannot see each other. Depth is therefore sufficient, and it keeps the SQL\n * text a pure function of the argument shape, which a counter threaded through\n * compilation would not be.\n */\n relationDepth?: number;\n}\n\n/**\n * `where: { accounts: { some: { … } } }` -> `exists (select 1 from \"Account\" …)`.\n *\n * A correlated subquery rather than a join, for the reason iteration 3 gave when\n * it deferred this: a join against a to-many multiplies the parent rows and then\n * needs a `distinct` to put them back, which changes the row count of the outer\n * query for a filter that should only ever *remove* rows. `exists` cannot.\n *\n * ### The child is always aliased\n *\n * Even when the tables differ and nothing is ambiguous. A self-relation —\n * `Employee.manager` — puts the same table on both sides, and there the\n * subquery's own `from` shadows the outer one, so the correlation silently\n * compares a row to itself. Aliasing conditionally would mean the dangerous case\n * is the one that takes the rarely-exercised branch; aliasing always means the\n * self-relation is compiled by the same code as everything else.\n *\n * The outer side is qualified by table name (or by the enclosing alias, when this\n * filter is itself nested), which is what makes the correlation refer outwards.\n * That needs nothing from the outer statement — `from \"User\"` puts `\"User\"` in\n * scope as a qualifier whether or not any other column uses one — so a query with\n * a relation filter leaves the rest of its SQL byte-identical.\n */\nfunction compileRelationFilter(\n schema: ModelSchema,\n relation: RelationSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment | null {\n // Shape before environment: `readOperators` only reads the relation's own\n // `kind`, so a malformed filter is reported as one even when the registry is\n // empty. The other order let a missing `register` call mask a plain typo.\n const operators = relationFilterOperators(relation.kind);\n const requested = readOperators(schema, relation, value, operators, context);\n\n const depth = context.relationDepth ?? 0;\n\n const dialect = context.dialect;\n // At depth 0 the outer scope is the queried table; deeper, it is the alias of\n // the subquery this one sits inside. `context.qualifier` already holds the\n // right answer in both cases when something set it — the lateral strategy does\n // at the root — so it wins, and the table name is the fallback.\n const parentQualifier =\n context.qualifier ?? `${dialect.quoteIdent(schema.table)}.`;\n\n const source = correlate(\n schema,\n relation,\n dialect,\n `_r${depth}`,\n parentQualifier,\n context.operation,\n );\n const child = source.child;\n const correlation = sql(source.correlation);\n\n const inner: WhereContext = {\n ...context,\n qualifier: source.qualifier,\n relationDepth: depth + 1,\n };\n\n const parts: Fragment[] = [];\n\n for (const operator of operators) {\n if (!(operator in requested)) continue;\n\n const argument = requested[operator];\n const at = (args: any) => requested.direct ? locate(args) : locate(args)?.[operator];\n\n // `is: null` / a bare `null` on a to-one: \"there is no related row\". Prisma\n // spells the opposite `isNot: null`.\n if (argument === null) {\n parts.push(existence(source, correlation, null, operator === \"is\"));\n continue;\n }\n\n const condition = compileWhere(child, argument, inner, at);\n\n if (operator === \"every\") {\n // `every` is \"no child fails it\", not \"some child passes it\" — the two\n // differ on a parent with no children at all, which `every` matches and\n // `some` does not. An empty `every: {}` therefore constrains nothing.\n if (!condition) continue;\n parts.push(\n existence(\n source,\n correlation,\n concat(sql(\"not \"), parenthesize(condition)),\n true,\n ),\n );\n continue;\n }\n\n const negate = operator === \"none\" || operator === \"isNot\";\n parts.push(existence(source, correlation, condition, negate));\n }\n\n if (parts.length === 0) return null;\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** `exists (select 1 from \"Child\" as \"_r0\" where <correlation> [and <rest>])`. */\nfunction existence(\n source: Correlated,\n correlation: Fragment,\n rest: Fragment | null,\n negated: boolean,\n): Fragment {\n const parts: Fragment[] = [\n sql(`${negated ? \"not \" : \"\"}exists (select 1 from ${source.source} where `),\n correlation,\n ];\n\n if (rest) parts.push(sql(\" and \"), rest);\n parts.push(sql(\")\"));\n\n return concat(...parts);\n}\n\n/**\n * Which operators a relation filter asked for, with Prisma's shorthands folded\n * into the same shape.\n *\n * A to-one accepts the filter directly — `where: { user: { email } }` means\n * `is` — and accepts `null` for \"no related row\". A to-many does not: Prisma\n * requires one of `some` / `every` / `none`, because a bare object there has no\n * unambiguous reading.\n */\nfunction readOperators(\n schema: ModelSchema,\n relation: RelationSchema,\n value: unknown,\n operators: readonly string[],\n context: WhereContext,\n): Record<string, unknown> & { direct?: boolean } {\n const path = `where.${relation.name}`;\n const many = relation.kind === \"many\";\n\n if (value === null) {\n if (many) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n context.operation,\n `${relation.name} is a to-many relation, so null is not a filter for ` +\n `it. Use { none: {} } for \"has no related rows\".`,\n );\n }\n return { is: null, direct: true };\n }\n\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new InvalidArgumentError(\n path,\n schema.name,\n context.operation,\n many\n ? `Expected an object holding ${operators.join(\", \")}.`\n : `Expected an object, or null.`,\n );\n }\n\n if (isOperatorForm(value as object, operators)) {\n return value as Record<string, unknown>;\n }\n\n if (many) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n context.operation,\n `Expected one of ${operators.join(\", \")}. A to-many relation has no ` +\n `single reading of a bare filter — { some: … } and { every: … } mean ` +\n `different things.`,\n );\n }\n\n // The to-one shorthand. Marked so the binder path stays on the object the\n // caller wrote rather than descending into an `is` key that is not there.\n return { is: value, direct: true };\n}\n\n\n/**\n * `{ username_provider: { username, provider } }` -> `username = ? and\n * provider = ?`.\n *\n * Returns `null` when `key` names no declared composite unique, so the caller\n * can fall through to reporting an unknown field.\n */\nfunction compileCompoundKey(\n schema: ModelSchema,\n key: string,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment | null {\n // `uniqueKeys`, not `schema.uniques` — the primary key is a unique key, and a\n // compound `@@id` lives only in `schema.primaryKey`. Searching `uniques`\n // alone made the two halves of this disagree: `matchUniqueKey` accepted\n // `tenantId_code` (it asks `uniqueKeys`, which includes the primary key), so\n // the operation compiled, and then this returned `null` and the caller\n // reported an unknown field. Both spellings failed and each error pointed at\n // the other.\n //\n // Invisible until now because the template's only compound key is\n // `SocialAccount`'s `@@unique([username, provider])`. A compound `@@id` — a\n // join table, or any tenant-scoped `@@id([tenantId, id])` — was unreachable\n // by key at all.\n const members = uniqueKeys(schema).find(\n (group) => group.length > 1 && group.join(\"_\") === key,\n );\n if (!members) return null;\n\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new InvalidArgumentError(\n `where.${key}`,\n schema.name,\n context.operation,\n `Expected an object holding ${members.join(\" and \")}.`,\n );\n }\n\n const supplied = value as Record<string, unknown>;\n const parts: Fragment[] = [];\n\n for (const member of members) {\n // Every member is required: a composite key is only unique as a whole, so\n // a partial one would quietly become a non-unique lookup.\n if (supplied[member] === undefined) {\n throw new UnsupportedQueryError(\n `where.${key}`,\n schema.name,\n context.operation,\n `Missing '${member}'. A composite key needs all of ${members.join(\", \")}.`,\n );\n }\n\n parts.push(\n compileFieldFilter(\n schema,\n schema.fields[member],\n supplied[member],\n context,\n (args) => locate(args)?.[member],\n ),\n );\n }\n\n return parts.length === 1 ? parts[0] : group(parts, \" and \");\n}\n\n/** `AND` / `OR`, accepting Prisma's array form and its single-object form. */\nfunction compileGroup(\n schema: ModelSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n joiner: \"AND\" | \"OR\",\n): Fragment | null {\n const parts: Fragment[] = [];\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const compiled = compileWhere(\n schema,\n value[i],\n context,\n (args) => locate(args)?.[i],\n );\n if (compiled) parts.push(compiled);\n }\n } else {\n const compiled = compileWhere(schema, value, context, locate);\n if (compiled) parts.push(compiled);\n }\n\n if (parts.length === 0) {\n // Prisma: an empty `AND` is vacuously true and contributes nothing; an empty\n // `OR` matches nothing at all. Verified against the SQL Prisma emits — it\n // produces `1=1` and `1=0` respectively.\n return joiner === \"AND\" ? null : FALSE;\n }\n if (parts.length === 1) return parts[0];\n return group(parts, joiner === \"AND\" ? \" and \" : \" or \");\n}\n\n/**\n * Boolean literals rather than `1=0` (which is what Prisma emits): they carry\n * the same meaning on both dialects and keep the invariant that no digit ever\n * reaches the SQL text outside an identifier, which is an actual test.\n */\nconst FALSE: Fragment = sql(\"false\");\n\nfunction group(parts: Fragment[], separator: string): Fragment {\n return concat(sql(\"(\"), joinFragments(parts, separator), sql(\")\"));\n}\n\n/**\n * Wraps a fragment in parentheses unless it already is one. `group` is the only\n * thing that emits a leading `(`, and it always closes it, so the check is\n * exact — and it keeps `not (...)` from stuttering into `not ((...))`.\n */\nfunction parenthesize(fragment: Fragment): Fragment {\n return fragment.text.startsWith(\"(\") ? fragment : group([fragment], \"\");\n}\n\n/** Every operator Prisma allows on a scalar field. */\nconst OPERATORS = new Set([\n \"equals\",\n \"not\",\n \"in\",\n \"notIn\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"mode\",\n]);\n\nconst COMPARISONS: Record<string, string> = {\n lt: \"<\",\n lte: \"<=\",\n gt: \">\",\n gte: \">=\",\n};\n\n/**\n * The internal key a batched relation loader uses to match a **tuple** of\n * columns against a list of tuples — the composite-relation counterpart of\n * `in`, and the reason #97 exists.\n *\n * **`$`-prefixed because a Prisma field cannot be.** Field names match\n * `[A-Za-z][A-Za-z0-9_]*`, so this cannot collide with a column, which a\n * `__`-prefixed name could not promise.\n *\n * It is not part of the public argument grammar, and that is **enforced rather\n * than asserted**. This branch sits above the field lookup, so a caller writing\n * the key by hand used to be honoured — not an injection, since the fields are\n * resolved against the schema and the values are bound, but an undocumented\n * input surface with none of the operand validation its neighbours have. The\n * operand now has to carry {@link PLANNER}, a module-private `Symbol` an\n * application cannot reach, exactly as `markPreScoped` and `markOrmAuthored`\n * gate their own claims.\n */\nexport const COMPOSITE_IN = \"$compositeIn\";\n\n/**\n * Marks a composite-`in` operand as the planner's own.\n *\n * A `Symbol`, so it is invisible to `Object.entries` — which means it does not\n * reach the plan key, where it would be noise, and cannot be written in JSON by\n * a caller who has seen the key name in a stack trace.\n */\nconst PLANNER = Symbol(\"gemi.orm.compositeInFromPlanner\");\n\n/** `{ fields: [\"a\", \"b\"], values: [[1, \"x\"], [2, \"y\"]] }`. */\ninterface CompositeInOperand {\n fields: string[];\n values: unknown[][];\n}\n\nexport function plannerCompositeIn(\n fields: string[],\n values: unknown[][],\n): Record<string, unknown> {\n return { [PLANNER]: true, fields, values };\n}\n\n/**\n * `(a, b) in (…)`, in whichever form the dialect can bind.\n *\n * Only ever reached on a dialect whose `canBindCompositeIn` said yes for these\n * column types — `plan-relations.ts` asks before it emits this key, and keeps\n * the portable `OR` of `AND`s otherwise. So there is no fallback here: arriving\n * with a dialect that cannot express it is a bug in that decision, not a shape\n * to degrade.\n */\nfunction compileCompositeIn(\n schema: ModelSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n const fields = assertCompositeInOperand(schema, operand, context);\n\n const resolved = fields.map((name) => {\n const field = schema.fields[name];\n if (!field) {\n throw new UnknownFieldError(name, schema.name, Object.keys(schema.fields));\n }\n return field;\n });\n\n const columns = resolved.map(\n (field) =>\n `${context.qualifier ?? \"\"}${dialect.quoteIdent(field.column)}`,\n );\n\n return dialect.compositeIn(\n columns,\n resolved.map((field) => field.type),\n (args) => (locate(args) as CompositeInOperand).values,\n );\n}\n\n/**\n * The operand's shape, checked at **plan** time.\n *\n * Every other operand in this file is validated here rather than left to fail\n * at bind time — `assertCreateManyOperand`'s note says why: a refusal that\n * arrives later has to unwind work that should never have started. This one\n * was the exception, and it showed: `{ $compositeIn: null }` raised a raw\n * `TypeError` from a destructure, and `{ fields: [\"id\"] }` with no `values` at\n * all compiled clean and deferred its failure to bind time.\n */\nfunction assertCompositeInOperand(\n schema: ModelSchema,\n operand: unknown,\n context: WhereContext,\n): string[] {\n /**\n * A caller's key gets the **unknown-key treatment**, which is what the\n * original comment promised and what every other key it is not a field for\n * already gets. `UnsupportedQueryError` would render \"does not support\n * '$compositeIn' *yet*\" — a promise about a key that is deliberately not in\n * the grammar and never will be. That word has now been corrected once each\n * on #82 and #88; this is the third time it has been raised, which is enough\n * to stop treating it as a wording nit and use the error that is simply\n * accurate: `$compositeIn` is not a field on this model.\n */\n const notAField = (): never => {\n throw new UnknownFieldError(\n COMPOSITE_IN,\n schema.name,\n Object.keys(schema.fields),\n );\n };\n\n if (typeof operand !== \"object\" || operand === null || Array.isArray(operand)) {\n return notAField();\n }\n\n if ((operand as Record<symbol, unknown>)[PLANNER] !== true) {\n return notAField();\n }\n\n /**\n * Below here the operand *is* the planner's, so a bad shape is this ORM's bug\n * rather than a caller's — and `UnsupportedQueryError` is the right class for\n * it: an internal invariant that does not hold is genuinely something the\n * ORM does not support, and \"yet\" is the honest word for a state it should\n * not be in.\n */\n const refuse = (detail: string): never => {\n throw new UnsupportedQueryError(\n COMPOSITE_IN,\n schema.name,\n context.operation,\n detail,\n );\n };\n\n const { fields, values } = operand as CompositeInOperand;\n\n // Below here the operand *is* the planner's, so these are its bugs rather\n // than a caller's — worth catching at compile time for the same reason, and\n // worth a different sentence because the audience is different.\n if (!Array.isArray(fields) || fields.length === 0) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with no fields.`);\n }\n if (!fields.every((name) => typeof name === \"string\")) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with a non-string field.`);\n }\n if (!Array.isArray(values)) {\n return refuse(`the planner built a '${COMPOSITE_IN}' with no values.`);\n }\n if (!values.every((tuple) => Array.isArray(tuple) && tuple.length === fields.length)) {\n return refuse(\n `the planner built a '${COMPOSITE_IN}' whose tuples do not all have ` +\n `${fields.length} value(s).`,\n );\n }\n\n return fields;\n}\n\n/**\n * The filters Prisma applies to a **scalar list** — `tags String[]`.\n *\n * A different set on a different left-hand side, which is why it is a branch\n * rather than four more entries in `OPERATORS`: `contains` on a `String` asks\n * about a substring, and on a `String[]` there is no such question — the one\n * Prisma spells is `has`. Sharing the table would have made every scalar\n * operator compile against an array column and answer something.\n *\n * A tuple for the same reason {@link JSON_FILTER_NAMES} is one: `ListFilter` in\n * `../types` said in a comment that it mirrors this list, and a comment is not\n * something the compiler checks.\n */\nconst LIST_FILTER_NAMES = [\n \"equals\",\n \"has\",\n \"hasEvery\",\n \"hasSome\",\n \"isEmpty\",\n] as const;\n\n/** One of {@link LIST_FILTER_NAMES}. `ListFilter` maps over this. */\nexport type ListFilterName = (typeof LIST_FILTER_NAMES)[number];\n\nconst LIST_FILTERS: ReadonlySet<string> = new Set(LIST_FILTER_NAMES);\n\n/**\n * `where: { tags: { has: \"urgent\" } }`.\n *\n * **The dialect answers first**, before any operand is looked at, because on\n * SQLite the answer is \"not this column, on this database, ever\" rather than\n * \"not this filter\". That refusal used to live in the generator (#300) and\n * could not stay there: the generated artifact is dialect-agnostic on purpose,\n * so refusing a scalar list at generation refused it for Postgres too — and\n * refused the *whole artifact*, since one `String[]` anywhere threw before any\n * model was emitted.\n */\nfunction compileListFilter(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n assertListDialect(schema, field, `where.${field.name}`, context.operation, dialect);\n\n // **A bare array is not shorthand for `equals` here**, and that is the one\n // place a list deliberately reads differently from a scalar — where\n // `{ email: \"a@b\" }` means `equals`, `{ tags: [\"a\"] }` means nothing.\n //\n // Not a judgement call: Prisma refuses it, measured against a generated 6.19\n // client — *\"Argument `strings`: Invalid value provided. Expected\n // StringNullableListFilter, provided (String).\"* Accepting it would make gemi\n // a silent superset of Prisma on the one dialect where a differential test\n // could otherwise check every other answer, which is the trade this project\n // has declined every time it has come up.\n //\n // The asymmetry that surprises: the same bare array *is* accepted as a\n // **write** value — `data: { tags: [\"a\"] }` is valid Prisma and valid here.\n // Filter and value are different positions and Prisma treats them\n // differently; so does this.\n if (Array.isArray(value)) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, and a bare array is not a filter on ` +\n `one — Prisma rejects it here too. Say which comparison you mean: ` +\n `{ ${field.name}: { equals: [...] } } for the whole list, or ` +\n `{ ${field.name}: { hasEvery: [...] } } for \"contains all of these\". ` +\n `A bare array *is* accepted as a value in \\`data\\`.`,\n );\n }\n\n if (!isFilterObject(value)) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list. Expected an object holding ` +\n `${[...LIST_FILTERS].sort().join(\", \")}; received ` +\n `${value === null ? \"null\" : typeof value}.`,\n );\n }\n\n const filter = value as Record<string, unknown>;\n const parts: Fragment[] = [];\n\n // Sorted, for the reason `compileWhere` sorts: the plan cache canonicalises\n // key order, so two objects differing only in it must compile alike.\n for (const key of Object.keys(filter).sort()) {\n const operand = filter[key];\n if (operand === undefined) continue;\n\n if (!LIST_FILTERS.has(key)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, and a list filter takes ` +\n `${[...LIST_FILTERS].sort().join(\", \")}. The scalar operators — ` +\n `${[...OPERATORS].sort().join(\", \")} — apply to a single value and ` +\n `Prisma does not offer them here.`,\n );\n }\n\n const at = (args: any) => locate(args)?.[key];\n parts.push(listComparison(schema, field, column, key, operand, context, at));\n }\n\n // An empty filter object constrains nothing, which is what the scalar path\n // does with `{}` too.\n if (parts.length === 0) return sql(\"true\");\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** One list filter key. */\nfunction listComparison(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n key: string,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n if (key === \"equals\") {\n return listEquals(schema, field, column, operand, context, locate);\n }\n\n if (key === \"isEmpty\") {\n if (typeof operand !== \"boolean\") {\n throw new InvalidArgumentError(\n `where.${field.name}.isEmpty`,\n schema.name,\n context.operation,\n `Expected true or false, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n return dialect.listIsEmpty(column, operand);\n }\n\n if (key === \"has\") {\n // One **element**, so it binds as one — through the element's own field, so\n // a `Json[]` gets #209's `::text::jsonb` on the placeholder and the\n // serialisation that has to travel with it. Binding it as a list instead\n // would produce an array literal on the left of `= any(...)`, and binding\n // it with no cast answers *false* on a `Json[]` rather than raising.\n const element = elementOf(field);\n return dialect.listHas(\n column,\n fieldParam(element, dialect, encoded(element, dialect, locate)),\n );\n }\n\n // `hasEvery` / `hasSome` — both take a list, and both have a defined answer\n // for an empty one: `@> '{}'` is true of every row and `&& '{}'` of none,\n // which is what Prisma means by \"contains all of nothing\" and \"shares one\n // element with nothing\".\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected an array, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n\n const values = fieldParam(field, dialect, encoded(field, dialect, locate));\n return key === \"hasEvery\"\n ? dialect.listHasEvery(column, values)\n : dialect.listHasSome(column, values);\n}\n\n/** `\"tags\" = $1` — whole-list equality, which is order-sensitive in SQL. */\nfunction listEquals(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n // A list column cannot be null in Prisma — `String[]?` is refused at schema\n // validation — but `equals: null` is still in the generated filter type, and\n // a column written by something other than Prisma can hold NULL. Same\n // reading as everywhere else: `= NULL` matches nothing, `is null` is meant.\n if (operand === null) return sql(`${column} is null`);\n\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.equals`,\n schema.name,\n context.operation,\n `'${field.name}' is a scalar list, so it compares against an array. ` +\n `Received ${typeof operand}. For \"is this element present\", use ` +\n `{ ${field.name}: { has: … } }.`,\n );\n }\n\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, encoded(field, dialect, locate)),\n );\n}\n\n/**\n * The same field, seen as **one element of itself**.\n *\n * `type` already carries the element type — that is the whole reason `isList`\n * is a flag beside it rather than a `ScalarType` constructor — so dropping the\n * flag is the entire conversion, and `encode`, `decode` and `castParameter` all\n * read it as the scalar they were written for.\n */\nfunction elementOf(field: FieldSchema): FieldSchema {\n return { ...field, isList: false };\n}\n\n/**\n * Refuses a scalar list on a dialect that has no array type, naming it.\n *\n * Shared by the read and write paths, and it says more than \"unsupported\"\n * because the reader's likeliest next question is whether they did something\n * wrong. They did not: Prisma refuses the *column* on SQLite, so a schema that\n * declares one was generated against Postgres and this process is pointed at a\n * database that could not hold it either.\n */\nexport function assertListDialect(\n schema: ModelSchema,\n field: FieldSchema,\n argument: string,\n operation: string,\n dialect: SqlDialect,\n): void {\n if (dialect.listFilters.size > 0) return;\n\n throw new UnsupportedQueryError(\n argument,\n schema.name,\n operation,\n `'${field.name}' is a scalar list, and ${dialect.name} has no array type ` +\n `to hold one. Prisma refuses the column itself on ${dialect.name} — ` +\n `\"the current connector does not support lists of primitive types\" — so ` +\n `this is a difference between the databases rather than a gap in the ` +\n `ORM. The generated artifact is dialect-agnostic, which is why this ` +\n `surfaces here rather than at \\`prisma generate\\`: the schema was ` +\n `generated against Postgres and DATABASE_URL names a ${dialect.name} ` +\n `database, which has no '${field.column}' column either. It works on ` +\n `postgres.`,\n );\n}\n\n/**\n * The filters Prisma applies to a value extracted from a JSON path.\n *\n * **A tuple, and the caller-facing type is a mapped type over it.**\n * `JsonPathFilter` in `../types` used to spell these ten names a second time,\n * in a file that neither imports this one nor is imported by it, so the two\n * lists could differ with no compile error, no failing test and no diff a\n * reviewer would flag. That is the mechanism behind #326, #333, #336 and #337 —\n * the compiler accepting something the type refuses to describe — and #336 was\n * the worst of them because the undescribed filter was silently absorbed as an\n * `equals` shorthand rather than refused.\n *\n * Deriving the type from this list makes the drift a compile error at the call\n * sites instead of something the next reviewer has to notice.\n */\nconst JSON_FILTER_NAMES = [\n \"equals\",\n \"not\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n] as const;\n\n/** One of {@link JSON_FILTER_NAMES}. `JsonPathFilter` maps over this. */\nexport type JsonFilterName = (typeof JSON_FILTER_NAMES)[number];\n\nconst JSON_FILTERS: ReadonlySet<string> = new Set(JSON_FILTER_NAMES);\n\n/**\n * `where: { metadata: { path: …, equals: … } }`.\n *\n * **Two dialects, two path grammars, and that is Prisma's split rather than\n * this ORM's.** Measured on both through a generated client: Postgres takes\n * `path: [\"a\", \"b\"]` and refuses a string; SQLite takes `path: \"$.a.b\"` and\n * refuses an array. So the argument is dialect-specific before it arrives here,\n * and `jsonPathSyntax` is what lets the check say which form *this* database\n * wants instead of failing inside the driver.\n *\n * **The path is bound, never interpolated.** This is the one place a caller's\n * value decides part of an expression's meaning, which makes it the obvious\n * place to break invariant 2 by accident. Neither dialect needs it in the text:\n * Postgres's `#>` takes a `text[]` parameter and SQLite's `json_extract` takes\n * a string, so the whole feature fits inside the existing rule.\n *\n * The operator set is the dialect's too. Prisma refuses `array_contains` and\n * the numeric comparisons on SQLite — *\"Unknown argument\"* — so refusing them\n * here is matching it, not falling short: implementing them would make gemi\n * answer a query the oracle cannot, which is precisely where a differential\n * test stops being able to check anything.\n */\nfunction compileJsonFilter(\n schema: ModelSchema,\n field: FieldSchema,\n column: string,\n filter: Record<string, unknown>,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n\n if (field.type !== \"Json\") {\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A 'path' filter reads inside a JSON document, and '${field.name}' is ` +\n `a ${field.type} column.`,\n );\n }\n\n assertPathShape(schema, field, filter.path, context);\n\n const path: Binder = (args) => locate(args)?.path;\n // **An `undefined` operand is an absent one**, which is the rule the scalar\n // operator loop already follows (`if (operand === undefined …) continue`) and\n // the rule the dispatch above follows for `path` itself\n // (`filter.path !== undefined`). Building `applied` from `Object.keys` alone\n // made this branch the one place that broke it: a filter assembled from a\n // form or a query string carries `equals: undefined` for the field nobody\n // filled in, and that compiled to `= NULL` — a predicate no row can satisfy —\n // where the same query with the key simply omitted got the bare-path refusal\n // below.\n //\n // Prisma answers both spellings identically. Measured on a generated 6.19.2\n // client against Postgres: `{ path: [\"a\"], equals: undefined }` and\n // `{ path: [\"a\"] }` both raise P2019 *\"A JSON path cannot be set without a\n // scalar filter.\"*, and `{ path: [\"a\"], equals: 1, gt: undefined }` compiles\n // the `equals` alone.\n //\n // **This is also what makes the plan cache safe here**, which is the stronger\n // reason and the one a reader will otherwise have to re-derive.\n // `canonicalShape` drops `undefined` members, so the two spellings were\n // already *one* cache key — measured:\n //\n // planKey(postgres, \"User\", \"findMany\", { where: { metadata: { path: [\"a\"] } } })\n // planKey(postgres, \"User\", \"findMany\", { where: { metadata: { path: [\"a\"], equals: undefined } } })\n // both -> postgres:batched:User:findMany:{where:{metadata:{path:[string]}}}\n //\n // while they compiled to two different things, a refusal and a `= NULL` plan.\n // Whichever compiled first decided for the other, so a bare `path` arriving\n // second was served the never-true plan instead of the refusal it raises\n // cold. Both throw now, so there is nothing left for the shared key to\n // collide on.\n const applied = Object.keys(filter)\n .filter((key) => key !== \"path\" && filter[key] !== undefined)\n .sort();\n\n if (applied.length === 0) {\n // Prisma: \"A JSON path cannot be set without a scalar filter.\" Reproduced\n // because the alternative is an extraction with nothing to compare it to,\n // which compiles to a value in a predicate position on one dialect and to\n // an error on the other.\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A 'path' needs a filter beside it — ${[...JSON_FILTERS].sort().join(\", \")}. ` +\n `Prisma refuses a bare path too.`,\n );\n }\n\n const parts: Fragment[] = [];\n\n for (const key of applied) {\n if (!JSON_FILTERS.has(key)) {\n throw new UnsupportedQueryError(\n `${field.name}.${key}`,\n schema.name,\n context.operation,\n `A JSON path filter takes ${[...JSON_FILTERS].sort().join(\", \")}.`,\n );\n }\n\n if (!dialect.jsonFilters.has(key)) {\n throw new UnsupportedQueryError(\n `${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${key}' on a JSON path is not available on ${dialect.name}. Prisma ` +\n `refuses it here too, so this is a difference between the databases ` +\n `rather than a gap in the ORM. It works on postgres.`,\n );\n }\n\n const operand = filter[key];\n\n // **`equals` and `not` answer the three sentinels; the other eight refuse\n // them.** That split is Prisma's, measured on a generated 6.19.2 client\n // against both databases rather than derived from the operators:\n //\n // equals / not compiled, and the SQL is in `jsonNullAtPath`\n // the other eight \"Invalid value provided. … provided Enum.\"\n //\n // The refusal below used to cover all ten, and its reason was true of the\n // extraction it named rather than of the dialect: `#>>` does yield NULL for\n // an absent key and for a JSON `null` alike, but `#>` does not, and neither\n // does SQLite's `->`. `dialect.jsonValueAt` is that second extraction, so\n // the distinction the sentinels exist to draw survives to the comparison\n // and there is nothing left to refuse — #407.\n //\n // A bare `null` takes the same branch, as `JsonNull`. It is not a third\n // reading: Prisma compiles `{ path: […], equals: null }` and\n // `{ path: […], equals: Prisma.JsonNull }` to byte-identical SQL and\n // returns identical rows on both dialects, measured. It was refused for the\n // same `#>>` reason (#371's second item), and the same fix reaches it.\n const sentinel: JsonNullKind | null =\n operand === null ? \"json\" : jsonNullKind(operand);\n\n if (sentinel && (key === \"equals\" || key === \"not\")) {\n parts.push(\n jsonNullAtPath(sentinel, column, path, field, dialect, key === \"not\"),\n );\n continue;\n }\n\n if (sentinel && operand !== null) {\n // **The clause naming the mechanism branches for `array_contains`**, for\n // the same reason `assertJsonOperand`'s `null` guard branches below: that\n // operator does not compare an extracted scalar at all — it compiles to\n // `#>` + `@>`, containment against a jsonb document — so telling its\n // caller about a scalar comparison names a mechanism it does not have.\n // Everything else here does compare one bound scalar against one\n // extracted value.\n const because =\n key === \"array_contains\"\n ? `'array_contains' tests containment against a document, and a ` +\n `sentinel is not one`\n : `'${key}' compares an extracted value against a scalar, and a ` +\n `sentinel is not one`;\n\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `${sentinelName(sentinel)} asks which kind of null a value is, which ` +\n `only 'equals' and 'not' can express — ${because}. ` +\n `Prisma refuses it under this operator too. Write ` +\n `{ ${field.name}: { path: […], equals: ${sentinelName(sentinel)} } }, ` +\n `or filter the column itself — ` +\n `{ ${field.name}: { equals: ${sentinelName(sentinel)} } }.`,\n );\n }\n\n // The same shape one level down — `{ path: …, array_contains: [AnyNull] }`.\n // Still refused, and now for its own reason rather than by inheriting the\n // extraction's: `AnyNull` is a *question*, not a value, so there is nothing\n // to put inside a document. (`equals` and `not` never reach here with an\n // object operand — `assertJsonOperand` refuses one below — so this is\n // `array_contains`'s case in practice.)\n if (carriesAnyNull(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Prisma.AnyNull is a question rather than a value — 'either kind of ` +\n `null' — so it cannot appear inside a document. Ask it directly: ` +\n `{ ${field.name}: { path: […], equals: Prisma.AnyNull } }.`,\n );\n }\n\n assertJsonOperand(key, operand, schema, field, context);\n\n parts.push(\n jsonComparison(key, column, path, field, dialect, (args) =>\n locate(args)?.[key],\n ),\n );\n }\n\n return parts.length === 1\n ? parts[0]\n : group(parts, \" and \");\n}\n\n/**\n * A null sentinel at a JSON path — `{ path: [\"operation\"], equals: AnyNull }`.\n *\n * **The two halves, and why neither is the other.** A `Json` column has two\n * empty states and so does a *key inside* one, except the key's second state is\n * \"not there at all\":\n *\n * DbNull the value at the path is missing — an absent key, or a column\n * that is SQL NULL, or one holding a JSON null (nothing to index)\n * JsonNull the value at the path is the JSON value `null`\n * AnyNull either, which is what `AnyNull` means everywhere else\n *\n * `dialect.jsonValueAt` is what keeps them apart; `jsonExtract` at `asText:\n * true` does not, which is the collapse that had all three refused here before\n * #407. So `DbNull` is `is null` on the extraction itself and `JsonNull` is an\n * equality against the JSON null, bound the way {@link jsonNullComparison}\n * binds it on the column path — through the dialect's own encoder, so `'null'`\n * on SQLite and `'null'::text::jsonb` on Postgres stay that encoder's business.\n *\n * **`negated` is the direct form, not `not (…)`.** Prisma emits `IS NOT NULL`,\n * `<>` and `(<> … AND IS NOT NULL)`, and the negation of the positive form\n * agrees with all three under three-valued logic — `equals`'s own comment makes\n * the same argument on the column path. The direct spelling is emitted because\n * it is the one the oracle emits and it reads as what it means; the contract is\n * equal results either way.\n *\n * Measured on 6.19.2 against Postgres 16 and SQLite, over rows covering an\n * absent key, a JSON null at the key, a scalar at the key, a SQL-NULL column\n * and a JSON-null column. Both dialects return the same five row sets, and this\n * compiles to the same predicates:\n *\n * equals: DbNull absent key, SQL-NULL column, JSON-null column\n * equals: JsonNull the key holding a JSON null\n * equals: AnyNull all four of those\n * not: DbNull the key holding a JSON null, and the key holding a scalar\n * not: JsonNull the key holding a scalar\n * not: AnyNull the key holding a scalar\n */\nfunction jsonNullAtPath(\n kind: JsonNullKind,\n column: string,\n path: Binder,\n field: FieldSchema,\n dialect: SqlDialect,\n negated: boolean,\n): Fragment {\n // `is null` on the extraction: nothing is there to compare.\n const missing = (): Fragment =>\n concat(\n dialect.jsonValueAt(column, path),\n sql(negated ? \" is not null\" : \" is null\"),\n );\n\n // ...and the JSON value `null`, which is a value and compares as one.\n const jsonNull = (): Fragment =>\n concat(\n dialect.jsonValueAt(column, path),\n sql(negated ? \" <> \" : \" = \"),\n fieldParam(field, dialect, () => dialect.encode(JSON_NULL, field)),\n );\n\n if (kind === \"db\") return missing();\n if (kind === \"json\") return jsonNull();\n\n // The path is bound twice, once per half, which is what Prisma does too —\n // it is a parameter, so there is nothing to share and nothing in the text.\n return group([jsonNull(), missing()], negated ? \" and \" : \" or \");\n}\n\n/**\n * What each JSON filter will accept as its operand.\n *\n * Three defects, all of them the shape the scalar path is already careful about\n * and all silent:\n *\n * - **The string filters had no non-string guard.** Their scalar siblings\n * refuse one, with a comment explaining that `String(null)` makes the\n * pattern `%null%` — \"a query that runs and returns the wrong rows\".\n * `string_contains: null` compiled to `like NULL`, which matches nothing\n * and raises nothing; `string_contains: 5` compiled to `%5%`. Prisma raises\n * for both.\n *\n * - **`equals` / `not` accepted a non-scalar.** On Postgres the comparison\n * binds `String(raw)` because `#>>` yields text, so `equals: { b: 1 }` bound\n * the string `\"[object Object]\"` and matched nothing.\n *\n * - **`null` fell between the two.** The string branch refuses a non-string\n * and the object branch tests `operand !== null` first, so `equals: null`\n * reached the binder and compiled to `= NULL` — see the guard below. Under\n * `equals` and `not` it is answered rather than refused now, and never\n * reaches this function: #407 gave those two the extraction that can tell a\n * JSON `null` from an absent key, and `equals: null` is `equals: JsonNull`\n * on the oracle. The guard below covers the operators that are left.\n *\n * The object operand is still a **refusal rather than an implementation**, and\n * the reason has narrowed. It used to be that answering it needs the JSON-\n * preserving extraction, which was Postgres-only here — so implementing it\n * would give SQLite either a second wrong answer or a silent divergence. That\n * is no longer true: `dialect.jsonValueAt` is that extraction and both dialects\n * have it (#407). What is left is simply that nobody has compiled a document\n * comparison against it — the operand would still bind through `jsonComparison`\n * as a scalar — so this stays a named limitation rather than becoming a silent\n * wrong answer, which is what this file does everywhere it cannot answer.\n * `array_contains` is exempt from the object rule because containment is\n * precisely the operator that takes a document — but not from the `null` one,\n * because a bound SQL NULL is not a JSON `null` on either side of `@>`.\n */\nfunction assertJsonOperand(\n key: string,\n operand: unknown,\n schema: ModelSchema,\n field: FieldSchema,\n context: WhereContext,\n): void {\n const stringly =\n key === \"string_contains\" ||\n key === \"string_starts_with\" ||\n key === \"string_ends_with\";\n\n if (stringly && typeof operand !== \"string\") {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected a string, received ${\n operand === null ? \"null\" : typeof operand\n }. Prisma raises here too — without this the pattern becomes ` +\n `'%${String(operand)}%', which runs and returns the wrong rows.`,\n );\n }\n\n // **`null` is refused under the operators that are left**, and the oracle\n // agrees about the numeric four and not about `array_contains`.\n //\n // `equals` and `not` do not reach this — `compileJsonFilter` compiles them\n // as `JsonNull` before calling here, because Prisma reads a bare `null` at a\n // path as the JSON value `null` and returns the rows holding one: identical\n // SQL and identical rows to `equals: Prisma.JsonNull`, measured on 6.19.2\n // against both dialects. That was #371's second item, and it was refused for\n // a reason that was true of `#>>` rather than of the database.\n //\n // The four numeric comparisons are a different answer, measured the same way:\n // `{ path: [\"a\"], gt: null }` does not compile on Prisma either. Its query\n // engine *panics* — \"JSON target types only accept strings or numbers, found:\n // null\", from `sql-query-builder/src/filter/visitor.rs` — so refusing is\n // matching the oracle rather than falling short of it, and this message says\n // so instead of promising an answer later. Left alone it reached the binder\n // and compiled to `cast((\"metadata\" #>> $1) as real) > $2` bound to NULL,\n // which is NULL rather than true: a query that runs and matches nothing.\n //\n // `array_contains` is included rather than exempt, **and it is the one place\n // here that refuses something the oracle answers**. Its mechanism is its own:\n // it takes the `#>` form, so the text collapse never applied to it, but\n // `jsonArrayContains` binds the operand raw, so `null` arrives as SQL NULL\n // and `x @> NULL` is NULL too — a query that runs and matches nothing.\n //\n // Prisma compiles it, measured: `(payload #> $1)::jsonb @> $2 AND\n // JSONB_TYPEOF((payload #> $3)::jsonb) = 'array'`, which also returns no rows\n // — so the refusal costs a caller nothing but an error where the oracle gave\n // an empty set, and this comment says so rather than claiming parity it does\n // not have. `docs/orm.md` records it in the same terms.\n //\n // The message below branches for the mechanism: telling an `array_contains`\n // caller about an extracted scalar would name something this operator does\n // not have, and pointing them at `{ equals: Prisma.JsonNull }` would answer a\n // containment question with an equality.\n if (operand === null) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n key === \"array_contains\"\n ? `null cannot be tested for containment through a JSON path: the ` +\n `operand binds as SQL NULL rather than as the JSON value, and ` +\n `'x @> NULL' is NULL rather than true — the query would run and ` +\n `match nothing. A null *inside* the document ` +\n `is an ordinary value and still compiles: ` +\n `{ ${field.name}: { path: […], array_contains: [null] } }.`\n : `null cannot be compared through a JSON path with '${key}', which ` +\n `compares the extracted value as a number — the comparison against ` +\n `NULL is NULL rather than true, so the query would run and match ` +\n `nothing. Prisma refuses it here too. For \"the value at this path ` +\n `is a JSON null\", use equals or not: ` +\n `{ ${field.name}: { path: […], equals: null } }.`,\n );\n }\n\n if (key === \"array_contains\" || stringly) return;\n\n // `equals`, `not`, and the four numeric comparisons all compare an extracted\n // scalar against one bound value. No `!== null` here: `typeof null` is\n // `\"object\"`, and the guard above has already refused it with its own reason.\n if (typeof operand === \"object\") {\n throw new UnsupportedQueryError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${key}' on a JSON path compares the extracted value as a scalar, so ` +\n `an object or array operand cannot be expressed — it would bind as ` +\n `'${String(operand)}' and match nothing. Prisma accepts one here; ` +\n `gemi does not yet. Use array_contains for containment, or narrow the ` +\n `path until it names a scalar.`,\n );\n }\n}\n\n/** The comparison for one JSON filter key. */\nfunction jsonComparison(\n key: string,\n column: string,\n path: Binder,\n field: FieldSchema,\n dialect: SqlDialect,\n value: Binder,\n): Fragment {\n if (key === \"array_contains\") {\n return dialect.jsonArrayContains(column, path, value);\n }\n\n // The string filters compare *text*, so they need the text-returning\n // extraction; everything else compares the value.\n const stringly =\n key === \"string_contains\" ||\n key === \"string_starts_with\" ||\n key === \"string_ends_with\";\n\n const extracted = dialect.jsonExtract(column, path, true);\n\n if (stringly) {\n const wrap =\n key === \"string_contains\"\n ? (text: string) => `%${text}%`\n : key === \"string_starts_with\"\n ? (text: string) => `${text}%`\n : (text: string) => `%${text}`;\n\n return concat(\n sql(\"(\"),\n extracted,\n sql(\") like \"),\n param((args, context) => {\n const raw = value(args, context);\n return raw === null || raw === undefined ? null : wrap(String(raw));\n }),\n );\n }\n\n const operator =\n key === \"equals\" ? \"=\" : key === \"not\" ? \"<>\" : COMPARISONS[key];\n\n // `#>>` and `json_extract` both yield text, so a numeric comparison has to\n // compare numbers rather than their spellings — otherwise \"10\" < \"9\". The\n // cast is structural, never a value.\n const numeric = key !== \"equals\" && key !== \"not\";\n const lhs = numeric\n ? concat(sql(\"cast((\"), extracted, sql(\") as real)\"))\n : concat(sql(\"(\"), extracted, sql(\")\"));\n\n return concat(\n lhs,\n sql(` ${operator} `),\n param((args, context) => {\n const raw = value(args, context);\n if (raw === null || raw === undefined) return null;\n if (numeric) return Number(raw);\n // Text on Postgres, native on SQLite — see `jsonComparesAsText`. The\n // wrong one returns no rows on one dialect and raises on the other.\n return dialect.jsonComparesAsText ? String(raw) : raw;\n }),\n );\n}\n\n/** The path is a string on SQLite and an array of string keys on Postgres. */\nfunction assertPathShape(\n schema: ModelSchema,\n field: FieldSchema,\n path: unknown,\n context: WhereContext,\n): void {\n const { dialect } = context;\n const wanted = dialect.jsonPathSyntax === \"array\" ? \"array\" : \"jsonpath\";\n const got = Array.isArray(path) ? \"array\" : typeof path === \"string\" ? \"jsonpath\" : \"other\";\n\n // **The empty path is refused on both dialects, and it is not the same\n // mistake as a wrong shape.** `[]` on Postgres extracts the whole document —\n // `[].every` is vacuously true, so it used to pass this check — and `\"\"` on\n // SQLite raises inside `json_extract` at execution time. Neither is a path,\n // and a caller who wrote one meant to write something. Refused with its own\n // sentence rather than the grammar message below, which would tell them to\n // use the form they already used.\n const empty =\n (Array.isArray(path) && path.length === 0) || path === \"\";\n if (empty) {\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A JSON path cannot be empty. ${\n dialect.jsonPathSyntax === \"array\"\n ? `On ${dialect.name} an empty array selects the whole document, ` +\n `which is a filter on the column rather than on a path — write ` +\n `{ ${field.name}: { equals: … } } if that is what you meant.`\n : `On ${dialect.name} an empty string raises inside json_extract.`\n }`,\n );\n }\n\n if (got === wanted) {\n if (wanted !== \"array\") return;\n\n // **Every segment is a string, and the number that used to be allowed here\n // was a superset of the oracle.** Prisma's generated `path` on Postgres is\n // `string[]`, and its client refuses a number at run time as well as at\n // compile time — measured on 6.19.2: `path: [\"items\", 0]` answers\n // *\"Argument `path`: Invalid value provided. Expected String, provided\n // Int.\"* before any SQL is built.\n //\n // Refused rather than kept, because this file already states the rule that\n // decides it: answering a query the oracle cannot express is \"precisely\n // where a differential test stops being able to check anything\"\n // (`compileJsonFilter`'s docblock, on the SQLite operators). Nothing is\n // lost — `[\"items\", \"0\"]` reaches the same array element, since `#>` takes\n // a `text[]` and the segment arrives as text either way. Measured: both\n // spellings bind `[\"items\", \"0\"]` and return the same row on Prisma, and\n // gemi's binder already stringifies through the `text[]` cast.\n //\n // Its own sentence rather than the grammar message below, which would tell\n // a caller who wrote an array to write an array.\n const offending = (path as unknown[]).findIndex(\n (part) => typeof part !== \"string\",\n );\n if (offending === -1) return;\n\n // `a ${typeof part}` alone reads as \"a undefined\" / \"a object\" for every\n // segment but the number, so the description is spelled out. And the array\n // index sentence is advice for one mistake in particular — a caller who\n // wrote `null` did not write an index — so it is gated on the number\n // rather than emitted for everything.\n const part = (path as unknown[])[offending];\n const described =\n part === null\n ? \"null\"\n : part === undefined\n ? \"undefined\"\n : Array.isArray(part)\n ? \"an array\"\n : typeof part === \"object\"\n ? \"an object\"\n : `a ${typeof part}`;\n\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n `A JSON path is an array of strings, and path[${offending}] is ` +\n `${described}. ` +\n (typeof part === \"number\"\n ? `An array index is a key too — write [\"items\", \"0\"] rather than ` +\n `[\"items\", 0]; it reaches the same element, because ` +\n `${dialect.name} takes the path as text. Prisma's path is ` +\n `string[] and its client refuses a number here too.`\n : `Prisma's path is string[] too.`),\n );\n }\n\n throw new UnsupportedQueryError(\n `${field.name}.path`,\n schema.name,\n context.operation,\n dialect.jsonPathSyntax === \"array\"\n ? `On ${dialect.name} a JSON path is an array of keys — [\"a\", \"b\"] — ` +\n `not a JSONPath string. Prisma splits them the same way, and refuses ` +\n `the other form on each database.`\n : `On ${dialect.name} a JSON path is a JSONPath string — \"$.a.b\" — not ` +\n `an array of keys. Prisma splits them the same way, and refuses the ` +\n `other form on each database.`,\n );\n}\n\nfunction compileFieldFilter(\n schema: ModelSchema,\n field: FieldSchema,\n value: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n): Fragment {\n const { dialect } = context;\n const column = `${context.qualifier ?? \"\"}${dialect.quoteIdent(field.column)}`;\n\n // A bare `Prisma.DbNull` is **not** shorthand for `equals`, and Prisma refuses\n // it: `where: { settings: Prisma.DbNull }` is an invalid invocation there,\n // spelled out under the offending key. Both sentinels are objects with no\n // enumerable properties, so left alone they read as an operator map holding\n // no operators — which compiles to `true`, and answered \"every row\" to a\n // question about the null ones.\n //\n // Refused rather than interpreted, because guessing which of the two nulls a\n // caller meant is the whole thing the sentinels exist to stop, and because\n // matching Prisma means matching its refusals as well as its results.\n const sentinel = jsonNullKind(value);\n if (sentinel) {\n throw new InvalidArgumentError(\n `where.${field.name}`,\n schema.name,\n context.operation,\n `${sentinelName(sentinel)} is not a filter on ` +\n `its own — Prisma rejects it here too. Write it as an explicit ` +\n `comparison: { ${field.name}: { equals: ${sentinelName(sentinel)} } }.`,\n );\n }\n\n // A scalar list takes a different operator set on a different left-hand side,\n // so the whole operand belongs to that branch — the same shape the `path`\n // check below has for a JSON document. Placed *above* the bare-value\n // shorthand because on a list the bare form is an **array**, which\n // `isFilterObject` reports as a value and would send to the scalar `equals`\n // with no dialect check and no operand validation.\n if (field.isList) {\n return compileListFilter(schema, field, column, value, context, locate);\n }\n\n // A bare value is shorthand for `equals`. A `Date` is a value, not a filter\n // object, even though `typeof` cannot tell them apart.\n if (!isFilterObject(value)) {\n return equals(column, field, value, dialect, locate);\n }\n\n const filter = value as Record<string, unknown>;\n const keys = Object.keys(filter).sort();\n\n // A `path` turns the whole operand into a JSON filter, whose operators are a\n // different set from the scalar ones and whose left-hand side is an\n // extraction rather than a column.\n if (filter.path !== undefined) {\n return compileJsonFilter(schema, field, column, filter, context, locate);\n }\n\n // Prisma-only, and only meaningful next to a string operator. Read here so it\n // does not get treated as an operator in its own right.\n const insensitive = filter.mode === \"insensitive\";\n if (filter.mode !== undefined && filter.mode !== \"default\") {\n if (!insensitive) {\n throw new InvalidArgumentError(\n `mode: ${JSON.stringify(filter.mode)}`,\n schema.name,\n context.operation,\n `Prisma takes 'default' or 'insensitive'.`,\n );\n }\n if (!dialect.supportsInsensitiveMode) {\n throw new UnsupportedQueryError(\n \"mode: \\\"insensitive\\\"\",\n schema.name,\n context.operation,\n `The ${dialect.name} dialect cannot express it — Prisma rejects it ` +\n `here too. Note SQLite's LIKE is already case-insensitive for ASCII.`,\n );\n }\n }\n\n const parts: Fragment[] = [];\n\n for (const key of keys) {\n const operand = filter[key];\n if (operand === undefined || key === \"mode\") continue;\n\n if (!OPERATORS.has(key)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `A scalar filter takes ${[...OPERATORS].sort().join(\", \")}.`,\n );\n }\n\n // `AnyNull` asks for both nulls at once, which only `equals` and `not` can\n // express. Under any other operator it has no meaning — Prisma's own\n // `JsonNullableFilter` admits it in exactly those two positions — and left\n // alone it would reach the binder, where it is an ORM bug by construction.\n // Refused here, where the field and operation are in scope to name it,\n // rather than at the backstop that would report it as ours.\n if (key !== \"equals\" && key !== \"not\" && carriesAnyNull(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Prisma.AnyNull means 'either kind of null', which only 'equals' and ` +\n `'not' can express. Write { ${field.name}: { equals: Prisma.AnyNull } }, ` +\n `or name the one you mean with Prisma.DbNull or Prisma.JsonNull.`,\n );\n }\n\n const at = (args: any) => locate(args)?.[key];\n\n switch (key) {\n case \"equals\":\n parts.push(equals(column, field, operand, dialect, at));\n break;\n\n case \"not\":\n parts.push(\n compileNot(schema, field, operand, context, at, column),\n );\n break;\n\n case \"in\":\n case \"notIn\":\n parts.push(\n inList(schema, column, field, operand, context, at, key === \"notIn\"),\n );\n break;\n\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\":\n parts.push(\n concat(\n sql(`${column} ${COMPARISONS[key]} `),\n fieldParam(field, dialect, encoded(field, dialect, at)),\n ),\n );\n break;\n\n case \"contains\":\n case \"startsWith\":\n case \"endsWith\":\n // Prisma raises \"Argument `contains` must not be null\" — verified.\n // Without this, `String(null)` makes the pattern `%null%`, which is a\n // query that runs and returns the wrong rows. The types catch the\n // static case but not a value that arrives dynamically.\n if (typeof operand !== \"string\") {\n throw new InvalidArgumentError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `Expected a string, received ${operand === null ? \"null\" : typeof operand}.`,\n );\n }\n if (field.type !== \"String\") {\n throw new UnsupportedQueryError(\n `where.${field.name}.${key}`,\n schema.name,\n context.operation,\n `'${field.name}' is a ${field.type}, and ${key} only applies to strings.`,\n );\n }\n parts.push(dialect.like(column, insensitive, likePattern(key, at)));\n break;\n }\n }\n\n if (parts.length === 0) return sql(\"true\");\n if (parts.length === 1) return parts[0];\n return group(parts, \" and \");\n}\n\n/** How a sentinel is spelled in a message, so an error can be pasted back as code. */\nfunction sentinelName(kind: JsonNullKind): string {\n return `Prisma.${kind === \"db\" ? \"DbNull\" : kind === \"json\" ? \"JsonNull\" : \"AnyNull\"}`;\n}\n\n/**\n * Whether an operand is `AnyNull`, or a list holding one.\n *\n * The list case is the reachable one: `in: [Prisma.AnyNull]` type-checks\n * nowhere in Prisma, but nothing stops it being written in JavaScript, and\n * `inList` would bind it as an ordinary value.\n */\nfunction carriesAnyNull(operand: unknown): boolean {\n if (jsonNullKind(operand) === \"any\") return true;\n return Array.isArray(operand) && operand.some((item) => jsonNullKind(item) === \"any\");\n}\n\n/** `not` is a whole nested filter, not just a value — `not: { in: [...] }`. */\nfunction compileNot(\n schema: ModelSchema,\n field: FieldSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n column: string,\n): Fragment {\n // `DbNull` is the sentinel spelling of the same question, so it takes the\n // same branch — see `equals`.\n if (operand === null || jsonNullKind(operand) === \"db\") {\n return sql(`${column} is not null`);\n }\n\n // `JsonNull` does not: it asks about a stored JSON *value*, so negating it is\n // a value comparison. Handled here rather than by delegating, because the\n // delegate refuses a bare sentinel — correctly, since Prisma does — and this\n // one did not arrive bare. `{ not: Prisma.JsonNull }` is a valid Prisma\n // filter and has to stay one.\n if (jsonNullKind(operand) === \"json\") {\n return concat(\n sql(\"not \"),\n parenthesize(equals(column, field, operand, context.dialect, locate)),\n );\n }\n\n // `not: AnyNull` is \"neither kind of null\", so it negates the union `equals`\n // builds. Safe to negate directly because that predicate is total — see the\n // note there — so no row falls through on NULL the way `not (col = value)`\n // would.\n if (jsonNullKind(operand) === \"any\") {\n return concat(\n sql(\"not \"),\n parenthesize(equals(column, field, operand, context.dialect, locate)),\n );\n }\n\n if (!isFilterObject(operand)) {\n return concat(\n sql(`${column} <> `),\n fieldParam(field, context.dialect, encoded(field, context.dialect, locate)),\n );\n }\n\n // `not: { in: [...] }` and the rest compile to `not (<positive form>)`.\n // Prisma emits `not in` directly, which is a different *text* but the same\n // predicate: both yield NULL — and so exclude the row — when the column is\n // NULL. The contract is equal results, not equal SQL.\n const inner = compileFieldFilter(schema, field, operand, context, locate);\n return concat(sql(\"not \"), parenthesize(inner));\n}\n\nfunction equals(\n column: string,\n field: FieldSchema,\n operand: unknown,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Fragment {\n // `= ?` with a null parameter matches nothing in SQL, where Prisma means\n // `is null`. This is the difference that would silently return wrong rows.\n //\n // `Prisma.DbNull` means the same thing on a `Json` column and arrives as a\n // sentinel object rather than as `null`, so it reached the parameter path\n // below and compiled to `= ?` — matching nothing, whatever the table held.\n // Its sibling `JsonNull` is a genuine *value* comparison and belongs there:\n // the column holds the JSON `null`, and `= 'null'` is how you find it.\n //\n // **KNOWN DIVERGENCE — a bare `null` on a `Json` column.** For every other\n // column type `operand === null` meaning `is null` *is* Prisma's reading. On\n // a `Json` column it is not: Prisma reads a bare `null` as the JSON value\n // `null` there, exactly as it does at a path. Measured on 6.19.2 against\n // Postgres 16 and SQLite, over a table holding both empty states:\n //\n // { equals: null } prisma \"payload\"::jsonb = $1 the JSON-null rows\n // gemi \"payload\" is null the SQL-NULL rows\n // { not: null } prisma \"payload\"::jsonb <> $1\n // gemi \"payload\" is not null (one row more)\n //\n // Disjoint row sets on identical data, and nothing raises. Left alone rather\n // than fixed here: this is the *column* path, and #407 is about a value at a\n // path — where a bare `null` now agrees with Prisma exactly, because\n // `compileJsonFilter` reads it as `JsonNull`. Changing the column would be a\n // behaviour change to released semantics for every `Json` filter, which wants\n // its own change and its own differential cases.\n //\n // `{ equals: Prisma.DbNull }` is unambiguous and compiles to this same\n // predicate on both libraries, so the divergence has a spelling that avoids\n // it. `docs/orm.md` says so where a reader will look, and\n // `known-divergences.test.ts` pins that it keeps saying so.\n if (operand === null || jsonNullKind(operand) === \"db\") {\n return sql(`${column} is null`);\n }\n\n // `AnyNull` is the union of the other two, and the only operand here that is\n // not a single comparison. Both halves are needed: the column being SQL NULL\n // and the column holding the JSON value `null` are different rows, and this\n // is the one filter that asks for both.\n //\n // No three-valued-logic trap in the `or`. `is null` is never NULL, and when\n // the column is non-NULL the second half is a proper boolean — so the\n // predicate is total, which is what makes negating it in `compileNot` safe.\n if (jsonNullKind(operand) === \"any\") {\n return group(\n [sql(`${column} is null`), jsonNullComparison(column, field, dialect)],\n \" or \",\n );\n }\n\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, encoded(field, dialect, locate)),\n );\n}\n\n/**\n * `<column> = <the JSON value null>`, as a bound parameter.\n *\n * The literal is the compiler's, not the caller's, so there is no argument to\n * read it out of — but it stays a parameter rather than being written into the\n * text, because invariant 2 admits no exception for a value the compiler\n * happens to know. It is also what keeps the dialects' encoders as the single\n * authority on how a JSON null is spelled: `'null'` on SQLite, `'null'::text::jsonb`\n * on Postgres, decided by `fieldParam` and `castParameter` rather than here.\n */\nfunction jsonNullComparison(\n column: string,\n field: FieldSchema,\n dialect: SqlDialect,\n): Fragment {\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, () => dialect.encode(JSON_NULL, field)),\n );\n}\n\nfunction inList(\n schema: ModelSchema,\n column: string,\n field: FieldSchema,\n operand: unknown,\n context: WhereContext,\n locate: (args: any) => any,\n negated: boolean,\n): Fragment {\n const { dialect } = context;\n\n if (!Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `where.${field.name}.${negated ? \"notIn\" : \"in\"}`,\n schema.name,\n context.operation,\n \"Expected an array.\",\n );\n }\n\n // `x in ()` is a syntax error, and Prisma emits a constant-false predicate\n // for it. `not in ()` is vacuously true by the same logic.\n if (operand.length === 0) return negated ? sql(\"true\") : FALSE;\n\n return dialect.inList(column, negated, operand.length, (args) => {\n const values = locate(args) as unknown[];\n return values.map((value) => dialect.encode(value, field));\n });\n}\n\n/**\n * Prisma does **not** escape `%` or `_` inside the value — verified by reading\n * the parameters it binds: `contains: \"50%_x\"` binds `\"%50%_x%\"`. So a user\n * string containing a wildcard really does act as a wildcard.\n *\n * That is a footgun, but the contract this ORM signs is differential equality\n * with Prisma, and escaping here would break it on every such query. Matching\n * Prisma and saying so is the honest option; diverging quietly is not.\n */\nfunction likePattern(\n operator: \"contains\" | \"startsWith\" | \"endsWith\",\n locate: (args: any) => any,\n): Binder {\n return (args) => {\n const value = String(locate(args));\n if (operator === \"contains\") return `%${value}%`;\n if (operator === \"startsWith\") return `${value}%`;\n return `%${value}`;\n };\n}\n\nfunction encoded(\n field: FieldSchema,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Binder {\n return (args) => dialect.encode(locate(args), field);\n}\n\n/**\n * True for `{ contains: ... }`, false for a plain value. A `Date` is a value\n * even though it is an object, and so is a `Uint8Array` for a `Bytes` column.\n */\nfunction isFilterObject(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !ArrayBuffer.isView(value)\n );\n}\n",
|
|
9
9
|
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport { COUNT_KEY } from \"../relation-filters\";\nimport type { ModelSchema, RelationSchema } from \"../schema\";\nimport { type Fragment, concat, sql } from \"./fragment\";\nimport { correlate } from \"./correlate\";\nimport { compileWhere } from \"./where\";\n\n/**\n * `orderBy: { organization: { name: \"asc\" } }` and\n * `orderBy: { accounts: { _count: \"desc\" } }`.\n *\n * The third use of the same correlated subquery — after `exists` for relation\n * filters and `count(*)` for `_count` — this time as a scalar in the `order by`\n * clause:\n *\n * order by (select \"_o0\".\"name\" from \"Organization\" as \"_o0\"\n * where \"_o0\".\"id\" = \"User\".\"organizationId\") asc\n *\n * A subquery rather than the `left join` Prisma emits, for the reason the other\n * two are subqueries: a join changes what the `from` clause contains, and on a\n * to-many it changes the row count. Ordering must not be able to do either. The\n * cost is that the subquery runs per row, which is the same index dependency the\n * benchmarks measured for `_count` — one `@@index` on the child's foreign key,\n * worth 6.3× there.\n *\n * ### The scope has nowhere to live in Prisma's shape, so we add one\n *\n * Every other path that reaches another model's rows carries a `where` the\n * policy walk can narrow: an `include` node has one, a relation filter's\n * operand is one, a `_count` entry takes one. `orderBy: { rel: { field: \"asc\" } }`\n * has none — Prisma's grammar has no slot for it.\n *\n * It still needs one. Ordering by a column of rows the caller cannot read leaks\n * their contents by comparison, and ordering by `_count` leaks their number\n * outright. So the policy walk writes `where` into this node, and this compiler\n * reads it. That key is **not** in Prisma's `orderBy` type, so the generated\n * bases — which type `args` as Prisma's own — cannot accept it from application\n * code. It is reachable only from the policy pass, which is the only thing that\n * should produce it.\n */\n\nexport interface RelationOrdering {\n expression: Fragment;\n direction: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n}\n\nexport function relationOrderExpression(\n schema: ModelSchema,\n relation: RelationSchema,\n value: unknown,\n operation: string,\n dialect: SqlDialect,\n locate: (args: any) => any,\n index: number,\n): RelationOrdering {\n const path = `orderBy.${relation.name}`;\n\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new InvalidArgumentError(\n path,\n schema.name,\n operation,\n relation.kind === \"many\"\n ? `Expected { _count: \"asc\" | \"desc\" }.`\n : `Expected an object naming one field of ${relation.model}.`,\n );\n }\n\n const node = value as Record<string, unknown>;\n // `where` is the policy walk's, not the caller's — see the note above.\n const keys = Object.keys(node).filter((key) => key !== \"where\");\n\n if (keys.length !== 1) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n keys.length === 0\n ? `Name the field to order by.`\n : `Name exactly one field to order by; got ${keys.join(\", \")}. ` +\n `Order by several with an array: [{ a: … }, { b: … }].`,\n );\n }\n\n const [key] = keys;\n const source = correlate(\n schema,\n relation,\n dialect,\n `_o${index}`,\n `${dialect.quoteIdent(schema.table)}.`,\n operation,\n );\n\n const selected = projection(\n schema,\n relation,\n source.child,\n key,\n node[key],\n operation,\n source.qualifier,\n dialect,\n );\n\n const filter = compileWhere(\n source.child,\n node.where,\n { dialect, operation, qualifier: source.qualifier },\n (args) => locate(args)?.where,\n );\n\n const parts: Fragment[] = [\n sql(\n `(select ${selected.expression} from ${source.source} ` +\n `where ${source.correlation}`,\n ),\n ];\n if (filter) parts.push(sql(\" and \"), filter);\n parts.push(sql(\")\"));\n\n return {\n expression: concat(...parts),\n direction: selected.direction,\n nulls: selected.nulls,\n };\n}\n\n/**\n * What the subquery selects, and which way it sorts.\n *\n * A to-many can only be ordered by `_count`; a to-one only by one of its own\n * fields. Both refuse the other's form rather than reinterpreting it — ordering\n * a to-one by `_count` would be ordering by 0 or 1, and ordering a to-many by a\n * field has no single answer for a parent with several children.\n */\nfunction projection(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n key: string,\n value: unknown,\n operation: string,\n qualifier: string,\n dialect: SqlDialect,\n): { expression: string; direction: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" } {\n const path = `orderBy.${relation.name}.${key}`;\n const { direction, nulls } = readDirection(schema, path, value, operation);\n\n if (key === COUNT_KEY) {\n if (relation.kind !== \"many\") {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n `${relation.name} is a to-one relation, so its count is 0 or 1. ` +\n `Order by one of ${child.name}'s fields instead.`,\n );\n }\n return { expression: \"count(*)\", direction, nulls };\n }\n\n if (relation.kind === \"many\") {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n `${relation.name} is a to-many relation, so ordering by '${key}' has no ` +\n `single answer for a parent with several children. Only ` +\n `{ _count: … } is supported.`,\n );\n }\n\n const field = child.fields[key];\n if (!field) {\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n `'${key}' is not a field on ${child.name}. Known fields: ` +\n `${Object.keys(child.fields).join(\", \")}.`,\n );\n }\n\n return {\n expression: `${qualifier}${dialect.quoteIdent(field.column)}`,\n direction,\n nulls,\n };\n}\n\n/** The same three forms `parseOrderBy` accepts for a column. */\nfunction readDirection(\n schema: ModelSchema,\n path: string,\n value: unknown,\n operation: string,\n): { direction: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" } {\n if (value === \"asc\" || value === \"desc\") return { direction: value };\n\n if (typeof value === \"object\" && value !== null) {\n const { sort, nulls } = value as Record<string, unknown>;\n if (sort !== \"asc\" && sort !== \"desc\") {\n throw new InvalidArgumentError(\n path,\n schema.name,\n operation,\n 'Expected \"asc\" or \"desc\".',\n );\n }\n if (nulls === undefined) return { direction: sort };\n if (nulls !== \"first\" && nulls !== \"last\") {\n throw new UnsupportedQueryError(\n `${path}.nulls`,\n schema.name,\n operation,\n 'Expected \"first\" or \"last\".',\n );\n }\n return { direction: sort, nulls };\n }\n\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n 'Expected \"asc\", \"desc\", or { sort, nulls }.',\n );\n}\n\n",
|
|
10
10
|
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownFieldError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport type { ModelSchema } from \"../schema\";\nimport { type Fragment, joinFragments, sql } from \"./fragment\";\nimport { relationOrderExpression } from \"./order-relation\";\n\n// Nothing in an `orderBy` is ever a parameter: a column name comes from the\n// schema and a direction is a closed set of two words. Both are structural, so\n// both belong in the plan key and neither may come from user input unchecked.\n\nconst DIRECTIONS = new Set([\"asc\", \"desc\"]);\nconst NULLS = new Set([\"first\", \"last\"]);\n\nexport interface OrderTerm {\n column: string;\n direction: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n /**\n * A compiled expression to order by, instead of the column.\n *\n * Present only for a relation ordering — `orderBy: { organization: { name:\n * \"asc\" } }` — which is a correlated subquery rather than a column, and the\n * first ordering term that can carry a *parameter* (the scope a policy put on\n * the related model). `column` stays populated as a label so the term is still\n * readable in a debugger and so `reverse()` needs no special case.\n */\n expression?: Fragment;\n}\n\n/**\n * What a relation ordering needs that a column ordering does not: a dialect to\n * quote with, and the path back into the argument tree for the scope's binders.\n *\n * Optional, and absent means relation orderings are refused with the message\n * they had before. The only caller that omits it is one compiling a *child*\n * query inside a strategy, where the relation would be a third level and the\n * planner has not been asked for one.\n */\nexport interface OrderContext {\n dialect: SqlDialect;\n /** Re-locates this `orderBy` inside the arguments at bind time. */\n locate: (args: any) => any;\n}\n\n/**\n * Parses Prisma's three accepted forms into terms:\n * `{ id: \"asc\" }`, `[{ a: \"asc\" }, { b: \"desc\" }]`, and the\n * `{ name: { sort: \"asc\", nulls: \"last\" } }` long form.\n */\nexport function parseOrderBy(\n schema: ModelSchema,\n orderBy: unknown,\n operation: string,\n context?: OrderContext,\n): OrderTerm[] {\n if (orderBy === undefined || orderBy === null) return [];\n\n const array = Array.isArray(orderBy);\n const entries = array ? orderBy : [orderBy];\n const terms: OrderTerm[] = [];\n\n for (let index = 0; index < entries.length; index++) {\n const entry = entries[index];\n /**\n * Where *this* entry sits, for a relation ordering's binders.\n *\n * The array form has to be indexed and the object form must not be — and\n * this is a place where getting it wrong is silent, because a scope's\n * parameters would simply bind `undefined` and the ordering would still\n * produce SQL.\n */\n const entryAt = (args: any) => {\n const found = context?.locate(args);\n return array ? found?.[index] : found;\n };\n if (typeof entry !== \"object\" || entry === null) {\n throw new InvalidArgumentError(\n \"orderBy\",\n schema.name,\n operation,\n \"Expected an object or an array of objects.\",\n );\n }\n\n // Insertion order, deliberately unsorted: unlike a `where`, the order of an\n // `orderBy`'s keys is semantic — it is the sort precedence.\n for (const [key, value] of Object.entries(entry)) {\n if (value === undefined) continue;\n\n if (key in schema.relations) {\n if (!context) {\n throw new UnsupportedQueryError(\n `orderBy.${key}`,\n schema.name,\n operation,\n \"Ordering by a relation is not implemented here.\",\n );\n }\n\n const ordered = relationOrderExpression(\n schema,\n schema.relations[key],\n value,\n operation,\n context.dialect,\n (args: any) => entryAt(args)?.[key],\n terms.length,\n );\n\n terms.push({\n column: key,\n direction: ordered.direction,\n ...(ordered.nulls ? { nulls: ordered.nulls } : {}),\n expression: ordered.expression,\n });\n continue;\n }\n\n const field = schema.fields[key];\n if (!field) {\n throw new UnknownFieldError(\n key,\n schema.name,\n Object.keys(schema.fields),\n );\n }\n\n terms.push({\n column: field.column,\n ...parseDirection(schema, key, value, operation),\n });\n }\n }\n\n return terms;\n}\n\nfunction parseDirection(\n schema: ModelSchema,\n key: string,\n value: unknown,\n operation: string,\n): { direction: \"asc\" | \"desc\"; nulls?: \"first\" | \"last\" } {\n if (typeof value === \"string\") {\n if (!DIRECTIONS.has(value)) {\n throw new InvalidArgumentError(\n `orderBy.${key}: ${JSON.stringify(value)}`,\n schema.name,\n operation,\n 'Expected \"asc\" or \"desc\".',\n );\n }\n return { direction: value as \"asc\" | \"desc\" };\n }\n\n if (typeof value === \"object\" && value !== null) {\n const { sort, nulls } = value as Record<string, unknown>;\n const direction = parseDirection(schema, key, sort, operation).direction;\n\n if (nulls === undefined) return { direction };\n if (typeof nulls !== \"string\" || !NULLS.has(nulls)) {\n throw new UnsupportedQueryError(\n `orderBy.${key}.nulls: ${JSON.stringify(nulls)}`,\n schema.name,\n operation,\n 'Expected \"first\" or \"last\".',\n );\n }\n return { direction, nulls: nulls as \"first\" | \"last\" };\n }\n\n throw new UnsupportedQueryError(\n `orderBy.${key}`,\n schema.name,\n operation,\n 'Expected \"asc\", \"desc\", or { sort, nulls }.',\n );\n}\n\n/** Flips every term. This is how Prisma reads a negative `take`. */\nexport function reverse(terms: OrderTerm[]): OrderTerm[] {\n return terms.map((term) => ({\n ...term,\n direction: term.direction === \"asc\" ? \"desc\" : \"asc\",\n ...(term.nulls\n ? { nulls: term.nulls === \"first\" ? (\"last\" as const) : (\"first\" as const) }\n : {}),\n }));\n}\n\nexport function compileOrderBy(\n terms: OrderTerm[],\n dialect: SqlDialect,\n /**\n * Prefix for every column — `\"User\".` — when the statement has a second table\n * in scope. See `WhereContext.qualifier`; absent is the common case and emits\n * byte-identical SQL to what it did before this existed.\n */\n qualifier?: string,\n): Fragment | null {\n if (terms.length === 0) return null;\n\n // `nulls first` / `nulls last` is used directly on both dialects. Prisma\n // emits a `CASE WHEN ... IS NULL` expression on SQLite instead, which dates\n // from before SQLite 3.30 — it has understood the standard syntax since, and\n // Bun bundles 3.51.\n return joinFragments(\n terms.map((term) => {\n const suffix =\n ` ${term.direction}` + (term.nulls ? ` nulls ${term.nulls}` : \"\");\n\n // A relation ordering brings its own expression — and its own parameters,\n // which is why this is a `Fragment` rather than a string.\n if (term.expression) {\n return joinFragments([term.expression, sql(suffix)], \"\");\n }\n\n return sql(\n `${qualifier ?? \"\"}${dialect.quoteIdent(term.column)}${suffix}`,\n );\n }),\n \", \",\n );\n}\n",
|
|
11
11
|
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n} from \"../errors\";\nimport type { ModelSchema } from \"../schema\";\nimport type { Binder, Fragment } from \"./fragment\";\nimport { reverse, type OrderTerm } from \"./orderBy\";\n\n/**\n * `take` / `skip` have to be integers, and Prisma is stricter than \"a number\":\n * a `skip` counts rows to pass over, so a negative one is meaningless and is\n * rejected rather than clamped. A negative *`take`* is not — it means \"the last\n * N\".\n *\n * **Why refusing rather than coercing**, which is the cheaper fix and the wrong\n * one. The sign of a `take` decides the *SQL*: it flips every ordering term and\n * reverses the result set. Everything else about these two arguments is a bound\n * value. So a `take` that is a string does not merely arrive in the wrong type —\n * it takes the wrong branch, because the branch is `typeof take === \"number\" &&\n * take < 0` and a string is not a number:\n *\n * { take: -2 } -> order flipped, bind 2 the last two rows\n * { take: \"-2\" } -> order as written, bind 2 the *first* two rows\n *\n * `Math.abs(Number(...))` then binds `2` either way, so the statement is valid,\n * the result set is the right size, and the rows are wrong. No error anywhere.\n *\n * Coercing early would fix that one case — `Number(\"-2\")` is negative — and\n * would keep accepting `take: \"abc\"`, which binds `NaN`. Prisma types these as\n * `number` and rejects a string outright, and #72 already chose refusal for the\n * same arguments on a *relation* node. This is that decision reaching the root,\n * where it should have been in the first place.\n *\n * **A fraction is the one deliberate divergence, and it is deliberate because\n * of what the alternative measures at.** Prisma accepts `take: 1.5` and\n * truncates toward zero. Binding it, which is what this did, does not:\n *\n * prisma take: 1.5 -> 1 row truncates\n * sqlite limit ? = 1.5 -> SQLiteError: datatype mismatch (SQLITE_MISMATCH)\n * postgres limit $1 = 1.5 -> 2 rows rounds to nearest\n *\n * Measured through Bun against both engines. So the status quo is an opaque\n * driver error on one dialect and a silent disagreement with Prisma *and* with\n * the other dialect on the second — from one argument, with no line naming\n * `take`. Matching Prisma would mean truncating here and also changing #72's\n * relation-node rule, which refuses fractions today; refusing keeps one rule at\n * both levels and fails in the loud direction. `docs/orm.md` records it as a\n * divergence rather than leaving it to be discovered.\n *\n * `argument` is the name to report: `take` at the root, `accounts.take` on a\n * relation node.\n *\n * **`InvalidArgumentError`, and this note is what asked for it.** #88 left the\n * error type deliberately wrong here — `UnsupportedQueryError` spells \"does not\n * support 'take' *yet*\", and there is no future in which `take: \"-2\"` becomes\n * supported — on the reasoning that validation is a *category* rather than a\n * reworded string, and that inventing one while #78 was in flight would be the\n * second copy this function exists to avoid.\n *\n * #78 landed `UnsupportedByDesignError` for \"a decision rather than a gap\", and\n * the third class followed it. A bad value now says `Invalid 'take'` and says\n * what a good one looks like, which is the whole of what was owed.\n */\nexport function assertPageArgument(\n model: string,\n operation: string,\n argument: string,\n key: \"take\" | \"skip\",\n value: unknown,\n): void {\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n throw new InvalidArgumentError(\n argument,\n model,\n operation,\n `Expected an integer, got ${JSON.stringify(value)}.`,\n );\n }\n if (key === \"skip\" && value < 0) {\n throw new InvalidArgumentError(\n argument,\n model,\n operation,\n `A 'skip' counts rows to pass over, so it cannot be negative. Prisma ` +\n `rejects one too.`,\n );\n }\n}\n\n/**\n * `skip` / `take`, plus the two pieces of Prisma behaviour around them that are\n * invisible until you read the SQL it emits:\n *\n * - Paginating without an `orderBy` injects `order by <primary key> asc`.\n * Without it, \"page 2\" is only meaningful if the storage engine happens to\n * return a stable order, which is not guaranteed on either dialect.\n * - A *negative* `take` means \"the last N\": Prisma flips every ordering term,\n * takes `abs(take)`, and then reverses the result set so the caller still\n * sees their own ordering. `reversed` carries that last part out to `shape`.\n *\n * **Validation happens here rather than in each caller's argument check.** Three\n * operations page — `findMany` and friends, `count`, `aggregate` — and they\n * validate their arguments in two different files. Putting the check at the one\n * place that *reads* `take` and `skip` means a fourth pager cannot be added\n * without it, which is the same reason invariant 1 puts every query through one\n * door.\n */\nexport function pagination(\n schema: ModelSchema,\n /**\n * The operation being compiled, for the error message. Required rather than\n * defaulted: this exists to report which call was refused, and a default\n * would name the wrong one on every caller that forgot it.\n */\n operation: string,\n args: any,\n dialect: SqlDialect,\n parsed: OrderTerm[],\n /**\n * Whether the operation returns at most one row, which pins `take` to 1\n * whatever the arguments say. Passed rather than derived from the operation\n * name, so this module needs to know nothing about which operations exist —\n * which is also what keeps `read.ts` and `aggregate.ts` from importing each\n * other to share it.\n */\n single = false,\n): { clause: Fragment; terms: OrderTerm[]; reversed: boolean } {\n // Against the caller's own arguments, before `single` pins anything. A\n // `findFirst` ignores the value of `take` — but it still accepts the\n // argument, and Prisma still rejects a string there, so refusing what was\n // written beats refusing what survived.\n if (args?.take !== undefined) {\n assertPageArgument(schema.name, operation, \"take\", \"take\", args.take);\n }\n if (args?.skip !== undefined) {\n assertPageArgument(schema.name, operation, \"skip\", \"skip\", args.skip);\n }\n\n const take = single ? 1 : args?.take;\n const skip = args?.skip;\n\n let terms = parsed;\n const paginating = take !== undefined || skip !== undefined;\n\n if (paginating && terms.length === 0 && !single) {\n terms = schema.primaryKey.map((name) => ({\n column: schema.fields[name]?.column ?? name,\n direction: \"asc\" as const,\n }));\n }\n\n const negative = typeof take === \"number\" && take < 0;\n if (negative) terms = reverse(terms);\n\n const takeBinder: Binder | null =\n take === undefined\n ? null\n : single\n ? () => 1\n : (callArgs: any) => Math.abs(Number(callArgs?.take));\n\n const skipBinder: Binder | null =\n skip === undefined ? null : (callArgs: any) => Number(callArgs?.skip);\n\n return {\n clause: dialect.paginate(takeBinder, skipBinder),\n terms,\n reversed: negative,\n };\n}\n",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"import {\n NANOID_DEFAULT_LENGTH,\n type DefaultKind,\n type DefaultSpec,\n type FieldSchema,\n} from \"./schema\";\n\n/**\n * The values gemi supplies itself on a write, rather than leaving to the\n * database.\n *\n * Which defaults have to be client-side is not a style question — it is forced\n * by the DDL Prisma emits. Reading the template's own migration:\n *\n * ```sql\n * \"publicId\" TEXT NOT NULL, -- @default(cuid())\n * \"createdAt\" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- @default(now())\n * \"updatedAt\" DATETIME NOT NULL, -- @updatedAt\n * ```\n *\n * - `publicId` and `updatedAt` carry **no database default at all**. Prisma\n * generates them in the client, so a row inserted without them violates a\n * NOT NULL constraint. Missing `@updatedAt` on *create* is the quiet version\n * of this bug: the column is only nullable on models where Prisma made it so.\n * `@default(nanoid())` is the same column with a different generator on it,\n * and was on the wrong side of this split until #350 — classified\n * `dbgenerated`, so the ORM omitted the column and the driver rejected the\n * row.\n *\n * **Prisma's client registers four of these, not three.** Its generator\n * registry reads `register(\"uuid\") register(\"cuid\") register(\"ulid\")\n * register(\"nanoid\")`, and `prisma migrate diff` gives every one of them a\n * `TEXT NOT NULL` with no `DEFAULT`. #350's first fix said \"three\" and left\n * `ulid` falling through to `dbgenerated` — the same bug, one function over,\n * which is what its review caught. All four are here now.\n * - `createdAt` does have a default, but it is `CURRENT_TIMESTAMP`, which SQLite\n * stores as the *text* `YYYY-MM-DD HH:MM:SS` — while Prisma stores a DateTime\n * as integer milliseconds. Letting the database fill it would write a\n * different storage form than Prisma writes, and drop sub-second precision.\n *\n * `autoincrement()` and `dbgenerated(...)` stay with the database, which is the\n * whole of the other side of this split.\n *\n * Verified against Prisma 6.19.2 rather than assumed: a `create` there returns\n * `createdAt` and `updatedAt` as the *same instant*, which is why `now` is\n * resolved once per logical operation and passed in rather than read per field.\n */\n\n/**\n * The kinds gemi supplies a value for, as an allowlist.\n *\n * **It was a denylist** — `kind !== \"autoincrement\" && kind !== \"dbgenerated\"`\n * — and the difference is what a *future* kind does on a runtime that predates\n * it. A denylist says \"yes, gemi supplies this\" for a kind it cannot generate,\n * so the column joins the insert and `clientSideValue` hands back `undefined`,\n * which the dialect encodes as **NULL**. A nullable column then takes NULL on\n * every row, silently, where an id belonged.\n *\n * An allowlist answers \"no\" instead, so the column is omitted and the database\n * decides — a NOT NULL violation where it matters, and nothing where it does\n * not. `SCHEMA_ARTIFACT_VERSION` should catch that skew first; this is what\n * makes it loud if it ever does not.\n *\n * Every member must have an arm in `clientSideValue`, which the exhaustive\n * `Record<DefaultKind, boolean>` in the tests is there to hold.\n */\nconst CLIENT_SIDE_KINDS: ReadonlySet<DefaultKind> = new Set<DefaultKind>([\n \"cuid\",\n \"uuid\",\n \"nanoid\",\n \"ulid\",\n \"now\",\n \"value\",\n]);\n\n/** Whether gemi supplies this default, or leaves the column to the database. */\nexport function isClientSideDefault(spec: DefaultSpec): boolean {\n return CLIENT_SIDE_KINDS.has(spec.kind);\n}\n\n/**\n * A field gemi must supply a value for when the caller did not: either it has a\n * client-side default, or it is `@updatedAt`, which Prisma sets on create as\n * well as on update.\n */\nexport function hasClientSideValue(field: FieldSchema): boolean {\n if (field.isUpdatedAt) return true;\n return field.default !== undefined && isClientSideDefault(field.default);\n}\n\n/**\n * The value for one field on one row. `now` is shared across every field and\n * every row of a single operation; everything else is generated per call.\n */\nexport function clientSideValue(field: FieldSchema, now: Date): unknown {\n // `@updatedAt` wins over any `@default`: Prisma stamps it on every write,\n // which is the entire point of the attribute.\n if (field.isUpdatedAt) return now;\n\n const spec = field.default;\n if (!spec) return undefined;\n\n switch (spec.kind) {\n case \"cuid\":\n // v1 only. `cuid(2)` is refused by the generator rather than recorded,\n // because gemi cannot reproduce `@paralleldrive/cuid2`'s output — see\n // `emit.ts`. So no artifact reaches here carrying a cuid version.\n return createCuid();\n case \"uuid\":\n // Absent means 4, which is what a bare `uuid()` has always meant. The\n // DMMF in fact normalises `uuid()` to `args: [4]`, so the generator\n // always records it; the fallback is for a hand-written spec.\n return createUuid(spec.version ?? 4);\n case \"nanoid\":\n // Likewise: the generator always records the length, so the fallback is\n // for a hand-written spec. 21 is what `nanoid()` means.\n return createNanoid(spec.length ?? NANOID_DEFAULT_LENGTH);\n case \"ulid\":\n return createUlid();\n case \"now\":\n return now;\n case \"value\":\n return spec.value;\n default:\n // autoincrement / dbgenerated — the database's business.\n return undefined;\n }\n}\n\n// --- random symbols --------------------------------------------------------\n\n/**\n * `size` symbols drawn uniformly from `alphabet`.\n *\n * The one place the uniformity argument lives, because it is the same argument\n * for every id below and it used to be made twice, half in `randomBlock`'s\n * comment and half in `createNanoid`'s.\n *\n * A byte is a draw from 256, and 256 is a multiple of the alphabet's size only\n * when that size is a power of two. When it is not, `byte % size` would favour\n * the first `256 % size` symbols — for cuid's 36 that is the first four,\n * delivered 8 times in 256 against everyone else's 7, which is 12.5% above\n * uniform and invisible in any single id. `limit` cuts the tail that causes it\n * and those bytes are redrawn.\n *\n * For a 64-symbol alphabet `256 % 64` is 0, so `limit` is 256, the loop never\n * rejects, and this is exactly the `& 63` mask nanoid ships — reached by\n * arithmetic rather than by special-casing it.\n */\nfunction randomChars(alphabet: string, size: number): string {\n const base = alphabet.length;\n const limit = 256 - (256 % base);\n\n const bytes = new Uint8Array(size);\n crypto.getRandomValues(bytes);\n\n let out = \"\";\n for (let i = 0; i < size; i++) {\n let byte = bytes[i];\n while (byte >= limit) {\n const resample = new Uint8Array(1);\n crypto.getRandomValues(resample);\n byte = resample[0];\n }\n out += alphabet[byte % base];\n }\n return out;\n}\n\n// --- cuid v1 ---------------------------------------------------------------\n\n// The format Prisma 6.19.2 actually emits for `@default(cuid())`, read off real\n// rows rather than taken from the docs:\n//\n// cms3j09fa0000a0452l77tbma\n// c ms3j09fa 0000 a045 2l77tbma\n// ^ ^ ^ ^ ^\n// | | | fingerprint random\n// | | counter\n// | timestamp, base 36\n// literal 'c'\n//\n// 25 characters, lowercase alphanumeric. Prisma's `cuid()` is still v1; `cuid2`\n// is a separate, opt-in generator with a different shape, so matching v1 is what\n// keeps a gemi-written `publicId` indistinguishable from a Prisma-written one in\n// length, prefix and charset.\n\nconst ALPHABET = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nconst BASE = 36;\nconst BLOCK_SIZE = 4;\nconst DISCRETE_VALUES = BASE ** BLOCK_SIZE;\n\n/**\n * Monotonic within a process, rolling over at one block's worth of values. It\n * is what keeps two cuids minted in the same millisecond distinct, so it must\n * not be reset or made per-call.\n */\nlet counter = 0;\n\nfunction pad(text: string, size: number): string {\n return text.length >= size ? text : \"0\".repeat(size - text.length) + text;\n}\n\n/**\n * cuid v1 derives this from the process id and the hostname, to keep two\n * processes minting concurrently from colliding.\n *\n * gemi uses a random block generated once per process instead. It fills exactly\n * the same role with strictly better collision behaviour — containers routinely\n * share both a hostname and a low pid — and it keeps `node:os` off the ORM\n * runtime's import graph. Nothing observable changes: the fingerprint is four\n * characters of the same alphabet in the same position, and nothing parses it.\n */\nconst FINGERPRINT = randomBlock();\n\n/** One four-character block of cuid's base-36 alphabet. */\nfunction randomBlock(): string {\n return randomChars(ALPHABET, BLOCK_SIZE);\n}\n\nexport function createCuid(): string {\n const timestamp = Date.now().toString(BASE);\n const count = pad((counter++ % DISCRETE_VALUES).toString(BASE), BLOCK_SIZE);\n return `c${timestamp}${count}${FINGERPRINT}${randomBlock()}${randomBlock()}`;\n}\n\n// --- nanoid ----------------------------------------------------------------\n\n/**\n * The alphabet, verbatim from the `nanoid` package Prisma bundles. Its order is\n * not alphabetical and not arbitrary — it is what the library ships, and an id\n * is a uniform draw from it, so a reordering changes nothing observable. It is\n * copied exactly anyway, because \"the same alphabet\" is the property.\n *\n * 64 characters, so `randomChars` computes a `limit` of 256 for it and never\n * rejects a byte — the same draw as nanoid's own `& 63`.\n */\nconst NANOID_ALPHABET =\n \"useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict\";\n\n/**\n * The id `@default(nanoid(size))` produces in the Prisma client, generated here\n * instead — same alphabet, same length, so a gemi-written column and a\n * Prisma-written one are indistinguishable.\n *\n * Unlike a cuid there is no structure to match: a nanoid is `size` independent\n * symbols and nothing more. No timestamp, no counter, no fingerprint — which is\n * also why none of the collision reasoning around `createCuid` applies here.\n */\nexport function createNanoid(size: number = NANOID_DEFAULT_LENGTH): string {\n return randomChars(NANOID_ALPHABET, size);\n}\n\n// --- ulid ------------------------------------------------------------------\n\n/**\n * Crockford's base32: the digits and the uppercase letters, less `I`, `L`, `O`\n * and `U` — the four that are misread as `1`, `1`, `0` and each other. Copied\n * from the string Prisma's client ships, which is the canonical one.\n *\n * 32 symbols, a power of two, so `randomChars` never rejects a byte here\n * either.\n */\nconst ULID_ALPHABET = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\n/** 48 bits of milliseconds, base 32. */\nconst ULID_TIME_CHARS = 10;\n/** 80 bits of randomness, base 32 — the width Prisma's generator uses. */\nconst ULID_RANDOM_CHARS = 16;\n\n/**\n * `@default(ulid())`, which #350's first fix missed: it never had a `case`, so\n * it fell through to `dbgenerated` and the column was omitted from every insert\n * — the same bug the fix was written for, on a fourth id function.\n *\n * A ULID is a timestamp followed by randomness, and the *order* is the point:\n * the time is big-endian and base 32 preserves byte order, so sorting ULIDs\n * lexicographically sorts them by creation time. That is why the timestamp is\n * built here digit by digit rather than through `toString(32)`, which would\n * emit a variable number of characters and destroy the alignment the ordering\n * depends on.\n */\nexport function createUlid(now: number = Date.now()): string {\n let time = \"\";\n let remaining = now;\n for (let i = 0; i < ULID_TIME_CHARS; i++) {\n time = ULID_ALPHABET[remaining % 32] + time;\n remaining = Math.floor(remaining / 32);\n }\n\n return time + randomChars(ULID_ALPHABET, ULID_RANDOM_CHARS);\n}\n\n// --- uuid ------------------------------------------------------------------\n\n/**\n * `@default(uuid(v))`. Prisma's client accepts 4 and 7 and throws on anything\n * else; the generator refuses the rest before an artifact can carry it, so this\n * only ever sees those two.\n *\n * **The version is not cosmetic**, which is why it had to travel with the spec.\n * A v4 is 122 random bits. A v7 puts 48 bits of big-endian milliseconds at the\n * front, so v7s sort by creation time and land next to each other in a B-tree —\n * the entire reason a schema asks for one. Minting a v4 where the schema said 7\n * loses both properties and leaves a column that still looks like a UUID, which\n * is how it went unnoticed.\n */\nexport function createUuid(version: number = 4): string {\n return version === 7 ? createUuidV7() : crypto.randomUUID();\n}\n\nconst HEX = Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, \"0\"),\n);\n\n/**\n * RFC 9562 §5.7: 48 bits of Unix milliseconds, the 4-bit version `7`, 12 random\n * bits, the 2-bit variant `0b10`, and 62 more random bits.\n *\n * The layout is asserted by the tests rather than trusted, because every field\n * but the timestamp is invisible in a rendered UUID.\n *\n * The ordering this buys is **per millisecond**. Everything after the timestamp\n * is random, so two ids minted in the same millisecond have no defined order\n * between them; §6.2's monotonic counter is what would fix that, and neither\n * Prisma's generator nor this one implements it. Sorting by a v7 orders rows by\n * the millisecond they were written, which is the property an index cares about.\n */\nfunction createUuidV7(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n\n const now = Date.now();\n // Big-endian, and `Math.floor(now / 2 ** 32)` rather than a shift: `>>>`\n // truncates to 32 bits, and the timestamp needs 48.\n bytes[0] = Math.floor(now / 2 ** 40) & 0xff;\n bytes[1] = Math.floor(now / 2 ** 32) & 0xff;\n bytes[2] = (now >>> 24) & 0xff;\n bytes[3] = (now >>> 16) & 0xff;\n bytes[4] = (now >>> 8) & 0xff;\n bytes[5] = now & 0xff;\n\n bytes[6] = (bytes[6] & 0x0f) | 0x70; // version 7, keeping the random low bits\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 0b10, likewise\n\n const hex = HEX;\n return (\n hex[bytes[0]] + hex[bytes[1]] + hex[bytes[2]] + hex[bytes[3]] +\n \"-\" + hex[bytes[4]] + hex[bytes[5]] +\n \"-\" + hex[bytes[6]] + hex[bytes[7]] +\n \"-\" + hex[bytes[8]] + hex[bytes[9]] +\n \"-\" + hex[bytes[10]] + hex[bytes[11]] + hex[bytes[12]] +\n hex[bytes[13]] + hex[bytes[14]] + hex[bytes[15]]\n );\n}\n",
|
|
18
18
|
"import type { SqlDialect } from \"./dialect\";\nimport type { FieldSchema } from \"./schema\";\n\n/**\n * Turns driver rows into the POJOs the caller sees. Built once per compiled\n * plan and closed over a fixed column list, so the hot loop does no per-row\n * schema lookups, no `for...in`, and no per-value type dispatch beyond the one\n * boolean decided at build time.\n *\n * This is a plain function today. `Model.$shape` is the static that calls it\n * (invariant 3), which is the seam a future `ActiveRecordModel` overrides to\n * build instances instead, and the seam iteration 8 hangs row provenance on.\n *\n * There are **two implementations**, and which one runs is decided once per\n * process — see `buildRowShaper`. Iteration 7 measured the difference at 3.4× on\n * a 1000-row read, roughly a third of that whole query, and that number is the\n * only reason the second one exists.\n */\nexport type RowShaper = (rows: unknown[]) => Record<string, unknown>[];\n\ninterface ShapedColumn {\n /** Key on the returned object — the Prisma field name. */\n key: string;\n /** Key on the driver row — the database column name. */\n column: string;\n field: FieldSchema;\n decode: boolean;\n}\n\n/**\n * One relation the plan will load. The shaper does not fetch anything; it\n * writes the *empty* value so the key exists on every row before the relation\n * loader fills in the rows that have children.\n *\n * These three lines are where most divergence bugs live, so they are stated\n * once, here: a to-one with no match is `null` — not `undefined`, not a missing\n * key — and an empty to-many is `[]` — not `null`, not absent. Prisma returns\n * exactly that, and the differential harness compares key presence.\n */\nexport interface ShapedRelation {\n key: string;\n kind: \"one\" | \"many\";\n}\n\n/**\n * Whether this runtime allows compiling a function from source.\n *\n * Probed once, at module load, by doing it. `new Function` is unavailable under\n * a strict Content-Security-Policy and on some edge runtimes, and the failure is\n * a throw at *construction* — so asking is the only way to know, and asking once\n * is better than a try/catch per compiled plan.\n */\nconst CAN_COMPILE = (() => {\n try {\n return new Function(\"return 1\")() === 1;\n } catch {\n return false;\n }\n})();\n\nlet compilationEnabled = true;\n\n/**\n * Forces the interpreted shaper.\n *\n * Exported because the two implementations must produce *identical* output, and\n * a test can only assert that if it can obtain both. That test is what stands\n * between this optimisation and a shape divergence visible only in production.\n */\nexport function setShaperCompilation(enabled: boolean): void {\n compilationEnabled = enabled;\n}\n\nexport function shaperCompilationAvailable(): boolean {\n return CAN_COMPILE;\n}\n\nexport function buildRowShaper(\n fields: FieldSchema[],\n dialect: SqlDialect,\n relations: readonly ShapedRelation[] = [],\n): RowShaper {\n if (CAN_COMPILE && compilationEnabled) {\n return buildCompiledShaper(fields, dialect, relations);\n }\n return buildInterpretedShaper(fields, dialect, relations);\n}\n\n/**\n * The portable implementation: a closure over the column list, assigning keys\n * dynamically.\n *\n * Kept as the fallback rather than deleted, and not dead code — it runs wherever\n * `new Function` is refused, and it is the reference the compiled one is\n * asserted equal to.\n */\nexport function buildInterpretedShaper(\n fields: FieldSchema[],\n dialect: SqlDialect,\n relations: readonly ShapedRelation[] = [],\n): RowShaper {\n const columns: ShapedColumn[] = fields.map((field) => ({\n key: field.name,\n column: field.column,\n field,\n decode: dialect.needsDecode(field),\n }));\n const width = columns.length;\n\n // Flattened to `(key, many)` pairs at build time for the same reason the\n // columns are: the per-row loop does no property lookups it can avoid, and\n // the common case — no relations — costs one comparison against zero.\n const related = relations.map((relation) => ({\n key: relation.key,\n many: relation.kind === \"many\",\n }));\n const relatedCount = related.length;\n\n return (rows: unknown[]) => {\n // Grown by `push` rather than preallocated: `new Array(n)` produces a holey\n // array, which is the slower of the two to write into.\n const out: Record<string, unknown>[] = [];\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i] as Record<string, unknown>;\n const shaped: Record<string, unknown> = {};\n for (let j = 0; j < width; j++) {\n const column = columns[j];\n const value = row[column.column];\n shaped[column.key] = column.decode\n ? dialect.decode(value, column.field)\n : (value ?? null);\n }\n for (let j = 0; j < relatedCount; j++) {\n // A fresh array per row: they are handed to the caller and pushed into\n // by the relation loader, so sharing one would alias every parent's\n // children together.\n shaped[related[j].key] = related[j].many ? [] : null;\n }\n out.push(shaped);\n }\n return out;\n };\n}\n\n/**\n * The fast implementation: a generated function body emitting one object literal\n * with every key spelled out.\n *\n * **Why it is 3.4× faster, since the reason decides what else is worth trying.**\n * Not the property-load indirection — a variant with the column data hoisted\n * into parallel arrays measured 0% different. It is the object's *shape*:\n * `shaped[key] = value` in a loop transitions the hidden class once per\n * property, thirteen times per row on `User`, while a literal with known keys\n * gets one hidden class and one allocation. That is also why there is little\n * further to win here without changing what is returned.\n *\n * Measured on 1000 `User` rows, 13 columns: 187µs interpreted, 55µs compiled,\n * byte-identical output including key order. The comparison is committed at\n * `templates/saas-starter/app/models/bench/shaper.ts` so the claim can be\n * re-run rather than believed.\n *\n * **On generating code.** Every identifier in the emitted source comes from the\n * generated schema — field names and column names — and nothing else, which is\n * the same property that makes the SQL compiler safe. `JSON.stringify` quotes\n * them, so a name containing a quote cannot break out of the literal. This must\n * never widen to anything a caller controls: if a future feature wants a\n * caller-supplied key in the output, it belongs in the interpreted path.\n */\nfunction buildCompiledShaper(\n fields: FieldSchema[],\n dialect: SqlDialect,\n relations: readonly ShapedRelation[],\n): RowShaper {\n const parts: string[] = [];\n\n for (let index = 0; index < fields.length; index++) {\n const field = fields[index];\n const key = JSON.stringify(field.name);\n const column = JSON.stringify(field.column);\n parts.push(\n dialect.needsDecode(field)\n ? `${key}: d.decode(row[${column}], f[${index}])`\n : `${key}: row[${column}] ?? null`,\n );\n }\n\n for (const relation of relations) {\n // Inside the literal, so every row gets its own array — the aliasing hazard\n // the interpreted path comments on is avoided by construction here.\n parts.push(\n `${JSON.stringify(relation.key)}: ${\n relation.kind === \"many\" ? \"[]\" : \"null\"\n }`,\n );\n }\n\n const source = `\n return function shape(rows) {\n const out = [];\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n out.push({ ${parts.join(\", \")} });\n }\n return out;\n };\n `;\n\n try {\n return new Function(\"d\", \"f\", source)(dialect, fields) as RowShaper;\n } catch {\n // `CAN_COMPILE` said yes and this still failed, which would be a schema\n // shape emitting something unparseable — a bug, not an environment. Falling\n // back keeps the query working rather than failing for every caller.\n return buildInterpretedShaper(fields, dialect, relations);\n }\n}\n",
|
|
19
19
|
"import {\n InvalidArgumentError,\n RecordNotFoundError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport type { SqlDialect } from \"../dialect\";\nimport type { ModelSchema, RelationSchema } from \"../schema\";\nimport type { Binder } from \"./fragment\";\nimport {\n type Link,\n type NestedWriteStep,\n type RelationExecutor,\n relatedSchema,\n resolveLink,\n singleFieldLink,\n} from \"./plan-relations\";\nimport { matchUniqueKey, type RefusalOrigin } from \"./unique\";\n\n/**\n * Nested writes: `connect`, `connectOrCreate`, shallow `create`, and\n * `createMany`.\n *\n * Which direction a nested write runs in is decided by *who holds the foreign\n * key*, and the two directions are genuinely different operations:\n *\n * ```ts\n * // this model holds organizationId — resolve the key, then insert once\n * User.create({ data: { email, organization: { connect: { id: 1 } } } })\n *\n * // Account holds userId — insert the user, then insert accounts pointing at it\n * User.create({ data: { email, accounts: { create: [{ ... }] } } })\n * ```\n *\n * The first is a `before` step (or, in the common case, no step at all — just a\n * column read straight out of the argument tree). The second is an `after` step,\n * because the key it needs does not exist until the parent row does.\n *\n * `createMany` is the second shape and only exists on the foreign side: the same\n * rows as a nested `create`, in one statement rather than one per row.\n *\n * The rest of Prisma's nested-write grammar — `set`, `disconnect`, `update`,\n * `upsert`, `delete`, `deleteMany`, `updateMany` — is implemented too, and this\n * paragraph used to say that all seven throw. What is left refused is refused\n * by *shape* rather than by name, at the site that knows why: the four\n * collection operands on a to-one, which Prisma's to-one input does not carry\n * either; `delete` through a key on this row, which would remove a row the\n * statement is not about (#391 left it the only one of the seven still refused\n * on that side); everything in {@link EXISTING_ROW_ONLY_STATEMENTS} under a\n * `create`; and the four that reach the far row *through* an implicit\n * many-to-many's pairs. `REFUSED` — the table this sentence pointed at — is\n * empty, and its docblock says why that is worth reading.\n *\n * **The line this file draws has two halves: which rows an operand can name,\n * and whose columns it writes.**\n *\n * Every supported operand names its rows — a new one, or an existing one the\n * caller identified by unique key — so it goes through the child's own\n * `findUnique`, `create` or `update`, and the child's policies decide whether\n * it is reachable at all. `set`, `disconnect`, `delete`, `deleteMany` and\n * `updateMany` act on rows the *call* did not name, and \"whatever is there\" has\n * no lookup to hang a scope on.\n *\n * `update` is the operand that shows the second half is needed, because it\n * *does* name its row: `update: { where, data }`. It is refused because of what\n * it writes — caller-supplied columns, which need the child's `onUpdate` and\n * the scope-escape guard run over the payload. Every supported operand writes\n * either a whole new row through the child's `create` (where `onCreate`\n * applies) or one foreign key the ORM itself chose.\n *\n * This used to say the line was \"each writes rows that **already exist**\", and\n * that was true until `connectOrCreate` arrived: on the foreign side a hit is\n * an `update` of the child's foreign key, because Prisma repoints the existing\n * row rather than duplicating it. So a supported operand does now write a row\n * that was already there. Restated rather than deleted, because the criterion\n * is what the next operand gets judged against — #75 built the whole `REFUSED`\n * table on it, with a per-entry reason derived from it, and #83's `set` on an\n * implicit many-to-many was fixed by exactly this reading: scope the delete to\n * the rows the caller can see. A stale criterion is worse than none, because it\n * is the one the next reader applies.\n *\n * Atomic since iteration 5: `$exec` opens a transaction for any plan carrying\n * steps, so a nested step that fails — or a child policy that denies — rolls\n * back the parent row too.\n */\n\nconst SUPPORTED_STATEMENTS = [\n \"connect\",\n \"connectOrCreate\",\n \"create\",\n \"createMany\",\n \"disconnect\",\n \"delete\",\n \"update\",\n \"set\",\n \"updateMany\",\n \"deleteMany\",\n \"upsert\",\n] as const;\n\n/**\n * One of {@link SUPPORTED_STATEMENTS}.\n *\n * `NestedCreate` and `NestedUpdate` in `../types` are mapped types over this\n * and the two tuples below, rather than four hand-written key lists in another\n * file. Which statements exist, and which exist only on a to-many or only on a\n * statement with a row to act on, are decisions made *here* — and until #369\n * the caller-facing type made them a second time, with nothing checking that\n * the two answers matched.\n */\nexport type NestedWriteStatement = (typeof SUPPORTED_STATEMENTS)[number];\n\nconst SUPPORTED: ReadonlySet<string> = new Set(SUPPORTED_STATEMENTS);\n\n/**\n * Operands that only exist on a statement with a row to act on.\n *\n * Prisma refuses `disconnect` and `delete` under a `create` — *\"Unknown\n * argument `disconnect`\"* — and it is right to: there is nothing linked to a\n * row that does not exist yet. Refused here rather than accepted and made a\n * no-op, so a caller who wrote one on the wrong operation hears about it.\n */\nconst EXISTING_ROW_ONLY_STATEMENTS = [\n \"disconnect\",\n \"delete\",\n \"update\",\n \"set\",\n \"updateMany\",\n \"deleteMany\",\n \"upsert\",\n] as const;\n\n/** One of {@link EXISTING_ROW_ONLY_STATEMENTS}. `NestedCreate` subtracts it. */\nexport type ExistingRowStatement = (typeof EXISTING_ROW_ONLY_STATEMENTS)[number];\n\nconst EXISTING_ROW_ONLY: ReadonlySet<string> = new Set(\n EXISTING_ROW_ONLY_STATEMENTS,\n);\n\n/**\n * The operands that describe *many* rows, and so exist on a to-many alone.\n *\n * Prisma's to-one nested input is `{ create, connectOrCreate, upsert,\n * disconnect, delete, connect, update }` — measured off a generated client —\n * with no `createMany`, `set`, `updateMany` or `deleteMany` key at all. Both\n * {@link planOwningSide} and {@link planForeignSide} refuse all four on a\n * to-one; this is the list they refuse, named once so the type can subtract it.\n */\nconst COLLECTION_ONLY_STATEMENTS = [\n \"createMany\",\n \"set\",\n \"updateMany\",\n \"deleteMany\",\n] as const;\n\n/** One of {@link COLLECTION_ONLY_STATEMENTS}. The to-one arms subtract it. */\nexport type CollectionOnlyStatement = (typeof COLLECTION_ONLY_STATEMENTS)[number];\n\n/**\n * The three of the four that share one refusal message.\n *\n * `createMany` is excluded because it is refused on its own, in both planners,\n * with a message about there being *one related row* rather than about there\n * being no *set of rows* — and on the foreign side that refusal also guards the\n * operand check that follows it. Derived by subtraction rather than written out\n * again, so a fifth collection-shaped operand added above lands here too.\n */\nconst NO_SET_OF_ROWS: ReadonlySet<string> = new Set(\n COLLECTION_ONLY_STATEMENTS.filter((statement) => statement !== \"createMany\"),\n);\n\n/** Statements that insert a new row, so nothing is linked to it yet. */\nconst CREATE_ONLY_STATEMENTS = new Set([\"create\", \"createMany\"]);\n\n/**\n * The operands still refused, and what each would take.\n *\n * Named individually rather than covered by one message, because \"not\n * implemented\" is much less useful than knowing whether the thing you reached\n * for is a rewrite or a wait. Each of these is a *write to rows that already\n * exist*, which is the line: everything supported writes new rows or repoints a\n * key, and none of it has to reason about what was there before.\n */\n/**\n * Nothing, now — and that is the point of leaving the table here.\n *\n * Every entry it once held described machinery that turned out to exist one\n * layer down: five of them said a pass was missing that the child's own\n * `$exec` already runs, and the sixth — `upsert`'s — said the branch could not\n * be decided from inside a nested step, when `connectOrCreate` had been\n * deciding one the same way since #94.\n *\n * Kept rather than deleted because the next operand added here should have to\n * write its reason down, and because a reason naming *machinery* is checkable\n * where one naming a *principle* is not. That distinction is the only thing\n * that made six stale entries findable.\n */\nconst REFUSED: Record<string, string> = {};\n\n/** A foreign-key column on *this* model that a nested write supplies. */\nexport interface ForeignKeyContribution {\n /** The field name on this model — `organizationId`. */\n field: string;\n /** Produces the value at bind time, already unencoded. */\n value: Binder;\n}\n\nexport interface NestedWritePlanning {\n contributions: ForeignKeyContribution[];\n before: NestedWriteStep[];\n after: NestedWriteStep[];\n /**\n * Fields of *this* model that the statement must return, because an `after`\n * step needs them to point its children at this row.\n */\n keyFields: string[];\n}\n\nconst EMPTY: NestedWritePlanning = {\n contributions: [],\n before: [],\n after: [],\n keyFields: [],\n};\n\nexport function planNestedWrites(\n schema: ModelSchema,\n data: unknown,\n operation: string,\n /** Re-locates `data` inside the call's argument tree at bind time. */\n locateData: (args: any) => any,\n /**\n * Needed only by the implicit many-to-many path, which emits statements\n * against a table with no model and therefore has no `Fragment` pipeline to\n * number its placeholders — SQLite writes `?` and Postgres `$1`.\n */\n dialect: SqlDialect,\n): NestedWritePlanning {\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n return EMPTY;\n }\n\n const entries = Object.keys(data as Record<string, unknown>)\n .sort()\n .filter((key) => key in schema.relations)\n .filter((key) => (data as Record<string, unknown>)[key] !== undefined);\n\n if (entries.length === 0) return EMPTY;\n\n const planning: NestedWritePlanning = {\n contributions: [],\n before: [],\n after: [],\n keyFields: [],\n };\n\n /** Which relation contributed each foreign-key column, for the guard below. */\n const contributedBy = new Map<string, string>();\n\n for (const key of entries) {\n const relation = schema.relations[key];\n const node = (data as Record<string, unknown>)[key];\n const locate = (args: any) => locateData(args)?.[key];\n const before = planning.contributions.length;\n\n planOne(schema, relation, node, operation, locate, planning, dialect);\n\n // **Two relations that share a foreign-key column are refused by name**\n // (#271). A composite relation joins on *n* columns and nothing stops two\n // of them from sharing one — it is the tenant-scoped shape this whole\n // change is about:\n //\n // ledger Ledger @relation(fields: [tenantId, ledgerCode], …)\n // note Ledger @relation(fields: [tenantId, noteCode], …)\n //\n // `prisma validate` accepts that on 6.19.2, and before #271 both relations\n // were refused here for their width, so writing through both at once was\n // unreachable. It is reachable now, and the two `tenantId` contributions\n // collide: `insertColumns` folds contributions through a `Map` keyed by\n // field, so the later one wins, and `entries` above is sorted, so the\n // winner is whichever relation sorts last.\n //\n // **Prisma resolves the operands in the opposite direction and lets the\n // first resolved win, so the caller's last `data` key decides the shared\n // column** — measured on 6.19.2 with query events on: writing\n // `{ note: connect(2,\"b\"), ledger: connect(1,\"a\") }` stores `tenantId=1`\n // where `{ ledger: …, note: … }` stores `2`. gemi stores `2` either way.\n //\n // Matching that would mean giving up the sorted key order, which the plan\n // cache needs — two argument objects differing only in key order have to\n // be one plan. So this refuses instead, which is what the width refusal\n // this change replaced was buying: no plausible wrong row. A caller who\n // wants both links connects through one relation — which writes the shared\n // column — and sets the other relation's remaining columns directly, since\n // `insertColumns` only refuses a column that is written *both* ways.\n for (let index = before; index < planning.contributions.length; index++) {\n const field = planning.contributions[index].field;\n const owner = contributedBy.get(field);\n if (owner !== undefined && owner !== key) {\n throw new UnsupportedQueryError(\n `data.${key}`,\n schema.name,\n operation,\n `'${field}' is written by both the '${owner}' and '${key}' relations, ` +\n `which join on it in common. Prisma lets the last key in 'data' win; ` +\n `gemi plans relations in a fixed order and will not guess which row ` +\n `you meant. Write one of them through the relation and set the ` +\n `other's own columns directly.`,\n );\n }\n contributedBy.set(field, key);\n }\n }\n\n return planning;\n}\n\nfunction planOne(\n schema: ModelSchema,\n relation: RelationSchema,\n node: unknown,\n operation: string,\n locate: (args: any) => any,\n out: NestedWritePlanning,\n dialect: SqlDialect,\n): void {\n if (typeof node !== \"object\" || node === null || Array.isArray(node)) {\n throw new InvalidArgumentError(\n `data.${relation.name}`,\n schema.name,\n operation,\n \"Expected an object holding 'connect' or 'create'.\",\n );\n }\n\n // Sorted, and it is load-bearing twice over. The plan cache needs it — two\n // argument objects differing only in key order must be one plan — and the\n // *order the steps run in* falls out of it, because they are pushed in this\n // order and run in that order.\n //\n // Only one pair is order-sensitive today, and it happens to sort the right\n // way: `create` before `createMany` is what Prisma does, verified from the\n // ids it hands back. `connect` before `createMany` is the other pair and its\n // order is not observable — repointing an existing child and inserting new\n // ones do not interact — but it is pinned by a differential case rather than\n // left to be rediscovered.\n //\n // So: this is a coincidence that is currently correct. An operand added here\n // whose order *is* observable cannot rely on the alphabet and has to sequence\n // itself explicitly.\n const keys = Object.keys(node as Record<string, unknown>)\n .sort()\n .filter((key) => (node as Record<string, unknown>)[key] !== undefined);\n\n if (keys.length === 0) return;\n\n const child = relatedSchema(schema, relation);\n\n // **Every joined field, not the first one** (#271).\n //\n // This used to be `singleFieldLink(resolveLink(…))`: reading across\n // `@relation(fields: [tenantId, orderId], references: [tenantId, id])` was\n // implemented by #67 on all six read surfaces, and the write surface refused\n // it by name rather than joining on the first field and writing plausible\n // wrong rows. The refusal was honest and it was the only thing left on that\n // list, so the narrowing is gone and what follows contributes *n* foreign-key\n // columns wherever it used to contribute one.\n //\n // Nothing here branches on how many there are. The two sides read the link\n // through {@link childLink}, {@link keySelect} and {@link nullKey}, which are\n // the same three shapes for one field as for four — so a relation joining on\n // one field compiles to exactly the arguments it did before, and there is no\n // single-field path left to diverge from the composite one.\n const link = resolveLink(schema, child, relation, operation);\n\n // An implicit many-to-many is *neither* side: the keys live in a third table\n // with no model, so both directions are the same work and the operand set is\n // wider — `disconnect` and `set` are a delete against the join table, which\n // needs no schema to compile.\n if (link.join) {\n // **The one caller that still cannot take more than one field**, and it is\n // an invariant rather than a gap: Prisma's implicit many-to-many links\n // parent and child by their *primary keys*, one column each side, into a\n // two-column join table there is no schema to widen. `singleFieldLink`\n // states that rather than letting `planJoinTable` index into `[0]` and be\n // silently wrong if it ever stopped holding.\n const pair = singleFieldLink(link, schema, relation, operation);\n\n for (const key of keys) {\n planJoinTable(\n schema,\n relation,\n child,\n pair,\n key,\n (node as Record<string, unknown>)[key],\n operation,\n (args: any) => locate(args)?.[key],\n out,\n dialect,\n );\n }\n return;\n }\n\n for (const key of keys) {\n if (!SUPPORTED.has(key)) {\n const why = REFUSED[key];\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `Only ${[...SUPPORTED].sort().join(\", \")} are implemented.` +\n (why ? ` '${key}' is not: ${why}` : \"\"),\n );\n }\n\n // `create` has no row to disconnect from, and Prisma does not offer these\n // there either — it reports them as an unknown argument.\n if (EXISTING_ROW_ONLY.has(key) && CREATE_ONLY_STATEMENTS.has(operation)) {\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${key}' acts on rows already linked to this one, and a '${operation}' ` +\n `has none yet — Prisma refuses it here too. Use it on an 'update'.`,\n );\n }\n }\n\n // `from` is non-empty exactly on the side that holds the foreign key.\n const owning = relation.from.length > 0;\n\n for (const key of keys) {\n const operand = (node as Record<string, unknown>)[key];\n const at = (args: any) => locate(args)?.[key];\n\n if (owning) {\n planOwningSide(\n schema,\n relation,\n child,\n link,\n key,\n operand,\n operation,\n at,\n out,\n );\n } else {\n planForeignSide(\n schema,\n relation,\n child,\n link,\n key,\n operand,\n operation,\n at,\n out,\n );\n }\n }\n}\n\n/**\n * This model holds the foreign key, so the far row must exist — or be created —\n * before the insert can bind, and the whole thing collapses to *n* extra\n * columns — one, in the ordinary schema; as many as the relation joins on in a\n * tenant-scoped one (#271).\n *\n * **The columns are contributed to the statement the caller already asked for,\n * which is what makes a composite key here atomic without arranging anything.**\n * `contributions` is a list keyed by field, and `insertColumns` /\n * `updateAssignments` fold every entry into the single `INSERT` or `UPDATE`\n * this operation compiles to — so \"some keys written, some not\" is not a state\n * this side can reach: the `before` step either resolves the whole tuple or\n * throws, and the statement either runs or does not. The partial-write hazard\n * is real on the *foreign* side, where each linked row is its own statement,\n * and it is answered there by the transaction every plan carrying steps opens.\n */\nfunction planOwningSide(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n link: Link,\n key: string,\n operand: unknown,\n operation: string,\n at: (args: any) => any,\n out: NestedWritePlanning,\n): void {\n // `parentFields` are the FK columns on this model; `childFields` are what\n // they reference on the other one, paired positionally.\n const fkFields = link.parentFields;\n const referencedFields = link.childFields;\n\n /** Assign the resolved key onto the statement — one contribution per column. */\n const contributeResolved = () => {\n for (const field of fkFields) {\n out.contributions.push({\n field,\n value: (_args, context) => context.resolved[field],\n });\n }\n };\n\n /** Record a whole key on the plan's per-call scratch space. */\n const resolveKey = (\n context: { resolved: Record<string, unknown> },\n values: readonly unknown[],\n ) => {\n for (let index = 0; index < fkFields.length; index++) {\n context.resolved[fkFields[index]] = values[index] ?? null;\n }\n };\n\n /**\n * **Whether linking through this relation has to displace a sibling** — the\n * one-to-one case, where this row's foreign key carries the `@unique` that\n * makes the far row hold one partner, so pointing at an occupied one is a\n * collision rather than a second link (#363).\n *\n * **It takes both halves: the unique index *and* the far side's `kind`.** The\n * first draft of this used the index alone, on the argument that\n * `planForeignSide`'s `relation.kind` test and this one were \"the same\n * predicate, two spellings\". They are not, and the difference is a silent\n * destructive write rather than a wording problem.\n *\n * The implication holds one way only. P1012 gives *`kind !== \"many\"` implies\n * the key is unique* — Prisma will not let a non-list back-relation exist\n * beside a foreign key with no `@unique`. **The converse is false.** A\n * `@unique` foreign key beside a *list* back-relation is a schema Prisma\n * accepts:\n *\n * model Team { id Int @id players Player[] }\n * model Player { id Int @id teamId Int? @unique\n * team Team? @relation(fields: [teamId], references: [id]) }\n *\n * `prisma validate` on that is *\"The schema at b.prisma is valid\"* — measured,\n * not assumed. And the index alone would have displaced there, where Prisma\n * does not: `Player.update({ where: { id: 2 }, data: { team: { connect:\n * { id: 2 } } } })` with player 1 already on team 2 answers **P2002** and its\n * whole statement log is `SELECT Team.id`, the `UPDATE`, `ROLLBACK` — the\n * sibling is never even read. Against the same key with `keeper Keeper?` in\n * place of `players Player[]`, the identical call displaces and the log gains\n * the incumbent `SELECT` and its clear. So the *back-relation* is what\n * decides, and the index is a necessary condition rather than the answer.\n *\n * It is not an exotic shape either: a `@unique` added to a foreign key for\n * indexing, or a one-to-many half-migrated to a one-to-one, both land on it.\n * Without the second half gemi's two ends disagreed about one relation — the\n * foreign side saw `kind === \"many\"` and refused to displace, this side saw\n * the index and did.\n *\n * So `relation.kind` is still not readable from here — it says `\"one\"` for a\n * many-to-one and a one-to-one alike, because both point at a single far row,\n * which is the part of the original argument that survives. The question goes\n * to the *child's* copy of the relation instead, found by `relationName`, and\n * `uniques` narrows it rather than answering it.\n *\n * **A back-relation that cannot be identified does not displace.** Absent or\n * ambiguous, the answer is unknown, and of the two ways to be wrong only one\n * writes to a row nobody named — so the fallback is the collision this\n * operand raised before #363, which is also what a schema too malformed to\n * read should get. The self-relation exclusion is `otherSide`'s, restated\n * rather than shared because that function *throws* on the same condition and\n * has never run on this path: turning a schema that compiled yesterday into a\n * hard error is not this issue's to do.\n *\n * Nullable, for the same reason the foreign side is: a detach has to leave a\n * value behind. A required foreign key cannot be nulled, so the repoint\n * collides as it always did. That is not what Prisma answers — it refuses\n * ahead of the write with P2014, *\"The change you are trying to make would\n * violate the required relation\"*, measured on a scratch schema, since this\n * one carries no required one-to-one for a case to reach. Recorded rather\n * than matched: it is a divergence in the failure's *class* on a call that\n * fails either way, where every other line of this is about a call that\n * succeeds. `assertDisconnectable` is deliberately not called, exactly as on\n * the foreign side: it would refuse the whole operand, including the\n * empty-far-row case that has always worked.\n *\n * **An index over exactly the relation's own fields**, which is what the\n * single-field test used to say and reads differently now that there may be\n * several (#271). Prisma's rule is on the relation: *\"A one-to-one relation\n * must use unique fields on the defining side\"*, meaning `fields` — so\n * `@@unique([tenantId, ownerId])` beside `@relation(fields: [tenantId,\n * ownerId], …)` is the composite one-to-one, and it is the same fact the\n * single-column form was stating.\n *\n * **Both halves of that rule are Prisma's, measured on 6.19.2 rather than\n * inferred**, because between them they are the whole discriminator:\n *\n * @@unique([tenantId, ledgerCode]) accepted — the one-to-one\n * @@unique([tenantId, ledgerCode, seal]) P1012, \"Either add an\n * `@@unique([tenantId,\n * ledgerCode])` attribute\"\n * @@unique([ledgerCode, tenantId]) the identical P1012\n *\n * So a wider group does *not* make the relation one-to-one — reading it as\n * one would clear rows the schema never said were exclusive — and the order\n * has to match the relation's `fields` as well.\n *\n * Written as set equality all the same, and the second row is why that is not\n * laxity: the length check is what carries the weight, and a positional loop\n * would read as though order were a thing this had decided, when on any\n * schema Prisma accepted the two lists are already identical. It also keeps a\n * hand-built `ModelSchema` — a fixture, or a generator that reorders — out of\n * the branch where the index is not recognised at all.\n *\n * A foreign key that is also the `@id` would not be found in `uniques`, which\n * records `@unique` and `@@unique` rather than the primary key; it is out of\n * reach anyway, since `@id` implies `NOT NULL` and the nullable guard has\n * already excluded it.\n */\n const backRelations = Object.values(child.relations).filter(\n (candidate) =>\n candidate.relationName === relation.relationName &&\n // A self-relation names the same model on both ends, so the *field* is\n // what distinguishes them — `otherSide`'s test, and without it a\n // self-referencing one-to-many would find its own owning side here,\n // read `kind: \"one\"` off it and displace.\n !(child.name === schema.name && candidate.name === relation.name),\n );\n\n const keyed = new Set(fkFields);\n\n const displaces =\n fkFields.every((field) => schema.fields[field]?.nullable === true) &&\n schema.uniques.some(\n (unique) =>\n unique.length === keyed.size && unique.every((name) => keyed.has(name)),\n ) &&\n backRelations.length === 1 &&\n backRelations[0].kind !== \"many\";\n\n /**\n * Whether there is a row to displace *from* — false under a `create`, where\n * this row does not exist yet, so nothing it holds can be the incumbent.\n */\n const existing = !CREATE_ONLY_STATEMENTS.has(operation);\n\n // This side is a to-one by construction — it holds a single foreign key — so\n // there is nothing for a `createMany` to write many of. Prisma does not offer\n // it here either; refused with the reason rather than the grammar, because a\n // caller who reached for it has the direction of the relation wrong.\n // The *other* half of this refusal is in `planForeignSide`, which reaches the\n // same conclusion from the far side of the key: a one-to-one whose child\n // holds the foreign key is still a to-one. Both are reachable and neither\n // subsumes the other, so the message is duplicated rather than shared.\n if (key === \"createMany\") {\n throw new UnsupportedQueryError(\n `data.${relation.name}.createMany`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one: this row holds the foreign key, so ` +\n `there is one related row at most and nothing to create many of. ` +\n `Prisma does not accept it here either.`,\n );\n }\n\n if (key === \"create\") {\n // The far row does not exist yet: create it first, through its own model's\n // `$exec` so it is subject to everything a top-level create is (invariant 1).\n out.before.push({\n relation: relation.name,\n operation: \"create\",\n async run(args, context, executor) {\n const created = (await executor.exec(\n relation.model,\n \"create\",\n { data: at(args), select: keySelect(referencedFields) },\n // NOT pre-scoped. Nothing walks `data.<relation>.create`, so the\n // child's own `onCreate` is the only thing that can scope this row.\n false,\n )) as Record<string, unknown> | null;\n\n resolveKey(context, valuesOf(created, referencedFields));\n },\n });\n contributeResolved();\n return;\n }\n\n /**\n * `connectOrCreate` — find the row by a unique key, and create it only if it\n * is not there.\n *\n * **A hit ignores `create` entirely**, which is not what the name suggests\n * and is worth pinning: it is `connect`-or-create, not upsert. Measured — an\n * existing organisation kept its own name where the `create` payload named a\n * different one.\n *\n * `findUnique`, not `findUniqueOrThrow`: a miss is the *other branch* here,\n * where for a plain `connect` it is an error.\n *\n * Object only on this side. The relation holds one foreign key, so there is\n * one row to point at, and Prisma refuses an array here too.\n */\n /**\n * `disconnect` on a to-one whose key is on **this** row — the same three arms\n * the foreign side takes, through the same two helpers (#359).\n *\n * Prisma's operand here is `XWhereInput | boolean`, read off the generated\n * client and measured against it:\n *\n * disconnect: true clears the link\n * disconnect: false nothing happens, the link survives\n * disconnect: {} clears it — the empty filter matches\n * disconnect: { name: \"Ada\" } clears it only if the linked row matches\n * disconnect: { name: \"Grace\" } no match, so nothing happens — and\n * **silently**, not P2025\n * disconnect: <filter>, nothing linked silently nothing\n *\n * The silence in the last two is what makes the filter arm a *conditional*\n * detach rather than a guarded one: there is no miss to report, which is the\n * same asymmetry the foreign side measured between `disconnect` and `delete`\n * (M8c). So the arms differ only in what decides the value of one column.\n *\n * **The boolean is structural here, where the foreign side re-reads it at\n * bind time**, and that difference is forced rather than chosen. The foreign\n * side's operands are *statements* — `listOf(null)` is no statement — so a\n * plan handed the wrong boolean can still write nothing. This side's is a\n * *column in the SET list*: `false` emits no assignment and `true` emits one,\n * so the two spellings cannot share a statement text and no bind-time check\n * could rescue a cache hit that got it wrong. What makes that sound is\n * `shapeOfMember`'s guard (#358), which gives a `disconnect` boolean its own\n * plan key precisely because this decision is made once, at compile time.\n * Before it, a plan compiled from `true` served `false` and nulled a foreign\n * key on a call that asked for nothing.\n *\n * `delete` has no meaning here for the same reason it has no `createMany`:\n * this side is a to-one, and deleting the far row through a `data` key would\n * be deleting a row the statement is not about. Prisma does offer it; it is\n * refused rather than guessed, because a `delete` that fires as a side effect\n * of an unrelated update is the kind of thing to implement deliberately.\n */\n if (key === \"disconnect\") {\n // Before the arms, so a required foreign key is refused whichever one was\n // spelled — including `false`, which asks for nothing and still cannot be\n // written. Prisma agrees for a reason of its own: it leaves `disconnect`\n // out of the input type entirely when the relation is required, so\n // `disconnect: false` there is *\"Unknown argument `disconnect`\"* rather\n // than an accepted no-op. Measured on `SocialAccount.user`.\n assertDisconnectable(schema, relation, fkFields, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.disconnect`,\n });\n\n // `true` -> `{}`, `false` -> `null`, a filter passes through: the same\n // translation and the same shape check the foreign side runs, reused rather\n // than restated so the two sides cannot answer one grammar differently\n // again — which is the defect #359 was filed for.\n //\n // The check goes **first**, on the operand as written: the translation is\n // lossy in the one direction that matters, since it maps `false` onto the\n // same `null` a caller may have spelled outright. See `assertToOneFilter`.\n assertToOneFilter(schema, relation, child, operand, key, operation);\n const filter = toOneOperand(key, operand);\n\n // `false` — no contribution and no step, so the operand contributes\n // *nothing at all*: a `data` carrying only this compiles to the read\n // `compileUpdate` emits for an empty assignment list, and the row comes\n // back with its link intact. That is Prisma's answer, and the reason the\n // differential asserts it by value: what this replaces was a write.\n if (filter === null || filter === undefined) return;\n\n /**\n * `true` — the link's columns bound to `null`, exactly as `connect`'s\n * direct form binds them to a value. No step, nothing on the child read or\n * written, and so no scoping question: the row being changed is the one the\n * statement already names.\n */\n if (operand === true) {\n for (const field of fkFields) {\n out.contributions.push({ field, value: () => null });\n }\n return;\n }\n\n /**\n * A filter — detach only if the row this one points at matches it.\n *\n * Two reads, and neither is avoidable from this side. The condition is a\n * property of the *linked* row, and which row that is lives in a column of\n * the row being updated, which the arguments do not carry — so the parent\n * is read first and the child second. The far side needs neither: its\n * filter goes straight into the `where` of the `updateMany` that clears the\n * key, because there the key is on the row being filtered.\n *\n * **The child read goes through the child's own `$exec`, un-pre-scoped**,\n * which is what puts this operand on the supported side of this file's\n * line. A `disconnect` that acts on \"whatever is there\" has no lookup to\n * hang a scope on; this one has, so a child the caller's policies hide\n * reads as absent and the link survives — the same conservative answer\n * `set` gives, and the same one the foreign side's `disconnect` gives for a\n * hidden row.\n *\n * The parent read is **pre-scoped**: `args.where` is the effective `where`\n * this call already put through this model's policies, so re-applying them\n * would `AND` the same predicate twice. It reads one column of one row —\n * `update` matched its `where` against a unique key — inside the\n * transaction the nested steps already run in, so the value it returns is\n * the one the statement below is about to write over.\n */\n out.before.push({\n relation: relation.name,\n operation: \"disconnect\",\n async run(args, context, executor) {\n // Default to the values that are already there, so a filter that\n // matches nothing writes the columns back unchanged. The contributions\n // are in the SET list either way — the statement's text cannot depend\n // on a value read at bind time — so \"nothing happens\" has to be spelled\n // as assignments that change nothing rather than as absent ones.\n resolveKey(context, nullsFor(fkFields));\n\n const parent = (await executor.exec(\n schema.name,\n \"findFirst\",\n { where: args?.where, select: keySelect(fkFields) },\n true,\n )) as Record<string, unknown> | null;\n\n const linked = valuesOf(parent, fkFields);\n // Nothing linked: no row for the filter to match, and Prisma is silent\n // about it. `null` is already what the columns hold. A *partially*\n // written composite key lands here too, and that is the right answer —\n // it joins to no row, so no filter can match through it.\n if (!isLinked(linked)) return;\n\n resolveKey(context, linked);\n\n const matched = await executor.exec(\n relation.model,\n \"findFirst\",\n {\n // `AND`, not a spread: a filter naming a referenced column itself\n // must narrow rather than replace the restriction that keeps this\n // on the linked row. Same rule as everywhere else here.\n // `link` reads the same way on this side: its `parentFields` are\n // this row's foreign key and its `childFields` are what they\n // reference, so `childLink` yields the far row's own columns bound\n // to the values just read off this one.\n where: conjoin(at(args), childLink(link, parent as Record<string, unknown>)),\n select: keySelect(referencedFields),\n },\n false,\n );\n\n if (matched) resolveKey(context, nullsFor(fkFields));\n },\n });\n\n contributeResolved();\n return;\n }\n\n if (key === \"delete\") {\n throw new UnsupportedQueryError(\n `data.${relation.name}.delete`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one whose foreign key lives on this row, so ` +\n `deleting through it would remove a row this statement is not about. ` +\n `Delete it directly, or 'disconnect' it first.`,\n );\n }\n\n /**\n * `update` through a to-one — this row holds the key, so the row being\n * written is the one it points at.\n *\n * Prisma accepts both spellings, measured: `update: { name: \"x\" }` and\n * `update: { data: { name: \"x\" } }`. The second is the documented one and the\n * first is what people write; accepting only one would refuse a legal query.\n *\n * An `after` step rather than a `before` one, and it needs the foreign key in\n * the statement's `RETURNING` — the far row is identified by *this* row's\n * column, whose current value the arguments do not carry. That is why\n * `keyFields` gains it here, where the other owning-side operands need\n * nothing returned at all.\n */\n if (key === \"update\") {\n out.keyFields.push(...fkFields);\n\n // The same check the foreign side runs, on the same operand grammar. Both\n // sides accept `{ where?, data }` and both must refuse an unknown key\n // inside it, or a misspelled `where` silently widens the write on whichever\n // side missed the check — the asymmetry #116 was filed about, arriving one\n // operand later.\n assertToOneWriteOperand(schema, relation, child, key, operand, operation);\n\n out.after.push({\n relation: relation.name,\n operation: \"update\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n // A composite key with any column null names no row — see\n // {@link isLinked} — so a half-written link is the *absent* case here\n // rather than a lookup that finds nothing later.\n if (!isLinked(valuesOf(parent, fkFields))) {\n // The same error as the foreign side's miss, and for the same reason\n // — this is one condition with two spellings, not two conditions.\n // Measured rather than inferred: Prisma answers P2025 here too,\n // *\"depends on one or more records that were required but not\n // found\"*, which `failureKind` maps to `notFound`.\n //\n // `UnsupportedQueryError` was wrong twice over. It classifies as\n // `other`, so the differential harness would have called it agreement\n // with a Prisma refusal of a different kind — and it prefixes \"does\n // not support … yet\", which reports a fully-implemented operation as\n // unimplemented because a row is missing. That vocabulary has been\n // corrected once each on #82 and #88.\n throw new RecordNotFoundError(relation.model, \"update\");\n }\n\n // `.data !== undefined` rather than `\"data\" in operandAt`, which is the\n // test {@link toOneOperand} makes and the one this used to disagree\n // with. `canonicalShape` drops an `undefined`-valued key, so `update:\n // {}` and `update: { data: undefined }` are one plan entry — and an\n // explicit `undefined` is the ordinary way a conditional write is\n // spelled, which is why `suppliedFields` skips it everywhere else.\n // Keying on presence sent `data: undefined` down to `updateMany` and\n // answered a no-op call with `updateMany requires 'data'`, on the side\n // this file cites as the precedent for the other one.\n const operandAt = at(args);\n const wrapped =\n operandAt !== null &&\n typeof operandAt === \"object\" &&\n (operandAt as Record<string, unknown>).data !== undefined;\n const record = operandAt as Record<string, unknown> | null;\n const data = wrapped ? record!.data : operandAt;\n\n // The caller's filter, conjoined with the link — so `update: { where,\n // data }` narrows *which* single row is written rather than being\n // decoration. Ignoring it was a silent wrong write: the operand\n // type-checks on both sides, the foreign side conjoins it and raises on\n // a miss, and this side renamed the linked row whether or not it\n // matched. Prisma answers P2025 for the non-matching case, which is\n // what the lookup below reproduces.\n //\n // The lookup only happens when a `where` is actually present, and that\n // is shape-stable — `canonicalShape` records a `where` key's presence —\n // so the common `update: { … }` spelling still costs one statement.\n const filter = wrapped ? record!.where : undefined;\n const where = conjoin(filter, childLink(link, parent));\n\n if (filter !== undefined) {\n const found = (await executor.exec(\n relation.model,\n \"findFirst\",\n { where, select: keySelect(referencedFields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (!found) throw new RecordNotFoundError(relation.model, \"update\");\n }\n\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where, data },\n // NOT pre-scoped: the child's own policies decide whether this row is\n // reachable and whether the payload is allowed to write what it\n // names — its `onUpdate` and its scope-escape guard.\n false,\n );\n },\n });\n return;\n }\n\n /**\n * The list operands, refused by name on a to-one.\n *\n * `set`, `updateMany` and `deleteMany` describe *many* rows, and this side\n * has one by construction — Prisma does not offer them here either. They were\n * in `SUPPORTED` with no branch on this side, so they fell through to the\n * `connect` handling below and reported `connect` back to a caller who wrote\n * something else. Same fall-through as `upsert`'s, found by the same test.\n *\n * The fourth collection operand, `createMany`, is refused above this with its\n * own wording, which is why the set read here is {@link NO_SET_OF_ROWS} and\n * not {@link COLLECTION_ONLY_STATEMENTS} whole.\n */\n if (NO_SET_OF_ROWS.has(key)) {\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one: this row holds a single foreign key, so ` +\n `there is no set of rows for '${key}' to act on. Prisma does not ` +\n `accept it here either. Use 'connect', 'disconnect' or 'update'.`,\n );\n }\n\n /**\n * `upsert` through a to-one whose key is on **this** row — update the far row\n * this one points at, or mint one and point at it (#391).\n *\n * **Its refusal named a write-back that this side does not need**: *\"an\n * absent far row would have to be created and then written back to a\n * `<parent>` that has already been inserted\"*. It has not been inserted. The\n * statement the caller asked for is the one this step runs *before*, so a\n * created row's key reaches it as a contribution — which is exactly what the\n * `create` and `connectOrCreate` branches above already do, and they are the\n * two operands either side of this one. What was genuinely missing was\n * deciding the branch, and that is a lookup, the same one `connectOrCreate`\n * has been deciding since #94. The seventh refusal in this file to describe\n * machinery one layer down.\n *\n * The refusal also pointed at a workaround that does not exist here: *\"upsert\n * the `<child>` directly, then 'connect' it\"*. On the **foreign** side that\n * works, because the child carries the back-reference to key the upsert on —\n * `Image.upsert({ where: { thumbnailForMediaId: id }, … })`, which is what\n * #354 shipped. On this side there is no such column: the link is this row's\n * `previewImageId`, and `Image` has nothing pointing back. So the caller was\n * being sent to a spelling with nothing to put in its `where`, and the real\n * workaround — read the foreign key, then branch by hand into `create` or\n * `update` — was left to be rediscovered per call site. That is the half of\n * #391 a wording fix would not have closed.\n *\n * **A `before` step, and the branch is decided from the parent's own key.**\n * The far row is identified by a column of this row, which the arguments do\n * not carry, so the parent is read first — pre-scoped, exactly as the\n * `disconnect` filter arm's parent read is and for the same reason: `args.where`\n * has already been through this model's policies. Then:\n *\n * linked, and the far row matches -> update it, key written back unchanged\n * linked, filter matches nothing -> the create branch, as Prisma's does\n * nothing linked -> create it and take the new key\n *\n * Measured against 6.19.2/SQLite on `Profile.user` (a one-to-one) and\n * `User.organization` (a many-to-one), which answer identically:\n *\n * no where, nothing linked insert the far row, update this row's key\n * no where, linked select the far row, update it, **this row is\n * not written at all**\n * where matching, linked the same update, filtered\n *\n * **Nothing displaces**, and that is per branch rather than an omission. The\n * update branch keeps the link it found; the create branch mints a row a line\n * earlier, so nothing can already be pointing at it — `connectOrCreate`'s miss\n * branch says the same thing in the same words, and Prisma agrees by\n * construction: its log for the create branch is the insert and the repoint,\n * with no incumbent lookup in it.\n *\n * **KNOWN DIVERGENCE — a `where` that matches nothing is served here and is a\n * Prisma bug there.** Prisma splices the operand's filter into the *parent's*\n * `UPDATE`, so the create branch emits\n * `update \"Profile\" set \"userId\" = ? where (\"id\" in (?) and \"User\".\"name\" = ?)`\n * — a column of the far table in this row's statement — and answers P2022,\n * *\"The column `main.User.name` does not exist in the current database\"*,\n * having already inserted the far row inside the transaction it then rolls\n * back. Measured on SQLite on both relation shapes above and on the composite\n * `LedgerNote.ledger`; the statement is invalid on Postgres too, though as a\n * missing `FROM`-clause entry rather than an unknown column, so the pin\n * asserts the failure and not its class. gemi runs the create branch the\n * operand asks for. It is the same operand the *hit* branch serves correctly\n * on both clients, so refusing the `where` outright would refuse a query\n * Prisma answers; the divergence is pinned in `writes.differential.test.ts`\n * rather than matched.\n *\n * **The hit branch writes this row's foreign key back unchanged**, which is\n * the one thing here that costs anything: the contribution is in the SET list\n * whether or not the branch that changes it ran, because a statement's text\n * cannot depend on a value read at bind time. On a model carrying\n * `@updatedAt` that stamps a row Prisma leaves alone. Pre-existing rather than\n * introduced — it is the same mechanism, and the same trade, as the owning\n * side's `disconnect` filter arm, whose measurements are in\n * `updateAssignments`' docblock in `write.ts`.\n *\n * A branch of its own is also what keeps the refusals honest, and that is why\n * this sits above `connect` rather than after it. With none, the operand fell\n * through to the `connect` handling and reported *\"'where' yet\n * (Organization.update.organization.connect)\"* — a different operand, a\n * different model, and a claim that `{ id: 1 }` is not a unique field when it\n * is. That is the shape #85 was filed for and #101 fixed on its own path.\n */\n if (key === \"upsert\") {\n // Both checks, in this order, and neither subsumes the other: the first is\n // the to-one *shape* — an array, a scalar, a misspelled `where` that would\n // otherwise be dropped and turn a filtered write into an unconditional one\n // — and the second is `upsert`'s own grammar, that both payloads are there.\n // `false` rather than `many`, for the reason its docblock gives: a to-one's\n // `where` is an optional `WhereInput`, not a unique key.\n assertToOneWriteOperand(schema, relation, child, key, operand, operation);\n assertUpsertOperand(schema, relation, child, operand, operation, false);\n\n out.before.push({\n relation: relation.name,\n operation: \"upsert\",\n async run(args, context, executor) {\n // Optional throughout, the way `connectOrCreate`'s reads are: the\n // plan-time checks above ran on the *shape*, and `canonicalShape`\n // records a key's presence, so a plan hit implies the same keys — but\n // nothing in a step should be the first place a missing one is a\n // `TypeError` rather than an error naming the argument.\n const record = at(args) as Record<string, unknown> | null | undefined;\n\n // Pre-scoped: `args.where` is the effective `where` this call already\n // put through this model's policies, so re-applying them would `AND`\n // the same predicate twice. One column of one row, inside the\n // transaction the nested steps already run in.\n const parent = (await executor.exec(\n schema.name,\n \"findFirst\",\n { where: args?.where, select: keySelect(fkFields) },\n true,\n )) as Record<string, unknown> | null;\n\n // A composite key with any column null names no row — see\n // {@link isLinked} — so a half-written link is the *absent* case here\n // and takes the create branch, as does a parent this statement will go\n // on to match nothing of. Prisma reaches the second the same way: its\n // parent read finds nothing, it inserts the far row, and the failure\n // arrives from the write-back as P2025, rolling the insert back. gemi's\n // own `update` raises `RecordNotFoundError` for the same call and takes\n // this step down with it.\n if (isLinked(valuesOf(parent, fkFields))) {\n // `AND`, not a spread: a filter naming a referenced column itself\n // must narrow rather than replace the restriction that keeps this on\n // the linked row. `childLink` reads as \"the row this one points at\"\n // on this side — the far row's own columns bound to the values just\n // read off this one.\n const where = conjoin(\n record?.where,\n childLink(link, parent as Record<string, unknown>),\n );\n\n const hit = (await executor.exec(\n relation.model,\n \"findFirst\",\n { where, select: keySelect(referencedFields) },\n // NOT pre-scoped: the child's own policies decide which rows exist,\n // and a row this caller cannot see reads as absent — which sends it\n // to the create branch, exactly as a hidden child does on the\n // foreign side. The conservative answer, and the same one there.\n false,\n )) as Record<string, unknown> | null;\n\n if (hit) {\n // The key this row already holds, written back unchanged. The\n // contribution is structural, so \"the link does not move\" has to be\n // spelled as an assignment that changes nothing rather than as an\n // absent one — the rule the `disconnect` filter arm states.\n resolveKey(context, valuesOf(hit, referencedFields));\n\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where, data: record?.update },\n // NOT pre-scoped: the child's `onUpdate` and its scope-escape\n // guard judge the payload, as they do for a nested `update`.\n false,\n );\n return;\n }\n }\n\n const created = (await executor.exec(\n relation.model,\n \"create\",\n { data: record?.create, select: keySelect(referencedFields) },\n // NOT pre-scoped — the child's own `onCreate` scopes the new row.\n false,\n )) as Record<string, unknown> | null;\n\n resolveKey(context, valuesOf(created, referencedFields));\n },\n });\n\n contributeResolved();\n return;\n }\n\n if (key === \"connectOrCreate\") {\n assertConnectOrCreateOperand(\n schema,\n relation,\n child,\n operand,\n operation,\n false,\n );\n\n out.before.push({\n relation: relation.name,\n operation: \"connectOrCreate\",\n async run(args, context, executor) {\n const where = at(args)?.where;\n\n const found = (await executor.exec(\n relation.model,\n \"findUnique\",\n { where, select: keySelect(referencedFields) },\n // NOT pre-scoped, for the reason `connect` is not: this reads another\n // model's rows to decide what to attach, so that model's policies say\n // which rows exist. Scoped away, a hit becomes a miss and the row is\n // *created* — so the fallback branch is what keeps this from being a\n // way to observe another tenant's keys.\n false,\n )) as Record<string, unknown> | null;\n\n if (found) {\n const values = valuesOf(found, referencedFields);\n // A hit **is** a connect, so it displaces where the miss below cannot\n // — measured on both sides, and the reason `displaces` is consulted\n // per *branch* rather than per operand. `planForeignSide`'s table\n // records the same split from the other end (M14c / M15d).\n if (displaces) {\n await displaceSibling(\n schema,\n fkFields,\n values,\n args?.where,\n existing,\n executor,\n );\n }\n resolveKey(context, values);\n return;\n }\n\n const created = (await executor.exec(\n relation.model,\n \"create\",\n { data: at(args)?.create, select: keySelect(referencedFields) },\n // NOT pre-scoped — the child's own `onCreate` scopes the new row.\n false,\n )) as Record<string, unknown> | null;\n\n // No displacement on this branch, and it is not an omission: the far\n // row was minted a line ago, so nothing can already be pointing at it.\n // Prisma agrees by construction rather than by rule — its miss branch\n // logs the insert and the repoint and no incumbent lookup at all.\n resolveKey(context, valuesOf(created, referencedFields));\n },\n });\n\n contributeResolved();\n return;\n }\n\n // `connect`. In the common case the caller already handed us the referenced\n // value — `connect: { id: 1 }` where the relation references `id` — and no\n // query is needed at all: it is one more bound column.\n //\n // Whether that is the case is a property of the argument *shape*, not of its\n // values, so the choice is made here at compile time and the two forms are two\n // plans. That is what keeps a `connect` from silently costing a round trip.\n if (\n typeof operand !== \"object\" ||\n operand === null ||\n Array.isArray(operand)\n ) {\n throw new InvalidArgumentError(\n `data.${relation.name}.connect`,\n schema.name,\n operation,\n \"Expected an object naming a unique field.\",\n );\n }\n\n /**\n * **Single-field only, and a composite `connect` takes the lookup** (#271).\n *\n * The optimisation is \"the caller already handed us the value the column\n * needs\", and on a composite relation they did not: Prisma spells a\n * multi-column unique key in its *compound* form —\n * `connect: { tenantId_code: { tenantId: 1, code: \"a\" } }`, one argument key\n * named after the index — so there is no key here whose value is a referenced\n * column. Reading one out would mean reproducing the generator's `_`-joined\n * naming rule inside the planner, and then assuming the caller reached for\n * the group the relation *references* rather than any other unique key on the\n * child, which `connect` explicitly allows.\n *\n * So the composite case pays one `findUniqueOrThrow`, and that costs parity\n * nothing: Prisma issues the same lookup. Measured on 6.19.2 with query\n * events on, `LedgerEntry.create({ data: { amount: 1, ledger: { connect:\n * { tenantId_code: { tenantId: 1, code: \"ab\" } } } } })` logs\n *\n * BEGIN IMMEDIATE\n * select Ledger.tenantId, Ledger.code where tenantId = ? and code = ?\n * insert into LedgerEntry (tenantId, ledgerCode, amount) values (?,?,?)\n * select the row back\n * COMMIT\n *\n * — the resolve is a statement there too. The zero-query path was always a\n * gemi-only shortcut over the shape where the operand *is* the value.\n */\n const direct =\n referencedFields.length === 1 &&\n (operand as Record<string, unknown>)[referencedFields[0]] !== undefined &&\n Object.keys(operand as Record<string, unknown>).filter(\n (name) => (operand as Record<string, unknown>)[name] !== undefined,\n ).length === 1;\n\n if (direct) {\n const referenced = referencedFields[0];\n const fkField = fkFields[0];\n\n /**\n * **The direct form still costs a step when it has an incumbent to\n * displace**, and only then.\n *\n * \"No query is needed at all\" is a claim about resolving the *operand*, and\n * it survives: the value is still read straight out of the argument tree\n * and never looked up. What a one-to-one adds is a second row that has to\n * stop holding it, which no amount of knowing the value answers.\n *\n * The condition is the schema's, not the call's, so the two forms are\n * still decided once at compile time and a many-to-one `connect` — which\n * is every `connect` in an ordinary schema — keeps the zero-query path it\n * has always had.\n */\n if (displaces) {\n out.before.push({\n relation: relation.name,\n operation: \"connect\",\n async run(args, _context, executor) {\n await displaceSibling(\n schema,\n [fkField],\n [at(args)?.[referenced]],\n args?.where,\n existing,\n executor,\n );\n },\n });\n }\n\n out.contributions.push({\n field: fkField,\n value: (args) => at(args)?.[referenced],\n });\n return;\n }\n\n // `connect: { publicId: \"...\" }` against a relation that references `id`:\n // Prisma resolves it with a lookup, and so do we. Validated now so a\n // non-unique connect target fails at compile time rather than matching an\n // arbitrary row.\n matchUniqueKey(child, operand, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.connect`,\n });\n\n out.before.push({\n relation: relation.name,\n operation: \"connect\",\n async run(args, context, executor) {\n const found = (await executor.exec(\n relation.model,\n \"findUniqueOrThrow\",\n { where: at(args), select: keySelect(referencedFields) },\n // NOT pre-scoped. This lookup reads another model's rows to decide what\n // to attach, so it is that model's policies that say which rows exist —\n // otherwise a `connect` by any unique key reaches every tenant's.\n false,\n )) as Record<string, unknown> | null;\n\n const values = valuesOf(found, referencedFields);\n\n // After the lookup, which is the ordering #363 asked how to get: the\n // clear cannot be written until the referenced value is known, and\n // sitting in the same step is what orders it without having to order a\n // write between two reads that are otherwise independent. It also puts\n // the *miss* on the right side of the detach — `findUniqueOrThrow` has\n // already raised, so a `connect` naming no row displaces nothing, which\n // is Prisma's answer (P2025 with the incumbent untouched).\n if (displaces) {\n await displaceSibling(\n schema,\n fkFields,\n values,\n args?.where,\n existing,\n executor,\n );\n }\n\n resolveKey(context, values);\n },\n });\n contributeResolved();\n}\n\n/**\n * The *child* holds the foreign key, so nothing can be written until this row\n * exists and its key is known. Both forms are therefore `after` steps, and both\n * need the key in the statement's `RETURNING` list — **every column of it**,\n * since a composite link is only usable once the whole tuple is known (#271).\n *\n * **This is the side the partial-write hazard is real on**, and it is answered\n * rather than avoided. The owning side folds its columns into one statement;\n * here each linked row is its own `update` or `create`, so a composite key\n * whose second statement fails leaves the first row repointed. `$exec` opens a\n * transaction for any plan carrying steps — iteration 5 — so the failure rolls\n * the parent row back with it, which is the same guarantee that already covers\n * a `connect` of three rows where the third does not exist.\n */\nfunction planForeignSide(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n link: Link,\n key: string,\n operand: unknown,\n operation: string,\n at: (args: any) => any,\n out: NestedWritePlanning,\n): void {\n const parentFields = link.parentFields;\n const childFields = link.childFields;\n\n out.keyFields.push(...parentFields);\n\n /**\n * **Whether linking through this relation has to displace what is linked\n * already** — the to-one case, where the child's key carries the `@unique`\n * that makes the relation hold one row, so a second link is a collision\n * rather than a second row.\n *\n * Prisma detaches the incumbent rather than deleting it, and it does so for\n * some of the operands that link and not others. That split is not derivable\n * — it is measured, on one fixture, and it is the reason `displaces` is\n * consulted per operand rather than applied to \"anything that links\":\n *\n * create displaces the incumbent, links the new row\n * connect displaces the incumbent, links the named row\n * connectOrCreate, hit the same — it *is* a connect (#361)\n * connectOrCreate, miss collides: P2002 on the child's key\n * upsert, create branch collides: P2002 on the child's key\n *\n * So the two branches of one `connectOrCreate` answer differently, which is\n * Prisma's asymmetry and not an embellishment: what displaces is *linking an\n * existing row*, plus the bare `create` — and the create inside the two\n * compound operands does not.\n *\n * Nullable, because a detach has to leave a value behind. A required child\n * key cannot be nulled at all, so the insert or repoint collides as it always\n * did, which is the only thing the schema permits. `assertDisconnectable` is\n * deliberately not called here: it would refuse the whole operand, including\n * the empty-to-one case that has always worked.\n *\n * **`relation.kind` is the whole discriminator here, and it is *not* the same\n * predicate as the owning side's (#363) — it is the stronger half of it.**\n * `kind` is a property of this relation's back-reference, and Prisma will not\n * let a non-list back-relation exist without `@unique` on the child's foreign\n * key. Verified against 6.19.2 rather than assumed: `User.profile Profile?`\n * beside a `Profile.userId` carrying no `@unique` is refused at parse time\n * with P1012 — *\"A one-to-one relation must use unique fields on the defining\n * side. Either add an `@unique` attribute to the field `userId`, or change\n * the relation to one-to-many\"* — so a schema reaching this line with\n * `kind !== \"many\"` **has** the index, and `kind` alone is sufficient here.\n *\n * **The converse does not hold, which is why the owning side needs two tests\n * where this one needs one.** A `@unique` foreign key beside a *list*\n * back-relation validates: `Player.teamId Int? @unique` next to\n * `Team.players Player[]` is accepted, and Prisma refuses the displacing\n * `connect` there with P2002 without reading the sibling. So \"the key is\n * unique\" is strictly weaker than `kind !== \"many\"`, and an owning-side\n * discriminator built on the index alone displaces on schemas this side\n * correctly leaves alone. That is a real defect this file shipped for one\n * review cycle; `planOwningSide`'s `displaces` now reads the *child's* copy of\n * the relation for its `kind` and uses `uniques` only to narrow. From the\n * owning side `relation.kind` is still unreadable — it says `\"one\"` for a\n * many-to-one and a one-to-one alike, because both point at a single far row.\n *\n * **Every column has to be nullable, not the first one** (#271). Prisma makes\n * a composite relation optional or required as a whole and refuses a mixture,\n * so on a schema it accepted the columns agree — but the test is over all of\n * them because half a detach is worse than none: the incumbent would keep a\n * key that still joins nowhere while the unique index still holds it.\n */\n const displaces =\n relation.kind !== \"many\" &&\n childFields.every((field) => child.fields[field]?.nullable === true);\n\n /**\n * **A to-one whose key is on the child**, which this function otherwise plans\n * as though the child were a list.\n *\n * It had exactly one `kind` check — `createMany`'s, further down — because no\n * fixture had the shape, so nothing ever reached this side with `kind: \"one\"`\n * (#116). Everything else took the to-many spelling: `updateMany` and\n * `deleteMany` *compiled*, and `update` / `delete` / `upsert` were refused\n * for looking wrong rather than for being unimplemented here.\n *\n * Measured against the generated client rather than reasoned about. Prisma's\n * to-one nested input is\n *\n * { create, connectOrCreate, upsert, disconnect, delete, connect, update }\n *\n * with no `createMany`, `set`, `updateMany` or `deleteMany` key at all — so\n * the first group below is refused for the same reason `planOwningSide`\n * refuses it, and says so in the same words.\n *\n * The rest of that input — `update`, `delete`, `upsert` — was refused here\n * too, for being spelled unlike the to-many form. It is implemented now, and\n * the implementation is a *translation* rather than three new bodies: see\n * {@link toOneOperand}.\n */\n // The operand as the caller wrote it, kept because the rewrite below\n // overwrites `operand` in place and `assertToOneFilter` has to read the\n // spelling rather than the translation — `false` and `null` are one value\n // afterwards and two very different calls before. See that function.\n const spelledOperand = operand;\n\n if (relation.kind !== \"many\") {\n // {@link NO_SET_OF_ROWS} rather than {@link COLLECTION_ONLY_STATEMENTS}:\n // `createMany` is the fourth of them and is refused further down, where its\n // own message and its operand check live together.\n if (NO_SET_OF_ROWS.has(key)) {\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one: there is a single ${child.name} row, ` +\n `so there is no set of rows for '${key}' to act on. Prisma does not ` +\n `offer it on a to-one either. Use 'connect', 'disconnect' or ` +\n `'update'.`,\n );\n }\n\n /**\n * **An array where the relation holds one row**, which compiled here and\n * wrote through it.\n *\n * Nothing below this point consults `kind`, so `create: [a, b]` inserted\n * two children, and `connect: [{ id: 1 }, { id: 2 }]` repointed *both* rows\n * through a relation that can hold one — the second silently winning. That\n * is a live divergence, not strictness: Prisma refuses all three, measured\n * off the generated client rather than reasoned from the docs.\n *\n * connect: [{ id: 1 }, { id: 2 }]\n * -> PrismaClientValidationError, neither row repointed\n * create: [{ bio: \"a\" }, { bio: \"b\" }]\n * -> \"Expected ProfileCreateWithoutUserInput or\n * ProfileUncheckedCreateWithoutUserInput, provided (Object, Object)\"\n *\n * `PrismaClientValidationError` carries **no `code`** — it is an argument\n * refusal rather than a database one — which is why this is\n * `InvalidArgumentError` and not either `Unsupported*`: the argument is\n * supported and the value is wrong. So the message names the shape that\n * would work rather than announcing that arrays are unimplemented.\n *\n * Sound at plan time because array-ness is *in the plan key*: an array and\n * a single object are different structures to `canonicalShape`, so they can\n * never share a cache entry and this refusal cannot be decided on one\n * call's behalf by another's.\n */\n if (Array.isArray(operand)) {\n throw new InvalidArgumentError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one — ${child.name} holds the foreign key, ` +\n `so there is one row here at most. Expected a single object for ` +\n `'${key}', not an array of them. Prisma refuses the array too.`,\n );\n }\n\n /**\n * The three that were refused are a **spelling** difference, not missing\n * machinery. `conjoin` returns the parent restriction alone when the\n * caller's filter is absent or `{}`, and `listOf(null)` is `[]` — so a\n * to-one is a to-many of one, and the bodies below already do the work\n * once the operand is written the way they read.\n *\n * **Rebinding `at` — translating at *bind* time and not only while the plan\n * is compiled — is load-bearing for exactly one branch, and that is the\n * correctness argument for this whole design.** Every other distinction the\n * table draws is *structural*, so it may safely be decided once when the\n * plan is built: `{ data }` against `{ where, data }`, a `where` present\n * against absent, an array against an object — `canonicalShape` records all\n * of those, so two calls that differ there are already two plans. The\n * boolean is the one that is not. `delete: true` and `delete: false` are\n * the same shape to everything except the guard `shapeOfMember` carries for\n * exactly this, and a plan key is a cache rather than a contract. Reading\n * the boolean inside `at` means the step consults the *call's* value on\n * every execution, so a plan handed the wrong one still writes nothing —\n * `listOf(null)` is `[]`. Belt and braces on purpose: the owning side's\n * version of the same collision was a silent wrong write for its whole\n * life, precisely because its `true`/`false` decision was made once at\n * compile time and never revisited.\n */\n // Checked *before* the rewrite, because the rewrite is lossy by\n // construction: it rebuilds the operand from the keys it knows, so a key it\n // does not know is gone by the time anything downstream could refuse it.\n assertToOneWriteOperand(schema, relation, child, key, operand, operation);\n\n const spelled = at;\n at = (args: any) => toOneOperand(key, spelled(args));\n operand = toOneOperand(key, operand);\n }\n\n /**\n * `disconnect` and `delete` on this side act on rows the caller named by\n * unique key — which is what makes them expressible at all, and what puts\n * them on the supported side of this file's line.\n *\n * **On a to-one the caller names a *filter*, or nothing at all**, and that\n * does not weaken the line: the row is still identified, by the parent's own\n * key, which is the strongest naming available. `assertToOneFilter` is what\n * replaces the unique-key match there, and the filter only narrows.\n *\n * They differ on a row that is *not* linked to this parent, and the\n * difference is Prisma's, measured rather than chosen — on both kinds, since\n * the second pair is the same asymmetry read through the to-one spelling:\n *\n * disconnect a row linked elsewhere -> succeeds, changes nothing\n * delete a row linked elsewhere -> raises \"are not connected\"\n * disconnect: true, nothing linked -> succeeds, changes nothing\n * delete: true, nothing linked -> P2025\n *\n * So both filter by the parent key as well as the caller's key, and only\n * `delete` treats a miss as an error. That filter is doing two jobs at once:\n * it reproduces Prisma's semantics, and it is what stops either operand from\n * reaching a row belonging to a different parent.\n *\n * **Scoping comes from the child's own operations**, as everywhere else here:\n * `updateMany` and `delete` go through the child's `$exec` un-pre-scoped, so\n * a row the child's policies hide is not reachable. For `delete` that means a\n * hidden row reports \"not connected\" rather than \"denied\" — the same answer\n * as a row that genuinely is not linked, which is the conservative one.\n */\n /**\n * `update: { where, data }` — the caller's columns, written to a row they\n * named by unique key.\n *\n * **The pass this was refused for turns out to exist**, one layer down. The\n * `REFUSED` entry said it \"needs its own scoping pass\" for `onUpdate` and the\n * scope-escape guard; both of those live in `applyPolicies`, which the\n * child's own `$exec` runs because this step is not pre-scoped. Verified\n * rather than assumed:\n *\n * another tenant's row -> { count: 0 } the child's scope\n * caller names a scoped column -> ScopeEscapeError\n *\n * So the refusal was describing a gap in the wrong place. What `update`\n * genuinely needs beyond `disconnect` is nothing: the parent-key filter that\n * keeps it off another parent's row is the same one, and the payload is the\n * child's business.\n *\n * `updateMany` stays refused because it names a *predicate* rather than a\n * row, which is the half of the line this file draws that has not moved.\n */\n /**\n * `set` — replace the whole set with the named rows.\n *\n * The one supported operand that acts on rows the **call** did not name: it\n * disconnects whatever is currently linked before connecting what was asked\n * for. That is the half of this file's line it appears to fail, and #83\n * already answered how — its implicit many-to-many `set` had the identical\n * problem and the fix was to give the disconnect a *lookup*: read the linked\n * rows through the child's own `findMany`, and clear only the ones the\n * caller can see.\n *\n * So `set` means **\"replace the set I can see\"**. With no policy on the child\n * every row is visible and it is Prisma's `set` exactly; with one, a row the\n * caller cannot see stays attached rather than being silently detached —\n * which is the same choice `disconnect` makes one operand over, and the\n * opposite of what an unscoped delete would do.\n *\n * Three measured details that are not obvious from the name:\n *\n * set [one of two] the unnamed row's key becomes null, the named stays\n * set [] every linked row is detached\n * set [another parent's row] it is repointed here, as `connect` does\n * set [a row that does not exist] silently ignored — no error\n *\n * The last is why the connect half is an `updateMany` rather than the\n * `update` a nested `connect` uses: Prisma does not raise here, and matching\n * that means not raising either.\n *\n * Both halves write the child's foreign key, so `set` inherits #98 exactly as\n * `connect` does: a child whose policy scopes on that column is refused by\n * the scope-escape guard, because it cannot tell a column the ORM wrote from\n * one the caller did. #99 fixes that for every relation operand at once, and\n * this needs no change when it lands.\n *\n * **The clearing half stopped inheriting it and the linking half must not,\n * which is measured rather than tidy.** `clearLinks` names the column as the\n * ORM's, because a nested `create` on an occupied to-one needs the same clear\n * and would otherwise be refused for a write nobody made. Naming it on the\n * *link* too makes `set` succeed — and succeed wrongly: the clear nulls the\n * key, which puts the row outside the very scope (`{ folderId: 2 }`) the link\n * then has to select it by, so the row is detached and never re-attached. A\n * silent half-write in place of a loud refusal. Left refused until #99 can\n * answer the scope as well as the guard.\n */\n /**\n * `updateMany` and `deleteMany` — a **filter**, applied to this parent's rows.\n *\n * These were the last two refused on the \"names a predicate rather than a\n * row\" reading of #94's line, and that reading was too strong. What the line\n * is really asking is whether there is a `where` the child's scope can be\n * `AND`ed into — and a predicate is exactly that. Both operations are in\n * `SCOPABLE`, so routing them through the child's own `$exec` gives the scope\n * on which rows match, and `updateMany` gets `onUpdate` and the scope-escape\n * guard over its payload, the same way #101's `update` does.\n *\n * The parent key goes into the filter for the same reason it does everywhere\n * else here: Prisma applies these to *this* parent's children only, verified\n * before implementing, and without it a `deleteMany: {}` would empty the\n * table.\n *\n * **The two operands are shaped differently**, which is easy to get backwards:\n *\n * updateMany: { where: { … }, data: { … } }\n * deleteMany: { … } the filter directly\n *\n * `upsert` stays refused, and its reason is the one that has not moved: it\n * needs to know which branch ran from inside a nested step, which neither\n * half of it provides.\n */\n /**\n * `upsert` — find by a unique key **within this parent's rows**, update it or\n * create it.\n *\n * Its refusal said it *\"needs a third thing neither half has: deciding which\n * branch ran, from inside a nested step\"*. It does not: the lookup decides\n * the branch, exactly as `connectOrCreate` has decided one since #94. That is\n * the sixth `REFUSED` reason in this series to describe machinery that was\n * already there.\n *\n * **Scoped to this parent, which is Prisma's own semantics and not an\n * embellishment** — measured, because it is the detail that decides what the\n * operand means:\n *\n * upsert a row belonging to another parent\n * -> Unique constraint failed on the fields: (`publicId`)\n *\n * Prisma looks only among *this* parent's children, does not find it, takes\n * the create branch, and collides. So the conjunction that keeps every other\n * filter operand on this parent is what produces the right branch here, not\n * merely what keeps it safe.\n */\n /**\n * **The to-one reaches this same body, and it needed nothing added.** Its\n * `where` is optional — `ProfileUpsertWithoutUserInput` is\n * `{ update, create, where? }` — so `conjoin(undefined, link)` is the link\n * alone and the lookup finds the single connected child. Measured on both\n * branches:\n *\n * no child, no `where` -> the create branch runs *and stamps the\n * foreign key* — Profile { bio: \"created\",\n * userId: 1 }\n * child present, no `where` -> the update branch runs against it\n * child present, `where` matching nothing\n * -> the create branch runs and collides:\n * P2002, \"Unique constraint failed on the\n * fields: (`userId`)\"\n *\n * The third is the note above transposed to the foreign side, and it is the\n * one to-one nested-write miss that is *not* P2025. It is left to happen\n * rather than pre-empted: the create is what Prisma runs, so surfacing\n * `UniqueConstraintError` from it is agreement, where refusing early would be\n * a different error for the same query.\n */\n if (key === \"upsert\") {\n assertUpsertOperand(\n schema,\n relation,\n child,\n operand,\n operation,\n relation.kind === \"many\",\n );\n\n out.after.push({\n relation: relation.name,\n operation: \"upsert\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n for (const entry of listOf(at(args)) as Record<string, unknown>[]) {\n const where = conjoin(entry.where, childLink(link, parent));\n\n const hit = (await executor.exec(\n relation.model,\n \"findFirst\",\n { where, select: keySelect(childFields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (hit) {\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where, data: entry.update },\n // NOT pre-scoped: the child's `onUpdate` and scope-escape guard\n // judge the payload, as they do for a nested `update`.\n false,\n );\n continue;\n }\n\n await executor.exec(\n relation.model,\n \"create\",\n {\n // The foreign key is ours, as it is for every create here.\n data: { ...(entry.create as object), ...childLink(link, parent) },\n select: keySelect(childFields),\n },\n false,\n );\n }\n },\n });\n return;\n }\n\n if (key === \"updateMany\" || key === \"deleteMany\") {\n const updating = key === \"updateMany\";\n assertManyOperand(schema, relation, operand, key, operation);\n\n out.after.push({\n relation: relation.name,\n operation: key,\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const operandAt = at(args) as Record<string, unknown>;\n const filter = updating ? operandAt?.where : operandAt;\n\n // **`AND`, not a spread.** A spread lets the parent key *overwrite* a\n // caller filter naming the same column: `deleteMany: { userId: 9 }` on\n // this parent's relation became `{ userId: <this parent> }`, so a query\n // asking for children belonging to somebody else deleted every one of\n // this parent's instead. Silent, and in the deleting direction.\n //\n // Prisma conjoins — measured, because the whole question is what it\n // does rather than what is tidy:\n //\n // deleteMany { userId: <other> } -> nothing deleted\n //\n // Conjoining also keeps the parent restriction *unforgeable* while\n // letting the caller's predicate narrow, which is exactly what\n // `withScope` does for a policy fragment and for the same reason.\n const where = conjoin(filter, childLink(link, parent));\n\n await executor.exec(\n relation.model,\n key,\n updating ? { where, data: operandAt?.data } : { where },\n // NOT pre-scoped. The child's scope narrows which rows match, and for\n // `updateMany` its `onUpdate` and scope-escape guard judge the\n // payload — which is the whole reason these are expressible.\n false,\n );\n },\n });\n return;\n }\n\n if (key === \"set\") {\n assertNamedRows(schema, relation, child, operand, \"set\", operation);\n assertDisconnectable(child, relation, childFields, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.set`,\n });\n\n out.after.push({\n relation: relation.name,\n operation: \"set\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const attach = childLink(link, parent);\n\n await clearLinks(\n relation.model,\n childFields,\n valuesOf(parent, parentFields),\n executor,\n );\n\n for (const entry of listOf(at(args))) {\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where: entry as object, data: attach },\n false,\n );\n }\n },\n });\n return;\n }\n\n if (key === \"update\") {\n assertNamedUpdates(\n schema,\n relation,\n child,\n operand,\n operation,\n relation.kind === \"many\",\n );\n\n out.after.push({\n relation: relation.name,\n operation: \"update\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const list = listOf(at(args));\n\n for (let index = 0; index < list.length; index++) {\n const entry = list[index] as Record<string, unknown>;\n // The caller's key *and* the link, so an `update` cannot reach a row\n // attached to a different parent — the same filter `delete` uses,\n // and it does the same two jobs. `AND` rather than a spread for the\n // reason `updateMany` documents: a key naming the foreign column\n // itself would otherwise be overwritten rather than honoured.\n const where = conjoin(entry.where, childLink(link, parent));\n\n const found = (await executor.exec(\n relation.model,\n \"findFirst\",\n { where, select: keySelect(childFields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (!found) {\n // `RecordNotFoundError`, not `UnsupportedQueryError`: nothing here\n // is unsupported, the row simply is not there. Prisma agrees —\n // P2025, *\"depends on one or more records that were required but\n // not found\"* — and the differential harness compares the failure\n // *kind* precisely so a refusal cannot pass as agreement with a\n // miss. This one was `other` against Prisma's `notFound` until the\n // harness said so.\n //\n // **Fatal on the to-one too, which was the open question and is\n // now measured.** The worry was that a to-one `update` naming a\n // non-matching `where` might be a no-op there, which would have\n // made this branch wrong for one `kind` and forced the two apart.\n // It does not: with a child present and `where: { bio: \"nope\" }`\n // Prisma raises P2025 — *\"No 'Profile' record was found for a\n // nested update on one-to-one relation 'ProfileToUser'\"* — with\n // wording identical to the no-child case, and the parent's own\n // assignments roll back with it. Absent and not-matching are one\n // condition to Prisma, so they stay one error here.\n throw new RecordNotFoundError(relation.model, \"update\");\n }\n\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where, data: entry.data },\n // NOT pre-scoped, and this is the whole reason `update` is\n // expressible: the child's own policies run over `data` — its\n // `onUpdate` defaults, its scope-escape guard refuses a caller\n // naming a scoped column — because they have not run yet.\n false,\n );\n }\n },\n });\n return;\n }\n\n if (key === \"disconnect\" || key === \"delete\") {\n const deleting = key === \"delete\";\n if (!deleting) {\n // Before any boolean normalisation would matter, and it has to be:\n // Prisma leaves `disconnect` out of the input type *entirely* when the\n // child's foreign key is required, so even `disconnect: false` is\n // rejected there — *\"Unknown argument `disconnect`. Did you mean\n // `connect`?\"*, with the available options listed as create /\n // connectOrCreate / upsert / connect / update. The refusal is on the\n // **key**, not on the value, and this one already reads only the schema.\n assertDisconnectable(child, relation, childFields, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.disconnect`,\n });\n }\n\n /**\n * **A to-one names a filter here; a to-many names rows by unique key.**\n *\n * `ProfileUpdateOneWithoutUserNestedInput` spells both operands\n * `ProfileWhereInput | boolean`, and it means it — measured:\n * `delete: { bio: \"seed\" }` is accepted with no `@unique` anywhere near\n * `bio`, and it deletes the connected row. Running `matchUniqueKey` on this\n * path would therefore refuse a query Prisma answers, which is why\n * `assertToOneFilter` replaces `assertNamedRows` rather than joining it.\n */\n if (relation.kind === \"many\") {\n assertNamedRows(schema, relation, child, operand, key, operation);\n } else {\n assertToOneFilter(\n schema,\n relation,\n child,\n spelledOperand,\n key,\n operation,\n );\n }\n\n out.after.push({\n relation: relation.name,\n operation: key,\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const list = listOf(at(args));\n\n for (let index = 0; index < list.length; index++) {\n // The caller's key *and* the link, so neither operand can reach a row\n // attached to a different parent. `AND` rather than a spread — see\n // `updateMany`.\n const where = conjoin(list[index], childLink(link, parent));\n\n if (!deleting) {\n await executor.exec(\n relation.model,\n \"updateMany\",\n { where, data: nullKey(childFields) },\n // NOT pre-scoped: clearing a foreign key is a write to the child,\n // so the child's scope decides which rows are reachable.\n false,\n // ...but the columns are *ours*: the caller wrote `disconnect:\n // { id }` and the ORM chose to null the key. Without this a child\n // scoped on its own foreign key is refused for a write it never\n // made — the same case as `connect`, see #98 and\n // `ormAuthoredFields`.\n childFields,\n );\n continue;\n }\n\n const found = (await executor.exec(\n relation.model,\n \"findFirst\",\n { where, select: keySelect(childFields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (!found) {\n /**\n * **Two misses, two errors — and this is the third time this exact\n * mis-classification has had to be corrected** (see the notes at\n * `planOwningSide`'s `update` and at this file's own `update`\n * miss).\n *\n * On a to-one the caller named no row: `delete: true` means the\n * connected child, and there is either one or there is not.\n * Reporting *\"the row named by `true` is not connected\"* would be\n * nonsense to read, and worse it classifies as `other` where Prisma\n * answers P2025 — *\"No 'Profile' record was found for a nested\n * delete on one-to-one relation 'ProfileToUser'\"* — so the\n * differential harness would score a refusal as agreement with a\n * miss. Measured on both spellings: `delete: true` with no child\n * and `delete: { bio: \"nope\" }` with a child present give the same\n * P2025, so one error covers both.\n *\n * **`disconnect` does not come through here at all, and that\n * asymmetry is Prisma's.** A disconnect that matches nothing —\n * `disconnect: true` with no child, or a filter matching none — is\n * a *silent no-op* that still returns the parent, measured both\n * ways. The two operands share this body but must not share their\n * miss handling, which is why only `deleting` reaches this branch.\n */\n if (relation.kind !== \"many\") {\n throw new RecordNotFoundError(relation.model, \"delete\");\n }\n\n throw new UnsupportedQueryError(\n `data.${relation.name}.delete`,\n schema.name,\n operation,\n `the row named by ${JSON.stringify(list[index])} is not ` +\n `connected to this ${schema.name}. Prisma raises here too, ` +\n `rather than deleting a row belonging to somebody else.`,\n );\n }\n\n await executor.exec(\n relation.model,\n \"deleteMany\",\n { where },\n // NOT pre-scoped, for the reason above — and `deleteMany` rather\n // than `delete` because the `where` carries the link as well as the\n // unique key, which `delete` refuses as a non-unique target.\n false,\n );\n }\n },\n });\n return;\n }\n\n /**\n * `create` — insert the child, with this row's key stamped onto it.\n *\n * **On a to-one the new row has to displace the old one, and Prisma\n * *detaches* the incumbent rather than deleting it** (#360). Measured, with\n * user 1 already carrying a profile:\n *\n * user.update({ data: { profile: { create: { bio: \"second\" } } } })\n * -> (\"seed\", null) the incumbent, orphaned and still in the table\n * (\"second\", 1) the new row takes the link\n *\n * The orphaning is the half that is not guessable, and getting it wrong in\n * the other direction — deleting the displaced row — is silent data loss\n * wearing the same green test. So the differential reads the table back\n * rather than only checking that the call returned.\n *\n * Without the detach the insert simply collides: the child's foreign key\n * carries the `@unique` that makes the relation a to-one, so this was a\n * `UniqueConstraintError` on a call Prisma answers. `create` survived #354\n * because that change was about the operands refused *by name* on this side,\n * and `create` was never one of them — against an *empty* to-one it has\n * always been correct, and no fixture had a to-one whose key is on the child\n * until #358 added one.\n *\n * **`clearLinks`, so the scoping consequence is the same one `set` has** —\n * which is why the two share it. A child hidden by the caller's policies is\n * not detached, and the incumbent then wins the unique key: a\n * `UniqueConstraintError` rather than a silent detach of a row the caller\n * cannot see. Conservative in the direction this file always chooses.\n *\n * A to-many displaces nothing — clearing every child before a nested `create`\n * would be a `set: []` nobody asked for — which is half of what `displaces`\n * decides; see it for the other half and for which operands share this.\n */\n if (key === \"create\") {\n out.after.push({\n relation: relation.name,\n operation: \"create\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n // No row means the statement matched nothing; `update` and `delete`\n // raise before this runs, so there is nothing to attach to.\n if (!parent) return;\n\n // Runs on a parent `create` too, where nothing can be linked yet and it\n // finds nothing. Deliberately not skipped by operation: gemi does not\n // enable SQLite's foreign-key pragma, so \"a row that was just inserted\n // has no children\" is a property of the database's enforcement rather\n // than of the ORM — and a correctness argument resting on a pragma is\n // the kind that holds until someone reads it. One read, on a path that\n // already runs several.\n if (displaces) {\n await clearLinks(\n relation.model,\n childFields,\n valuesOf(parent, parentFields),\n executor,\n );\n }\n\n for (const item of listOf(at(args))) {\n await executor.exec(\n relation.model,\n \"create\",\n {\n // The foreign key is set by us, not by the caller: a nested create\n // that also named it would be describing two different parents.\n data: { ...(item as object), ...childLink(link, parent) },\n // Nothing reads the result, and the narrowest select keeps the\n // returned payload from growing with the child's column count.\n select: keySelect(childFields),\n },\n // NOT pre-scoped — the child's `onCreate` is what scopes this row.\n false,\n );\n }\n },\n });\n return;\n }\n\n /**\n * `createMany`: the same rows as a nested `create`, in **one statement**.\n *\n * The biggest single item on #65 — parent-and-children in one call — and the\n * work is sequencing rather than SQL: `compileCreateMany` already exists, and\n * the parent's `RETURNING` already yields the key the children need. What this\n * step adds is running it once with the key stamped onto every row, instead of\n * once per row.\n *\n * That difference is the point. A nested `create` of forty rows is forty\n * statements; this is one, which is what makes the shape worth porting rather\n * than rewriting into a transaction with explicit foreign keys.\n */\n if (key === \"createMany\") {\n // The mirror of `planOwningSide`'s guard: that one catches a to-one whose\n // foreign key is on *this* row, this one catches a one-to-one whose key is\n // on the child. Same conclusion, different direction, and both reachable.\n if (relation.kind !== \"many\") {\n throw new UnsupportedQueryError(\n `data.${relation.name}.createMany`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one, so there is nothing to create many ` +\n `of. Prisma does not accept it here either.`,\n );\n }\n\n assertCreateManyOperand(schema, relation, operand, operation);\n\n out.after.push({\n relation: relation.name,\n operation: \"createMany\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const items = listOf(at(args)?.data).map((item) => ({\n // Same rule as the nested `create` beside this one: the foreign key\n // is ours to set, not the caller's. Prisma leaves it out of the\n // nested input type entirely, so a row naming it is describing a\n // different parent than the call is.\n ...(item as object),\n ...childLink(link, parent),\n }));\n\n // **No short-circuit on an empty list**, and that is worth the round\n // trip it costs.\n //\n // Returning early here would skip the child's `$exec`, and with it the\n // child's *policies* — so whether the ORM refuses a misconfigured\n // policy would depend on the length of an array at run time. A model\n // carrying a `scope` with no `onCreate` is refused on the call with one\n // row and accepted on the call with none, which means the\n // misconfiguration hides behind data that happens to be empty in\n // development and reports itself on the first request whose list is\n // not. Nothing is written either way, so it is not a leak — it is a\n // refusal that arrives late, which is the thing the rest of the\n // compiler is arranged to prevent by deciding everything from the\n // argument *shape*.\n //\n // The cost is one `select … where false`, which is what\n // `compileCreateMany` emits for an empty list. Prisma does accept the\n // empty list and write nothing — verified — and so does this.\n await executor.exec(\n relation.model,\n \"createMany\",\n { data: items },\n // NOT pre-scoped. `createMany` is in the set an `onCreate` applies\n // to, and it applies per row — so the child's policy stamps the\n // tenant column onto every one of these, exactly as it would for a\n // top-level `createMany`.\n false,\n );\n },\n });\n return;\n }\n\n /**\n * `connectOrCreate` on this side is the pair of branches the owning side has,\n * with `connect` spelled as an update of the child's foreign key.\n *\n * Both branches go through the child's own `$exec`, so both are scoped by the\n * child's policies — and they have to be, in opposite directions: an\n * unscopeable *update* would re-parent another tenant's row, and an unscoped\n * *read* would let a hit reveal that a row with that key exists. Scoped, a\n * hidden row reads as absent and the call creates its own, which is the same\n * answer the caller would get if it truly did not exist.\n */\n if (key === \"connectOrCreate\") {\n // `relation.kind === \"many\"`, not a hardcoded `true`. This side is reached\n // by both kinds — that is the whole of #116 — so a literal here told\n // `assertConnectOrCreateOperand` that a to-one takes a list, and its array\n // guard was unreachable from the one direction that needed it. The outer\n // to-one guard above now refuses the array first; this keeps the function\n // honest about which relation it was asked about rather than relying on\n // the order of two checks.\n assertConnectOrCreateOperand(\n schema,\n relation,\n child,\n operand,\n operation,\n relation.kind === \"many\",\n );\n\n out.after.push({\n relation: relation.name,\n operation: \"connectOrCreate\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const list = listOf(at(args));\n\n for (let index = 0; index < list.length; index++) {\n const item = list[index] as Record<string, unknown>;\n\n const found = (await executor.exec(\n relation.model,\n \"findUnique\",\n { where: item.where, select: keySelect(childFields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (found) {\n // **The row is already this parent's, so there is nothing to do.**\n //\n // Free here in a way it is not for the bare `connect` below: the\n // `findUnique` above already selected the child's foreign key, so\n // the comparison costs no statement. `connect` has no such read —\n // giving it the same short-circuit means buying a lookup, which is\n // why it is #372's question rather than this branch's.\n //\n // Without this the pair below is a **clear followed by a repoint of\n // the row the clear just nulled**, and on a child scoped by that\n // same foreign key the clear puts it outside the scope the repoint\n // selects it through — so the operand raises `RecordNotFoundError`\n // on a call that should change nothing. Net-nothing either way for\n // an unscoped child, which is why it stayed hidden; the scoped one\n // is where the wasted statement becomes a wrong answer.\n //\n // `displaces` gates it because that is the only shape the clear\n // runs in. On a to-many there is no clear, so the repoint is one\n // redundant `update` writing the value already there — measured to\n // agree with Prisma, and skipping it would be an unmeasured change\n // to a branch this issue is not about.\n if (\n displaces &&\n childFields.every((field, index) =>\n sameKey(found[field], parent[parentFields[index]]),\n )\n ) {\n continue;\n }\n\n // The hit branch **is** a connect, so it displaces what is linked\n // exactly as the bare operand does (#361) — and the miss branch\n // below does not, which is Prisma's own split rather than a\n // shortcut here. Measured on one fixture: `connectOrCreate` hitting\n // a row orphans the incumbent and takes the link, while the same\n // call missing collides on the child's unique key. See `displaces`.\n if (displaces) {\n await clearLinks(\n relation.model,\n childFields,\n valuesOf(parent, parentFields),\n executor,\n );\n }\n\n await executor.exec(\n relation.model,\n \"update\",\n {\n where: item.where,\n data: childLink(link, parent),\n select: keySelect(childFields),\n },\n // NOT pre-scoped, for the reason the bare `connect` below is not:\n // this repoints an existing child, so the child's scope decides\n // which rows are reachable.\n false,\n // ...and the column is *ours*, the same one and for the same\n // reason (#98). Left off here while `connect` carried it, so one\n // operand spelled two ways answered a child scoped on its own\n // foreign key differently: `connect` went through and this raised\n // `ScopeEscapeError` about a `folderId` the caller never wrote\n // (#373). The hit branch **is** a connect — the docblock above\n // says so for displacement, and provenance follows from the same\n // fact. The miss branch below needs no marker: it creates the far\n // row, so there is no caller-supplied key to tell ours apart from.\n childFields,\n );\n continue;\n }\n\n await executor.exec(\n relation.model,\n \"create\",\n {\n // The foreign key is ours, not the caller's — the same rule the\n // nested `create` above follows, and Prisma leaves it out of the\n // nested input type entirely.\n data: { ...(item.create as object), ...childLink(link, parent) },\n select: keySelect(childFields),\n },\n false,\n );\n }\n },\n });\n return;\n }\n\n // `connect` on this side means \"point that existing row at me\", which is an\n // update of the child's foreign key — not something this row's insert can do.\n //\n // Checked here rather than in the step below, for the reason `assertNamedRows`\n // gives: the step runs after the parent row is written, so a key the child\n // does not declare unwinds an insert that should never have happened. The\n // owning side has always checked its `connect` at plan time; this side had\n // not, which made the same operand answer differently depending on which\n // table the foreign key is on (#110).\n assertNamedRows(schema, relation, child, operand, key, operation);\n\n /**\n * **On a to-one this repoint has to displace what is linked already** (#361),\n * the same way the nested `create` beside it does and through the same\n * `clearLinks`. Without it the child's `@unique` foreign key rejects the\n * second link, so `connect` was a `UniqueConstraintError` on a call Prisma\n * answers by orphaning the incumbent.\n *\n * Measured across the four shapes, because only one of them diverged and the\n * other three are what kept it hidden:\n *\n * connect onto an empty to-one attaches agreed already\n * connect a child of another parent repoints it agreed already\n * connect the row already linked here writes nothing see below\n * connect onto an occupied to-one displaces the divergence\n *\n * **The third is the one the clear and the link cross on, and #361 got it\n * right in the table and wrong in the statements** (#372). `clearLinks` nulls\n * the very row the caller named and the repoint puts the key straight back,\n * so the committed state agrees — and that is all `M15b` could see. The two\n * statements in between are not harmless. **The repoint has to re-select the\n * row by the column the clear just changed, so it fails whenever anything in\n * that `where` depends on the old value** — and there are two ways to get\n * one, not just the policy shape #372 was reported through:\n *\n * - a child whose policy scopes on *its own foreign key*\n * (`{ folderId: 2 }`) — the scope is `AND`ed into the repoint's `where`,\n * and the clear has just moved the row out of it;\n * - **no policy anywhere**, when the caller names the row *by* that foreign\n * key (`connect: { folderId: 2 }`). `assertNamedRows` accepts that\n * operand because the column is in `uniques`, which is the same fact that\n * makes the relation a to-one in the first place — and then the caller's\n * own `where` is the thing the clear invalidates.\n *\n * Either way the repoint matches nothing and the whole call raises\n * `RecordNotFoundError` naming a model and an operation the caller never\n * wrote. A call that worked before #361. The second shape is what makes this\n * a plain correctness bug rather than a policy interaction, and it is why the\n * differential can pin it at all: `M15e` in `writes.differential.test.ts` is\n * that spelling, `error` against `ok`, with no policy in it.\n *\n * So the named row is resolved first and the operand short-circuits when it\n * already points here — {@link alreadyLinked}. That is Prisma's own shape\n * rather than a repair invented for the scope: measured on 6.19.2/SQLite with\n * query logging, `folder.update({ data: { cover: { connect: { id: 30 } } } })`\n * where cover 30 already holds folder 2 logs **four selects and no `UPDATE`**\n * between its `BEGIN` and `COMMIT`, where the same call onto an occupied\n * folder logs the incumbent clear and the repoint. The lookup itself is\n * Prisma's too — every `connect` above begins by selecting the operand's row\n * with its foreign key in the projection.\n *\n * #361 declined this as \"a lookup on every `connect` to save one write on a\n * rare one\", which was the right trade for the fact it had in view. Two\n * things changed it: the write it saves is a live failure rather than a\n * redundancy, and the lookup is not on every `connect` — only where\n * `displaces` holds, which is a to-one, so every many-to-one and every\n * to-many `connect` costs exactly what it did.\n *\n * **A miss detaches nothing**, which is Prisma's answer (P2025, nothing\n * written) and is not a special case here: a row the lookup cannot find is\n * left to the repoint, which raises, and the clear is inside the transaction\n * the nested steps already run in. That covers the row that does not exist\n * and the row this caller's policies hide alike — both read as absent, and\n * both get the answer they had before this change.\n */\n out.after.push({\n relation: relation.name,\n operation: \"connect\",\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n // `displaces` is only ever true on a to-one, where the array spelling is\n // refused above — so this is one extra select at most, never one per item.\n const pending: unknown[] = [];\n for (const item of listOf(at(args))) {\n if (\n displaces &&\n (await alreadyLinked(\n relation.model,\n childFields,\n item,\n valuesOf(parent, parentFields),\n executor,\n ))\n ) {\n continue;\n }\n pending.push(item);\n }\n\n // Nothing left to link means nothing to displace either: the only row that\n // could hold this parent's key is the one the caller named, and it holds\n // it already. Returning here is what makes the call write nothing at all.\n if (pending.length === 0) return;\n\n if (displaces) {\n await clearLinks(\n relation.model,\n childFields,\n valuesOf(parent, parentFields),\n executor,\n );\n }\n\n for (const item of pending) {\n await executor.exec(\n relation.model,\n \"update\",\n {\n where: item,\n data: childLink(link, parent),\n select: keySelect(childFields),\n },\n // NOT pre-scoped. Repointing an existing row at this parent is a write\n // to the child, and the child's scope decides which rows are reachable\n // — otherwise `connect` re-parents another tenant's row.\n false,\n // ...and the columns being written are *ours*, not the caller's.\n // Without this, a child whose policy scopes on its foreign key is\n // refused for a write it never made — see #98 and\n // `ormAuthoredFields`.\n childFields,\n );\n }\n },\n });\n}\n\n/**\n * What an implicit many-to-many accepts, and how it differs from\n * {@link SUPPORTED} — which is the ordinary-relation set.\n *\n * **The two must be reconciled deliberately.** `planOne` checks `link.join`\n * first and returns, so this path never consults `SUPPORTED` at all: the sets\n * drift without anything failing to compile and without a test noticing, and\n * they did — #83 landed this one while four branches were adding to the other,\n * none of which could see it from inside itself.\n *\n * **The gaps are unimplemented, not by design, and that is measured rather than\n * reasoned.** An earlier version of this comment claimed the split was \"the\n * link versus the far row\" — operands about the pair work here, operands about\n * the far row do not. It is a tidy rule and it is wrong. Prisma offers five of\n * the six through an implicit m-n:\n *\n * update OK the far row is updated\n * delete OK the far row is deleted, not just the pair\n * deleteMany OK\n * updateMany OK\n * connectOrCreate OK\n * createMany Unknown argument — Prisma refuses it here too\n *\n * So `delete` through a join table really does mean deleting the far row, which\n * is the opposite of what that rule predicted. Only `createMany` is a genuine\n * refusal, and it is Prisma's rather than ours.\n *\n * `connectOrCreate` is implemented here because #83 already had both of its\n * halves — `connect` inserts a pair for an existing row, `create` writes the\n * row and its pair — so it is those two selected by a lookup. The remaining\n * four reach the far row *through* the pairs, which is a second hop this path\n * does not have yet; {@link JOIN_TABLE_REFUSED} says so in those terms rather\n * than inventing a principle.\n *\n * `set` is the one operand with **two implementations** — this file's\n * join-table version from #83 and the ordinary-relation one — and they agree\n * because both were reasoned to \"replace the set I can see\" independently, not\n * because they share anything. Worth knowing when either is changed.\n */\nconst JOIN_TABLE_SUPPORTED = new Set([\n \"connect\",\n \"connectOrCreate\",\n \"disconnect\",\n \"set\",\n \"create\",\n]);\n\n/**\n * Why each ordinary-relation operand is not offered through a join table.\n *\n * Same shape as {@link REFUSED}, and for the same reason: \"not implemented\" is\n * much less useful than knowing whether the thing you reached for is a rewrite\n * or a wait — and here most of them are neither, they are a different operation\n * wearing the same name.\n */\nconst JOIN_TABLE_REFUSED: Record<string, string> = {\n // Prisma's own refusal, not this ORM's — the one entry here that is a\n // decision rather than a gap, and it is not gemi's decision.\n createMany:\n `Prisma does not offer 'createMany' through an implicit many-to-many ` +\n `either — it reports it as an unknown argument. Use 'create', which writes ` +\n `the row and its pair.`,\n // The four that reach the far row through the pairs. Prisma implements all\n // of them; this path does not have the second hop yet.\n update:\n `Reaching the far row means reading the pairs first, which this path does ` +\n `not do yet. Update the related model directly, filtered by its own key.`,\n updateMany:\n `As 'update': it needs the pairs read before the far rows can be matched.`,\n delete:\n `It deletes the far row rather than the pair — Prisma does this through a ` +\n `join table too — and reaching it means reading the pairs first, which ` +\n `this path does not do yet. Use 'disconnect' to remove the link, or delete ` +\n `the row through its own model.`,\n deleteMany:\n `As 'delete': the far rows have to be found through the pairs first.`,\n};\n\n/**\n * Writes through Prisma's implicit many-to-many join table.\n *\n * The table has **no model**: no registered class, no generated base, no\n * `$schema` — just `_PostToTag` with an `A` and a `B` column, named from the\n * two model names in alphabetical order, with the pair as its primary key. So\n * the two operands that work for an ordinary relation have nothing to compile\n * *to*, and these statements are emitted directly, the way the read side's\n * `readPairs` already does.\n *\n * Which column is which end comes from `resolveLink`, never from declaration\n * order. That distinction is invisible on `Post` / `Tag` and wrong on a\n * self-relation, where both ends are the same model and only the *field* name\n * separates them.\n *\n * Every operand is an `after` step: the pair cannot be written until this row\n * has a key. Two of them are more than one statement — `set` deletes before it\n * inserts — and `$exec` already opens a transaction for any plan carrying\n * steps, so the whole thing is atomic.\n *\n * **The rows the pairs point at are still read and written through the child's\n * own `$exec`**, so a `connect` cannot reach a row the child's policies hide,\n * and a `create` gets the child's `onCreate`. Only the join table itself —\n * which has no model and nothing an application could scope — is written\n * directly.\n */\nfunction planJoinTable(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n link: { parentField: string; childField: string; join?: Link[\"join\"] },\n key: string,\n operand: unknown,\n operation: string,\n at: (args: any) => any,\n out: NestedWritePlanning,\n dialect: SqlDialect,\n): void {\n if (key === \"connectOrCreate\") {\n assertConnectOrCreateOperand(\n schema,\n relation,\n child,\n operand,\n operation,\n relation.kind === \"many\",\n );\n }\n\n if (!JOIN_TABLE_SUPPORTED.has(key)) {\n const why = JOIN_TABLE_REFUSED[key];\n if (why) {\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is an implicit many-to-many, and '${key}' means ` +\n `something different through a join table. ${why}`,\n );\n }\n\n throw new UnsupportedQueryError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is an implicit many-to-many. Only ` +\n `${[...JOIN_TABLE_SUPPORTED].sort().join(\", \")} are implemented ` +\n `through its join table.`,\n );\n }\n\n // `connect`, `disconnect` and `set` name existing rows by a unique key, and\n // the step below resolves them one at a time — after the parent row exists,\n // since a pair needs both ends. That made a key the child does not declare\n // refuse from mid-transaction, while the *same* operand on an ordinary\n // relation refuses from the compiler (#110). `create` names no existing row\n // and `connectOrCreate` is checked above, so those two are not this.\n if (key === \"connect\" || key === \"disconnect\" || key === \"set\") {\n assertNamedRows(schema, relation, child, operand, key, operation);\n }\n\n const join = link.join!;\n const parentField = link.parentField;\n const childField = link.childField;\n\n // `dialect.quoteIdent`, not a local helper. It does the same escaping *and*\n // rejects a NUL byte, which exists because NUL is the parameter sentinel in\n // `compile/fragment.ts`. Prisma generates these identifiers so nothing can\n // reach that check today — but this is the one file emitting SQL without the\n // `Fragment` pipeline, which makes it the one most worth holding to the rule\n // rather than the one to excuse from it.\n const quoted = (name: string) => dialect.quoteIdent(name);\n\n out.keyFields.push(parentField);\n\n out.after.push({\n relation: relation.name,\n // The operand this step implements, not a two-way split of it. This read\n // `key === \"create\" ? \"create\" : \"connect\"`, which labelled `disconnect`,\n // `set` and `connectOrCreate` as `connect` — the first of those being the\n // opposite operation. The field exists so a plan is legible from the\n // outside, so a wrong label is the whole of its cost.\n operation: key as NestedWriteStep[\"operation\"],\n async run(args, _context, executor, rows) {\n const parent = rows[0];\n if (!parent) return;\n\n const parentKey = parent[parentField];\n if (parentKey === null || parentKey === undefined) return;\n\n // `set` replaces the whole set, so what is there now goes first — but\n // **only the part of it this caller can see**.\n //\n // A bare `delete … where \"A\" = ?` removes every pair, including ones\n // pointing at children the child model's policies hide, and nothing on\n // that path consults the child. `disconnect` right below refuses the same\n // effect when it is named explicitly — it resolves through the child's\n // own `findUniqueOrThrow`, which raises for a row the caller cannot see —\n // so an unscoped `set` would make the authorization boundary disagree\n // with itself depending on which operand you reached for.\n //\n // Not a read leak: nothing comes back, and the caller cannot tell a\n // hidden link existed. It is an unscoped *write* to state they could not\n // otherwise reach, which is the thing this layer exists to prevent.\n //\n // So the existing links are read, filtered through the child's own\n // `findMany` — where its scope applies exactly as it does anywhere else —\n // and only those are deleted. `set` therefore means \"replace the set I\n // can see\", which is what every other policy in this ORM does: narrow,\n // never widen. With no policy on the child, every link is visible and\n // this is byte-for-byte the old behaviour, so Prisma parity is unchanged\n // wherever there is no policy to apply.\n if (key === \"set\") {\n const linked = (await executor.query(\n `select ${quoted(join.childColumn)} from ${quoted(join.table)} ` +\n `where ${quoted(join.parentColumn)} = ${dialect.placeholder(0)}`,\n [parentKey],\n )) as Record<string, unknown>[];\n\n const existing = Array.from(linked, (row) => row[join.childColumn]);\n\n if (existing.length > 0) {\n const visible = (await executor.exec(\n relation.model,\n \"findMany\",\n {\n where: { [childField]: { in: existing } },\n select: { [childField]: true },\n },\n // NOT pre-scoped: the child's scope is the whole point here.\n false,\n )) as Record<string, unknown>[];\n\n // One statement, not one per link. The scoped form is a `delete`\n // over an `in` list rather than a loop, because this repo counts\n // *statements*: `plans/orm/benchmarks.md` measures include trees that\n // way, and the lateral strategy exists to remove `N - 1` of them. A\n // loop here would have made `set` the one write that reintroduces\n // them — invisible on SQLite, where round trips are in-process, and\n // paid in full on Postgres, where they are not.\n //\n // Placeholders are built per length rather than bound as one array\n // parameter. `dialect.inList` does the latter on Postgres, but it\n // returns a `Fragment` and this is the one path that emits SQL\n // without that pipeline — there is no model to route the join table\n // through. The cost is one server-side plan per distinct link count;\n // the ORM's own plan cache is unaffected, since it keys on the\n // argument shape and this text never reaches it.\n const targets = Array.from(visible, (row) => row[childField]);\n\n // Every existing link points at a row this caller cannot see, so\n // there is nothing to clear and `in ()` is a syntax error on both\n // dialects. The loop this replaced degenerated to zero iterations\n // here; the single statement has to say so explicitly.\n if (targets.length > 0) {\n await runPairStatement(\n executor,\n `delete from ${quoted(join.table)} where ` +\n `${quoted(join.parentColumn)} = ${dialect.placeholder(0)} and ` +\n `${quoted(join.childColumn)} in (` +\n targets\n .map((_, index) => dialect.placeholder(index + 1))\n .join(\", \") +\n `)`,\n [parentKey, ...targets],\n );\n }\n }\n }\n\n const items = listOf(at(args));\n if (items.length === 0) return;\n\n const childKeys: unknown[] = [];\n\n for (const item of items) {\n if (key === \"create\") {\n const created = (await executor.exec(\n relation.model,\n \"create\",\n { data: item, select: { [childField]: true } },\n // NOT pre-scoped: the child's own `onCreate` is what scopes the row.\n false,\n )) as Record<string, unknown> | null;\n if (created) childKeys.push(created[childField]);\n continue;\n }\n\n /**\n * `connectOrCreate` is the two branches above selected by a lookup, so\n * it needed no new machinery here — which is why it is the one of the\n * five missing operands this change adds.\n *\n * `findUnique`, not the `findUniqueOrThrow` the `connect` path below\n * uses: a miss is the *other branch* here rather than an error. And a\n * scoped-away hit therefore takes the create branch, which is the same\n * answer the ordinary-relation `connectOrCreate` gives and closes the\n * same probe — `connect` raising where this succeeds would together\n * confirm a row the caller cannot see.\n */\n if (key === \"connectOrCreate\") {\n // The `where` was validated at plan time by\n // `assertConnectOrCreateOperand`, which the branch at the top of this\n // function runs for both relation kinds.\n const entry = item as Record<string, unknown>;\n\n const hit = (await executor.exec(\n relation.model,\n \"findUnique\",\n { where: entry.where, select: { [childField]: true } },\n false,\n )) as Record<string, unknown> | null;\n\n if (hit) {\n childKeys.push(hit[childField]);\n continue;\n }\n\n const made = (await executor.exec(\n relation.model,\n \"create\",\n { data: entry.create, select: { [childField]: true } },\n false,\n )) as Record<string, unknown> | null;\n if (made) childKeys.push(made[childField]);\n continue;\n }\n\n // `connect`, `disconnect` and `set` all name existing rows by a unique\n // key — checked at plan time above. Resolved through the child's own\n // `$exec`, so its policies decide which rows exist — otherwise a\n // connect by any unique key reaches every tenant's.\n const found = (await executor.exec(\n relation.model,\n \"findUniqueOrThrow\",\n { where: item, select: { [childField]: true } },\n false,\n )) as Record<string, unknown> | null;\n if (found) childKeys.push(found[childField]);\n }\n\n for (const childKey of childKeys) {\n if (key === \"disconnect\") {\n await runPairStatement(\n executor,\n `delete from ${quoted(join.table)} where ` +\n `${quoted(join.parentColumn)} = ${dialect.placeholder(0)} and ` +\n `${quoted(join.childColumn)} = ${dialect.placeholder(1)}`,\n [parentKey, childKey],\n );\n continue;\n }\n\n // `on conflict do nothing`, because the pair is the join table's\n // primary key and Prisma treats a repeated `connect` as a no-op rather\n // than an error. Without it the second connect of the same pair is a\n // raw driver unique violation, which is neither Prisma's behaviour nor\n // a useful one. Both dialects spell it the same way — SQLite has had it\n // since 3.24 — so this needs no dialect branch.\n await runPairStatement(\n executor,\n `insert into ${quoted(join.table)} ` +\n `(${quoted(join.parentColumn)}, ${quoted(join.childColumn)}) ` +\n `values (${dialect.placeholder(0)}, ${dialect.placeholder(1)}) ` +\n `on conflict do nothing`,\n [parentKey, childKey],\n );\n }\n },\n });\n}\n\n/**\n * One statement against a table with no model, on the connection this call\n * resolved — which is what keeps it inside the caller's transaction.\n *\n * Placeholders come from the dialect rather than being hardcoded, for the same\n * reason `readPairs` renders its statement: SQLite writes `?` and Postgres\n * `$1`, and this path has no `Fragment` pipeline to do it automatically.\n */\nasync function runPairStatement(\n executor: { query(text: string, values: unknown[]): Promise<unknown> },\n text: string,\n values: unknown[],\n): Promise<void> {\n await executor.query(text, values);\n}\n\n/**\n * `upsert`'s operand: `{ where, create, update }`, or a list of them.\n *\n * The two payloads are always required — one per branch. **The `where` is\n * required only on a to-many**, which is Prisma's own split rather than a\n * looseness: `AccountUpsertWithWhereUniqueWithoutUserInput` has `where:\n * AccountWhereUniqueInput`, while `ProfileUpsertWithoutUserInput` is\n * `{ update, create, where? }` — the to-one already knows which row it means,\n * because the parent's key names it. So the unique-key match is skipped there\n * too: a to-one `where` is a `WhereInput` filter narrowing the single linked\n * row, not a key selecting one out of many.\n *\n * Checked at plan time like every other operand here, so a missing key fails\n * when the query compiles rather than after the parent row is written.\n */\nfunction assertUpsertOperand(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n operand: unknown,\n operation: string,\n many: boolean,\n): void {\n const at = `data.${relation.name}.upsert`;\n const entries = (Array.isArray(operand) ? operand : [operand]) as unknown[];\n\n for (const entry of entries) {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n many\n ? `Expected an object with 'where', 'create' and 'update'.`\n : `Expected an object with 'create' and 'update' — on a to-one the ` +\n `'where' is optional, since the parent's key already names the row.`,\n );\n }\n\n const record = entry as Record<string, unknown>;\n const required = many\n ? ([\"where\", \"create\", \"update\"] as const)\n : ([\"create\", \"update\"] as const);\n\n for (const name of required) {\n if (record[name] === undefined) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected a '${name}' key — 'upsert' names the row to look for, ` +\n `what to write if it is there, and what to write if it is not.`,\n );\n }\n }\n\n if (!many) continue;\n\n matchUniqueKey(child, record.where, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.upsert.where`,\n });\n }\n}\n\n/**\n * The caller's filter and the parent restriction, as a conjunction.\n *\n * Never a spread. A spread merges by *key*, so a caller naming the foreign key\n * column silently replaces the restriction that keeps the operand on this\n * parent's rows — and the failure is a wider write, not an error. `AND` cannot\n * be overwritten by any key the caller chooses, and it still lets their\n * predicate narrow, which is the property `withScope` relies on for policy\n * fragments.\n *\n * An empty or absent filter contributes nothing, so the common case is the\n * restriction alone rather than `AND` of one thing.\n */\nfunction conjoin(\n filter: unknown,\n restriction: Record<string, unknown>,\n): Record<string, unknown> {\n if (\n filter === undefined ||\n filter === null ||\n typeof filter !== \"object\" ||\n Array.isArray(filter) ||\n Object.keys(filter as object).length === 0\n ) {\n return restriction;\n }\n return { AND: [filter as object, restriction] };\n}\n\n/**\n * The three shapes a link takes in an argument object, and the two questions\n * asked about its *values* — written once so that a relation joining on four\n * fields goes down the same path as one joining on one (#271).\n *\n * Before these, every site spelled the link as `{ [childField]: parent[\n * parentField] }` or `select: { [childField]: true }` by hand, in about forty\n * places across the two sides. Generalising each of them separately is how a\n * composite relation ends up correlating on every field in nine operands and on\n * the first field in the tenth — a silent wrong write, which is precisely what\n * the refusal these replace was protecting against. One function per shape\n * means the count of fields is invisible to the callers, so there is no\n * single-field spelling left for a new operand to copy.\n */\n\n/**\n * `{ <childField>: row[<parentField>], … }` — the far side's columns bound to\n * the values this row holds.\n *\n * On the foreign side that reads as \"belonging to this parent\": the child's\n * foreign key set to the parent's key. On the owning side the same call reads\n * as \"the row this one points at\": `link.parentFields` are this row's foreign\n * key and `link.childFields` are what they reference, so the object is the far\n * row's own columns. One function, because the arithmetic is identical and the\n * two sides differ only in which table the result is applied to.\n *\n * An object with several keys is a conjunction in every `where` this ORM\n * compiles, and several assignments in every `data`, so the same shape serves\n * both — which is why `create`, `connect`, `update`, `delete` and the two\n * `*Many` operands can all take it unchanged.\n */\nfunction childLink(\n link: { parentFields: string[]; childFields: string[] },\n parent: Record<string, unknown>,\n): Record<string, unknown> {\n const key: Record<string, unknown> = {};\n for (let index = 0; index < link.childFields.length; index++) {\n key[link.childFields[index]] = parent[link.parentFields[index]];\n }\n return key;\n}\n\n/** `{ <field>: true, … }` — the narrowest select that reads a whole link back. */\nfunction keySelect(fields: readonly string[]): Record<string, true> {\n const select: Record<string, true> = {};\n for (const field of fields) select[field] = true;\n return select;\n}\n\n/** `{ <field>: null, … }` — a detach, which has to clear *every* column. */\nfunction nullKey(fields: readonly string[]): Record<string, null> {\n const cleared: Record<string, null> = {};\n for (const field of fields) cleared[field] = null;\n return cleared;\n}\n\n/** The same detach spelled as *values* rather than as a `data` object. */\nfunction nullsFor(fields: readonly string[]): null[] {\n return fields.map(() => null);\n}\n\n/** The values of `fields` on `row`, positionally. */\nfunction valuesOf(\n row: Record<string, unknown> | null | undefined,\n fields: readonly string[],\n): unknown[] {\n return fields.map((field) => row?.[field]);\n}\n\n/**\n * Whether a link's columns actually name a row.\n *\n * **A partially-null composite key links nothing**, which is SQL's rule and not\n * a choice made here: `(tenantId, orderId) = (1, NULL)` is `UNKNOWN`, so the\n * join finds no row however many other columns match. Prisma agrees at the\n * type level — an optional relation over composite fields makes *all* of them\n * optional together, and `include` on a row holding `(1, NULL)` returns `null`.\n *\n * So every place that used to test one value for `null` — \"is anything linked\n * here\" — tests the whole key through this, and a half-written key reads as\n * *absent* rather than as a link to a row that does not exist. Getting this\n * backwards is what would make `clearLinks` null the key of every unlinked row\n * in the table, and `disconnect`'s filter arm read a child by a `NULL` key.\n */\nfunction isLinked(values: readonly unknown[]): boolean {\n return values.every((value) => value !== null && value !== undefined);\n}\n\n/**\n * Null the foreign-key columns of every row that currently holds `values` **and\n * that the caller can see** — the clearing half of `set`, the half a nested\n * `create` on an occupied to-one needs before it can insert (#360), and the\n * half the owning side's `connect` needs before it can repoint (#363).\n *\n * Shared rather than written three times because the *scoping* is the\n * interesting part and it has to be identical on all of them: the read goes\n * through the target model's own `findMany` un-pre-scoped, so a row that\n * model's policies hide is not detached. `set` therefore means \"replace the set\n * I can see\" (#83), the nested `create` means \"displace the child I can see\",\n * and the owning-side `connect` means \"displace the sibling I can see\" — with a\n * hidden incumbent the insert or repoint collides on the unique key instead,\n * which is the conservative answer rather than a silent detach of somebody\n * else's row.\n *\n * **`model` is a parameter rather than `relation.model` because the two\n * directions clear different tables.** On the foreign side the rows holding the\n * key belong to the *child*; on the owning side they are siblings of the row\n * being written, in the model the statement is already about. Same statement\n * pair, same scoping rule, two tables — so the only thing that varies is which\n * one, and passing it is what let #363 reuse this instead of restating it.\n *\n * The `findMany` decides whether to issue the write at all. The `updateMany`\n * would match the same rows on its own; what the read adds is that the common\n * case — nothing linked — costs a select rather than an update, and that the\n * scope is consulted through a read before anything is written.\n *\n * `fields` is ORM-authored: the caller named a row to `set`, or a payload to\n * `create`, or a row to `connect`, and the ORM chose to null these columns.\n * Without it a model scoped on one of them is refused by the scope-escape guard\n * for a write it never made — #98, and the reason `disconnect` one operand over\n * passes the same list. **Every** column of the link goes in it, because a\n * composite key is cleared by writing null to all of them and each one is as\n * much the ORM's as the first.\n *\n * **A key with a null component clears nothing** (#271), and the guard is not\n * defensive tidying. `where: { tenantId: 1, orderId: null }` matches every row\n * whose order is unset in that tenant — rows linked to *nothing*, which is the\n * opposite of the set this is asked for — and the `updateMany` behind it would\n * then write null over null across all of them. See {@link isLinked}. Nothing\n * reaches here with a null today (`displaceSibling` returns first, and the\n * foreign side reads its values out of a primary key), so this buys no\n * behaviour; it means a caller that one day does cannot silently rewrite the\n * table.\n */\nasync function clearLinks(\n model: string,\n fields: readonly string[],\n values: readonly unknown[],\n executor: RelationExecutor,\n): Promise<void> {\n if (!isLinked(values)) return;\n\n const where: Record<string, unknown> = {};\n for (let index = 0; index < fields.length; index++) {\n where[fields[index]] = values[index];\n }\n\n const linked = (await executor.exec(\n model,\n \"findMany\",\n { where, select: keySelect(fields) },\n false,\n )) as Record<string, unknown>[];\n\n if (linked.length === 0) return;\n\n await executor.exec(\n model,\n \"updateMany\",\n { where, data: nullKey(fields) },\n false,\n fields,\n );\n}\n\n/**\n * **Whether the row a `connect` named already points at this parent** — the\n * question that turns a clear-then-repoint into no statements at all (#372).\n *\n * The foreign-side twin of the `sameKey` test inside {@link displaceSibling},\n * and the same answer read from the other end of the key: on the owning side\n * the row that must not be cleared is the one being written, here it is the one\n * being named. Both exist because clearing a row and then selecting it by the\n * column just cleared is a contradiction the moment anything in that `where`\n * depends on the old value — a policy scoping on the column, or a caller who\n * named the row by it.\n *\n * **Prisma issues no write for an already-linked `connect` from either end, and\n * only this end matches that outright.** The owning side skips the *clear* and\n * still emits the repoint — {@link displaceSibling}'s docblock says so in plain\n * terms, and that residual divergence is #370's class, not something #363/#375\n * closed. Do not read the symmetry above as parity.\n *\n * **Un-pre-scoped, so the child's own policies decide what this can see** — the\n * same rule every other statement in this step follows, and it is what makes\n * the miss answer fall out rather than needing a branch. A row that does not\n * exist and a row this caller cannot see both read as absent, so both are\n * treated as \"not linked here\" and left to the repoint, which raises\n * `RecordNotFoundError` for them exactly as it did before.\n *\n * Getting that direction backwards would be the expensive mistake: a lookup\n * that ignored the scope could answer \"already linked\" for another tenant's row\n * and make the whole operand a silent no-op, which is a `connect` that reports\n * success and links nothing.\n *\n * `findUnique` rather than `findFirst` because `assertNamedRows` has already\n * run `matchUniqueKey` over this operand — the same lookup, and the same\n * spelling, that `connectOrCreate`'s hit branch uses one screen up.\n */\nasync function alreadyLinked(\n model: string,\n fields: readonly string[],\n where: unknown,\n values: readonly unknown[],\n executor: RelationExecutor,\n): Promise<boolean> {\n const named = (await executor.exec(\n model,\n \"findUnique\",\n { where, select: keySelect(fields) },\n false,\n )) as Record<string, unknown> | null;\n\n if (named === null || named === undefined) return false;\n\n // **`every`, not `some`** — the row is already linked here only if the whole\n // key matches. A composite key agreeing on one column and not the rest points\n // somewhere else entirely, and short-circuiting on it would skip a repoint\n // that has to happen. This is the one site of #386's generalisation that is\n // not a rename: `sameKey` compares a single value, so the fold belongs here.\n return fields.every((field, index) => sameKey(named[field], values[index]));\n}\n\n/**\n * **Detach the sibling that already holds this foreign-key value, so the row\n * being written can take it** — the owning side of #361's displacement, and the\n * whole of #363.\n *\n * The two directions look alike and are not the same operation. On the foreign\n * side the incumbent is a row of the *child* model, reached through\n * `planForeignSide`; here it is a row of the model the statement is already\n * writing, one `@unique` foreign key away. `clearLinks` is shared between them\n * because the statement pair and the scoping rule are identical; everything\n * below is what only this side needs.\n *\n * Measured against Prisma 6.19.2 on SQLite before it was written, with query\n * logging on. `Profile.update({ where: { id: 1 }, data: { user: { connect:\n * { id: 2 } } } })` where user 2's profile is taken issues, in order:\n *\n * select User.id where id = 2 resolve the operand\n * select Profile.* where id = 1 the row being written\n * select Profile.id, userId where userId in (2) the incumbent\n * update Profile set userId = null where id in (2) detach it\n * update Profile set userId = 2 where id in (1) take the link\n *\n * all inside one `BEGIN IMMEDIATE` / `COMMIT`. The incumbent is left in the\n * table with a null key — **orphaned, not deleted** — which is the half a fix\n * in the wrong direction turns into silent data loss wearing a green test.\n *\n * **Why the row being written is skipped: because Prisma skips it too.**\n * `connect`ing the far row a caller is already connected to writes *nothing at\n * all* — measured with logging on, the whole call is\n *\n * BEGIN IMMEDIATE / select the operand / select this row /\n * select the operand again / select this row again / COMMIT\n *\n * with no `update` in it. So this is not a departure to be justified; it is the\n * behaviour. (An earlier draft of this docblock claimed Prisma nulls the column\n * and writes the same value straight back for a net nothing. It does not, and\n * the claim survived into four places before it was measured rather than\n * reasoned about.)\n *\n * The skip matters *more* here than it would as mere parity, which is worth\n * keeping: the repoint on this side is not a statement of its own but a\n * contribution to the main statement, whose `where` has already been through\n * this model's policies. A model scoped on the foreign key would have its own\n * row put outside that scope by a clear, so the main statement would match\n * nothing and leave the row detached and never re-attached — a silent\n * half-write, #98's hazard arriving on this side, and the same argument #362\n * used to leave `set`'s *link* half not naming its column.\n *\n * **The residual divergence runs the other way and is not fixed here.** Prisma\n * makes the whole call a no-op; gemi still emits the repoint `UPDATE`, because\n * the contribution is in the SET list at compile time and cannot be withdrawn\n * at bind time. Same rows either way — it writes the value already there — but\n * on a one-to-one owner carrying `@updatedAt` gemi bumps the stamp where Prisma\n * leaves it. That is an instance of the stamp divergence #370 documented rather\n * than a new one, no fixture can see it (neither `Profile` nor `Cover` has the\n * column), and it is specific to *this* path: on a many-to-one both clients\n * issue the update and both stamp.\n *\n * **Why a `create` reads nothing.** There is no row yet, so there is no self to\n * be the incumbent and no `where` to read one through.\n *\n * **Why an absent parent detaches nothing, which is belt and braces and is\n * kept anyway.** Prisma *does* detach and then rolls the whole thing back —\n * measured on `update({ where: { id: 99 } })`, which logs the\n * `update … set userId = null`, then `ROLLBACK`, then answers P2025. gemi\n * reaches the same committed state by the same route, because `update` raises\n * `RecordNotFoundError` on a `where` that matches nothing and every plan\n * carrying a step runs in a transaction — verified by dropping this return and\n * watching `O12g` stay green. So it buys no correctness today; it buys two\n * statements on a miss, and it makes this step's effect independent of whether\n * the statement *after* it raises, which is the assumption that would be\n * expensive to have baked in silently if that ever changed.\n */\nasync function displaceSibling(\n schema: ModelSchema,\n fkFields: readonly string[],\n /**\n * The values about to be written into this row's foreign key, positionally\n * paired with `fkFields`.\n *\n * **A key with a null component displaces nothing**, which is the composite\n * generalisation of the `value === null` return this has always had rather\n * than a new rule: the row is being *un*linked, and there is no incumbent for\n * a link that is not being made. See {@link isLinked}.\n */\n values: readonly unknown[],\n /**\n * This statement's own `where`, **already through this model's policies** —\n * so the read below is pre-scoped, exactly as the `disconnect` filter arm's\n * parent read is, and for the same reason: applying them again would `AND`\n * the same predicate twice.\n */\n where: unknown,\n /** False on a `create`, where the row does not exist yet. */\n existing: boolean,\n executor: RelationExecutor,\n): Promise<void> {\n if (!isLinked(values)) return;\n\n if (existing) {\n const self = (await executor.exec(\n schema.name,\n \"findFirst\",\n { where, select: keySelect(fkFields) },\n true,\n )) as Record<string, unknown> | null;\n\n if (self === null || self === undefined) return;\n // **Every column, not the first that differs** — the skip is \"this row\n // already points at that row\", and on a composite key that is only true\n // when the whole tuple matches. Reading it as \"some column matches\" would\n // skip the clear for a sibling holding `(1, \"b\")` while this row takes\n // `(1, \"a\")`, and the repoint would then collide on the unique index the\n // caller cannot see.\n if (fkFields.every((field, index) => sameKey(self[field], values[index]))) {\n return;\n }\n }\n\n await clearLinks(schema.name, fkFields, values, executor);\n}\n\n/**\n * Whether two foreign-key values name the same row.\n *\n * Not `===`, because the two operands reach this from different places and a\n * key type can survive the trip differently. One side is read out of the\n * database through a `select`; the other is either a caller's literal — `connect:\n * { id: 2 }`, taken straight from the argument tree by the direct form — or a\n * value read back off the far model. A `BigInt` key is the case that makes this\n * concrete rather than theoretical: `2n === 2` is `false`, and answering \"these\n * are different rows\" there is what would make the clear fire on the row it is\n * meant to skip.\n *\n * The fallback is deliberately loose in the other direction too — it calls the\n * number `2` and the string `\"2\"` the same row. Harmless for every key type in\n * reach: Prisma's unique keys are `Int`, `BigInt`, `String`, `Bytes` and the\n * date types, and a `String` key whose value is `\"2\"` can only be compared\n * against another `String`, since the column it came from decides both sides.\n * Stated rather than tightened, because the tightening would have to know the\n * field's type here and the looseness has no reachable victim.\n */\nfunction sameKey(a: unknown, b: unknown): boolean {\n if (a === null || a === undefined || b === null || b === undefined) {\n return false;\n }\n return a === b || String(a) === String(b);\n}\n\n/**\n * The filter operands, which are shaped differently from each other.\n *\n * `updateMany` wraps its filter in `where` and carries a `data` beside it;\n * `deleteMany` *is* the filter. Checked at plan time, so a caller who wrote one\n * shape for the other hears about it before the parent row is written.\n *\n * `UnsupportedQueryError` here because that is what this branch has; both are\n * argument *validation* and belong in #103's `InvalidArgumentError`. They need\n * no edit when it lands — its conversion selects sites by whether their detail\n * already says what a valid value looks like, and these say `Expected an\n * object with 'where' and 'data'`.\n */\nfunction assertManyOperand(\n schema: ModelSchema,\n relation: RelationSchema,\n operand: unknown,\n key: string,\n operation: string,\n): void {\n const at = `data.${relation.name}.${key}`;\n\n if (typeof operand !== \"object\" || operand === null || Array.isArray(operand)) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n key === \"updateMany\"\n ? `Expected an object with 'where' and 'data'.`\n : `Expected an object of filters — 'deleteMany' takes the filter ` +\n `directly, not wrapped in a 'where'.`,\n );\n }\n\n if (key !== \"updateMany\") return;\n\n const record = operand as Record<string, unknown>;\n for (const required of [\"where\", \"data\"] as const) {\n if (record[required] === undefined) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected a '${required}' key — 'updateMany' names which rows to ` +\n `write and what to write to them.`,\n );\n }\n }\n}\n\n/**\n * `update`'s operand: `{ where, data }`, or a list of them on a to-many.\n *\n * `data` is *not* inspected here — it is the child's, and the child's own\n * `$exec` validates it against the child's schema and policies. Checking it\n * against this model would be checking the wrong shape.\n *\n * **On a to-one only `data` is required, and it may have been written bare.**\n * `toOneOperand` has already turned `update: { bio: \"x\" }`,\n * `update: { data: … }` and `update: { where, data }` into the one form this\n * reads, so what arrives is always `{ where?, data }` — but the `where` is\n * genuinely optional there (`UpdateToOneWithWhereWithoutUserInput` spells it\n * `where?`) and it is a filter rather than a key, so `matchUniqueKey` does not\n * run on it either.\n */\nfunction assertNamedUpdates(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n operand: unknown,\n operation: string,\n many: boolean,\n): Record<string, unknown>[] {\n const at = `data.${relation.name}.update`;\n const entries = (Array.isArray(operand) ? operand : [operand]) as unknown[];\n const out: Record<string, unknown>[] = [];\n\n for (const entry of entries) {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected an object with 'where' and 'data'.`,\n );\n }\n\n const record = entry as Record<string, unknown>;\n const required = many ? ([\"where\", \"data\"] as const) : ([\"data\"] as const);\n\n for (const name of required) {\n if (record[name] === undefined) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected a '${name}' key — 'update' names the row to write and ` +\n `the columns to write to it.`,\n );\n }\n }\n\n if (many) {\n matchUniqueKey(child, record.where, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.update.where`,\n });\n }\n\n out.push(record);\n }\n\n return out;\n}\n\n/**\n * The rows a `disconnect` / `delete` names, each by a unique key.\n *\n * Validated at plan time for the reason every operand here is: a refusal that\n * arrives mid-transaction has to unwind a parent row that should never have\n * been written.\n */\nfunction assertNamedRows(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n operand: unknown,\n key: string,\n operation: string,\n): Record<string, unknown>[] {\n const at = `data.${relation.name}.${key}`;\n const entries = (Array.isArray(operand) ? operand : [operand]) as unknown[];\n const out: Record<string, unknown>[] = [];\n\n for (const entry of entries) {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected an object naming a unique field, or an array of them.`,\n );\n }\n matchUniqueKey(child, entry, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.${key}`,\n });\n out.push(entry as Record<string, unknown>);\n }\n\n return out;\n}\n\n/**\n * A to-one `disconnect` / `delete` operand, **as the caller spelled it** — a\n * boolean, or a filter object, and nothing else.\n *\n * The counterpart of {@link assertNamedRows}, and deliberately *not* it. That\n * one runs `matchUniqueKey`, which is right where the caller is picking one row\n * out of many and wrong here: Prisma's to-one operand is a `WhereInput`, and\n * `delete: { bio: \"seed\" }` — a column with no unique index anywhere near it —\n * is accepted and deletes the connected row. Sharing `assertNamedRows` would\n * have refused that at compile time with a list of unique keys the caller never\n * had to name.\n *\n * **Run before {@link toOneOperand} rather than after it, which is what makes\n * `null` reachable at all.** That translation maps `false` to `null`, so a\n * check downstream of it sees one value for two very different calls: the\n * deliberate no-op, and an operand of a type Prisma has no arm for. This used\n * to sit downstream and pass both, and the second is the one that mattered —\n * before #359 the owning side refused everything but `true`, so `disconnect:\n * null` was an `UnsupportedQueryError` there, and widening the grammar turned a\n * refusal into silence. That is the failure class the differential suite exists\n * to pin, arrived at from the tidy direction, and it is not one to inherit on\n * the strength of the far side having it too.\n *\n * Measured, so the refusal is matching Prisma rather than being stricter than\n * it (6.19.2, SQLite): `disconnect: null` is a `PrismaClientValidationError` on\n * all three shapes it can be written against — a one-to-one from either end and\n * a many-to-one — with nothing written. `undefined` is the *absent* key and\n * stays a no-op on both clients, which is why only `null` is named here:\n * `canonicalShape` drops an undefined member outright, so `disconnect:\n * undefined` and no `disconnect` at all are already one call.\n *\n * Sound at plan time for the same reason the boolean guard is (#358):\n * `canonicalShape` records `null` as `\"null\"`, the booleans as `\"true\"` /\n * `\"false\"` and a filter by its structure, so no two of them can share a cache\n * entry and this refusal can never be decided on one call's behalf by another's.\n *\n * `InvalidArgumentError` because the argument is supported and the value is\n * wrong — the same reading `assertCreateManyOperand` uses, and the reason the\n * message names the two shapes that work instead of announcing a gap.\n */\nfunction assertToOneFilter(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n operand: unknown,\n key: string,\n operation: string,\n): void {\n if (operand === undefined) return;\n if (typeof operand === \"boolean\") return;\n if (operand !== null && typeof operand === \"object\" && !Array.isArray(operand)) {\n return;\n }\n\n throw new InvalidArgumentError(\n `data.${relation.name}.${key}`,\n schema.name,\n operation,\n `'${relation.name}' is a to-one, so '${key}' takes either a boolean — ` +\n `'true' for the connected ${child.name}, 'false' for nothing — or an ` +\n `object of filters it has to match. Prisma's operand here is ` +\n `'${child.name}WhereInput | boolean'.` +\n // Named rather than left to the list above, because `null` is the one\n // wrong value with an obvious intent: it is what an optional flag\n // degrades to, and `false` is the spelling that means what it was\n // reaching for. Prisma refuses it too, so pointing at `false` is a\n // correction and not a workaround.\n (operand === null\n ? ` 'null' is not one of them — write 'false' for the no-op. Prisma ` +\n `answers 'null' with a validation error rather than accepting it.`\n : \"\"),\n );\n}\n\n/**\n * The plan-time shape check for a to-one `update` / `upsert`, run **before**\n * {@link toOneOperand} rewrites the operand.\n *\n * Three holes it closes, all of the same kind: the to-one path dropped the\n * `matchUniqueKey` its to-many sibling runs — correctly, since Prisma's to-one\n * `where` is a `WhereInput` and not a unique key — and then put nothing in its\n * place, so the operand reached the step unexamined.\n *\n * 1. **A key the rewrite does not know is discarded silently.** The wrapper\n * branch rebuilds `{ where, data }` from the keys it recognises, so\n * `update: { data: { … }, wehre: { … } }` loses the typo and the filter\n * with it — and `conjoin(undefined, link)` is the parent link alone, so a\n * nested update the caller *guarded* runs unguarded. A write that should\n * not have happened, with nothing raised anywhere. Prisma answers `Unknown\n * argument 'wehre'`, and `assertConnectOrCreateOperand` in this file\n * already refuses extra keys for exactly this reason.\n * 2. **A `where` that is not an object is dropped by `conjoin`**, whose first\n * arm treats an array or a scalar as \"no filter\". So `upsert: { where:\n * [{ bio: \"old\" }], … }` finds the connected row and takes the *update*\n * branch, where Prisma applies the filter, matches nothing and takes the\n * *create* branch onto a unique violation. Two different rows written.\n * 3. **A non-object operand escapes to run time.** `update: null` normalises\n * to `{ where: undefined, data: null }`, which `assertNamedUpdates` passes\n * because its `data` key is present — and the failure then arrives from\n * inside the `after` step as `InvalidArgumentError('data', 'Profile',\n * 'updateMany')`, naming a model and an operation the caller never wrote,\n * after the parent row has already been written and has to be unwound.\n * Plan-time validation exists in this file precisely to prevent that.\n *\n * The payload spelling is deliberately *not* key-checked. `update: { bio: \"x\" }`\n * is the child's own `data`, so every key in it is the child's business and\n * belongs to the child's schema — checking it here would be checking the wrong\n * shape, which is the rule {@link assertNamedUpdates} states. The wrapper is\n * distinguishable because it carries a `data`, which is the same test the\n * rewrite makes one function down.\n */\nfunction assertToOneWriteOperand(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n key: string,\n operand: unknown,\n operation: string,\n): void {\n if (key !== \"update\" && key !== \"upsert\") return;\n\n const argument = `data.${relation.name}.${key}`;\n const refuse = (reason: string): never => {\n throw new InvalidArgumentError(argument, schema.name, operation, reason);\n };\n\n if (operand === null || typeof operand !== \"object\" || Array.isArray(operand)) {\n refuse(\n `Expected an object, got ${JSON.stringify(operand) ?? typeof operand}. ` +\n (key === \"upsert\"\n ? `'upsert' on a to-one takes { create, update } — and an optional ` +\n `'where' the connected ${child.name} has to match.`\n : `'update' on a to-one takes the ${child.name} columns directly, ` +\n `or { data } — and an optional 'where' the connected row has to ` +\n `match.`),\n );\n }\n\n const record = operand as Record<string, unknown>;\n const wrapper = key === \"upsert\" || record.data !== undefined;\n if (!wrapper) return;\n\n const known =\n key === \"upsert\" ? [\"where\", \"create\", \"update\"] : [\"where\", \"data\"];\n\n for (const name of Object.keys(record)) {\n if (record[name] === undefined || known.includes(name)) continue;\n refuse(\n `Unknown key '${name}'. '${key}' on a to-one takes ` +\n `${known.map((one) => `'${one}'`).join(\", \")} and nothing else, so ` +\n `'${name}' would be dropped rather than applied — a misspelled ` +\n `'where' would turn a filtered write into an unconditional one. ` +\n `Prisma refuses the same key by name.`,\n );\n }\n\n if (\n record.where !== undefined &&\n (record.where === null ||\n typeof record.where !== \"object\" ||\n Array.isArray(record.where))\n ) {\n refuse(\n `'where' has to be an object of filters — Prisma's is a ` +\n `'${child.name}WhereInput', which narrows *which* single row is ` +\n `written rather than choosing among several. Anything else is dropped ` +\n `by the conjunction that keeps this operand on the connected row, so ` +\n `the write would land unfiltered.`,\n );\n }\n}\n\n/**\n * A `disconnect` clears a foreign key, so the column has to be nullable.\n *\n * Prisma refuses it on a required relation at the type level; here the schema\n * is the only thing that knows, so the refusal says which column and why rather\n * than letting the database report a not-null violation from inside a nested\n * step.\n *\n * `owner` and `caller` are separate parameters because they are separate\n * questions, and one parameter answering both is what went wrong. The column\n * lives on whichever side holds the foreign key — the caller's row on a to-one,\n * the child's on a to-many — and that is what the *message* has to name. The\n * *structured* model is always the caller's. Passing `owner` for both meant a\n * `User.update` reported `model = \"Account\"` on the foreign side while the\n * owning side reported `User`, from the same function (#112).\n *\n * **Every column of the link, and the first required one is named** (#271).\n * Prisma makes a composite relation optional or required as a whole — it\n * refuses a mixture, *\"The fields of a relation must either all be optional or\n * all be required\"* — so on a schema Prisma accepted the columns agree and any\n * one of them answers. Checking all of them anyway costs nothing and means the\n * refusal does not depend on a validation rule enforced in another program:\n * a hand-built `ModelSchema` with a nullable `tenantId` beside a required\n * `ledgerCode` is refused here rather than nulling half a key.\n *\n * That is a claim about behaviour, so it is measured rather than asserted —\n * `ledgerSealMixed` in `fixtures.ts` is exactly that schema, and\n * `composite-relations.test.ts` names the column this refuses on. **The\n * nullable column is first there deliberately**: `[fieldNames[0]]` is what this\n * collapses to if the generalisation is undone, and over `(nullable, required)`\n * that answers *\"detachable\"*. The same fixture pins the two `displaces`\n * predicates, which generalised the same way and were equally unpinned.\n */\nfunction assertDisconnectable(\n owner: ModelSchema,\n relation: RelationSchema,\n fieldNames: readonly string[],\n caller: RefusalOrigin,\n): void {\n const required = fieldNames.find((name) => !owner.fields[name]?.nullable);\n if (required === undefined) return;\n\n throw new UnsupportedQueryError(\n caller.argument,\n caller.model,\n caller.operation,\n `'${owner.name}.${required}' is required, so there is no value to leave ` +\n `behind — a disconnected row would have to be deleted or repointed ` +\n `instead. Prisma does not offer 'disconnect' on a required relation ` +\n `either.`,\n );\n}\n\n/**\n * `connectOrCreate`'s operand: `{ where, create }`, or a list of them on a\n * to-many.\n *\n * Validated at plan time so a misspelled key fails when the query is compiled,\n * rather than after the parent row has been written and the transaction has to\n * unwind it — the same reason `createMany`'s operand is checked here.\n *\n * The `where` has to be a unique key, which is Prisma's rule and not merely\n * ours: without it the lookup matches an arbitrary row and \"connect or create\"\n * silently becomes \"connect to whichever one came back first\".\n */\nfunction assertConnectOrCreateOperand(\n schema: ModelSchema,\n relation: RelationSchema,\n child: ModelSchema,\n operand: unknown,\n operation: string,\n many: boolean,\n): Record<string, unknown>[] {\n const at = `data.${relation.name}.connectOrCreate`;\n\n if (Array.isArray(operand) && !many) {\n // **Which side holds the key is read off the relation, not assumed.** This\n // sentence used to say \"this row holds the foreign key\" unconditionally,\n // which was true of the only caller that could pass `many: false` — the\n // owning side — and false the moment the foreign side stopped hardcoding\n // `true`. `from` is non-empty exactly on the side that holds the key, the\n // same test `planOne` makes to choose between the two planners, so the two\n // cannot drift.\n const owning = relation.from.length > 0;\n\n throw new InvalidArgumentError(\n at,\n schema.name,\n operation,\n `'${relation.name}' is a to-one: ` +\n (owning\n ? `this row holds the foreign key`\n : `${child.name} holds the foreign key`) +\n `, so there is one row to point at and a list has no meaning. Prisma ` +\n `refuses an array here too — as a validation error on the argument, ` +\n `which is why this is a bad value rather than a gap.`,\n );\n }\n\n const entries = (Array.isArray(operand) ? operand : [operand]) as unknown[];\n\n if (entries.length === 0) return [];\n\n const out: Record<string, unknown>[] = [];\n\n for (const entry of entries) {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected an object with 'where' and 'create'.`,\n );\n }\n\n const record = entry as Record<string, unknown>;\n\n for (const required of [\"where\", \"create\"] as const) {\n if (record[required] === undefined) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Expected a '${required}' key — 'connectOrCreate' names the row to ` +\n `look for and the row to write if it is not there.`,\n );\n }\n }\n\n const extra = Object.keys(record).filter(\n (key) => key !== \"where\" && key !== \"create\" && record[key] !== undefined,\n );\n if (extra.length > 0) {\n throw new UnsupportedQueryError(\n at,\n schema.name,\n operation,\n `Unexpected ${extra.sort().join(\", \")} — 'connectOrCreate' takes ` +\n `'where' and 'create'.`,\n );\n }\n\n matchUniqueKey(child, record.where, {\n model: schema.name,\n operation,\n argument: `data.${relation.name}.connectOrCreate.where`,\n });\n out.push(record);\n }\n\n return out;\n}\n\n/**\n * `createMany`'s operand is `{ data }` — not the rows directly, which is the\n * one place Prisma's nested grammar adds a level.\n *\n * Checked at plan time, so a misspelled key fails when the query is compiled\n * rather than after the parent row has already been written and the transaction\n * has to unwind it.\n */\nfunction assertCreateManyOperand(\n schema: ModelSchema,\n relation: RelationSchema,\n operand: unknown,\n operation: string,\n): void {\n const at = `data.${relation.name}.createMany`;\n\n if (typeof operand !== \"object\" || operand === null || Array.isArray(operand)) {\n throw new InvalidArgumentError(\n at,\n schema.name,\n operation,\n `Expected an object with a 'data' key — the rows go inside it, not ` +\n `directly under 'createMany'.`,\n );\n }\n\n const keys = Object.keys(operand as Record<string, unknown>).filter(\n (key) => (operand as Record<string, unknown>)[key] !== undefined,\n );\n\n if (!keys.includes(\"data\")) {\n throw new InvalidArgumentError(at, schema.name, operation, `Expected a 'data' key.`);\n }\n\n for (const key of keys) {\n if (key === \"data\") continue;\n\n // `skipDuplicates` is the one a caller will actually reach for, so it gets\n // the reason instead of the generic message.\n //\n // **Scoped to the nested form on purpose.** This used to say \"at any\n // level\", which was true when it was written and stops being true the\n // moment #69 lands: a top-level `Account.createMany({ data, skipDuplicates\n // })` compiles to `on conflict do nothing` on Postgres. Naming the level\n // keeps the sentence true either way, and points at the spelling that\n // works today rather than at a wait.\n //\n // Whether the nested form should simply pass it through is a real question\n // and not this change's: the step below already calls the child's own\n // `$exec(\"createMany\", …)`, so forwarding the flag is close to free — but\n // it would need the top-level support to exist first, and until then it\n // would fail with an error about an unknown argument on a model the caller\n // did not name.\n throw new UnsupportedQueryError(\n `${at}.${key}`,\n schema.name,\n operation,\n key === \"skipDuplicates\"\n ? `'skipDuplicates' is not implemented on a *nested* 'createMany'. ` +\n `Write the children with their own '${relation.model}.createMany' ` +\n `call, which takes it.`\n : `Expected only 'data'.`,\n );\n }\n}\n\n/**\n * Prisma accepts both a single object and an array everywhere a to-many nested\n * write is legal, and the singular form is the common one on a to-one.\n */\nfunction listOf(value: unknown): unknown[] {\n if (value === undefined || value === null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * A to-one nested-write operand, rewritten in the spelling the to-many bodies\n * above already read.\n *\n * **Prisma's to-one nested input is a different grammar, not a subset of the\n * to-many one** — quoted from a generated client rather than from the docs\n * (`ProfileUpdateOneWithoutUserNestedInput`):\n *\n * update XOR<UpdateToOneWithWhereWithoutUserInput, UpdateWithoutUserInput>\n * where UpdateToOneWithWhereWithoutUserInput = { where?, data }\n * upsert { update, create, where? }\n * disconnect ProfileWhereInput | boolean\n * delete ProfileWhereInput | boolean\n * connect ProfileWhereUniqueInput\n *\n * Three of those differences would be got wrong by reading the to-many side and\n * assuming symmetry, so each is named with the measurement behind it:\n *\n * - **the `where` is optional, and it is a filter.** Not a unique key —\n * `WhereInput`, not `WhereUniqueInput` — which is why `assertToOneFilter`\n * replaces `assertNamedRows` here and `matchUniqueKey` does not run.\n * Measured: `delete: { bio: \"seed\" }` is accepted against a column with no\n * unique index and deletes the connected row.\n * - **the data may be written bare.** `update: { bio: \"x\" }` and\n * `update: { data: { bio: \"x\" } }` are one operation. The owning side\n * measured that years ago; this is the same measurement repeated on the\n * foreign side, because the owning side's said nothing about this one.\n * - **the boolean is not an empty filter.** `true` means the connected row;\n * `false` means *nothing at all*, measured — `delete: false` and\n * `disconnect: false` with a child present return the parent and leave the\n * child exactly as it was, foreign key included.\n *\n * So `true` becomes `{}`, which `conjoin` reduces to the parent link alone —\n * precisely the one connected row — and `false` becomes `null`, which `listOf`\n * reduces to `[]`, which is no statement.\n */\nfunction toOneOperand(key: string, operand: unknown): unknown {\n if (key === \"update\") {\n // A `data` key is the wrapper; anything else is the payload itself. The\n // same test `planOwningSide`'s `update` makes, deliberately — the two\n // spellings collapse to one operation, so the compiler should not have two\n // shapes of its own for them. It carries the same ambiguity, too: a child\n // with a scalar column called `data` would be read as the wrapper. Prisma's\n // own input types have that hazard by construction and it has never been\n // reachable in practice, so it is inherited rather than invented.\n //\n // **`!== undefined` rather than `in`**, and the difference is a plan-cache\n // bug rather than a style choice. `canonicalShape` drops a key whose value\n // is `undefined` (see its object branch), so `update: {}` and `update: {\n // data: undefined }` are ONE plan key. Branching on `in` gave them two\n // compilations: the first normalised and compiled, the second reached\n // `assertNamedUpdates` and was refused for a missing `data` — so whether\n // the refusal fired depended on which spelling warmed the cache. Testing\n // the value instead is what `assertNamedUpdates` itself does, one operand\n // over, and it puts both spellings on the same branch.\n //\n // This is the same defect as the `disconnect` boolean two functions down,\n // arrived at from the opposite direction: there the key was too coarse for\n // the code, here the code was finer than the key. Both are decided by\n // asking what `canonicalShape` actually records.\n if (\n operand !== null &&\n typeof operand === \"object\" &&\n (operand as Record<string, unknown>).data !== undefined\n ) {\n const record = operand as Record<string, unknown>;\n return { where: record.where, data: record.data };\n }\n return { where: undefined, data: operand };\n }\n\n if (key === \"delete\" || key === \"disconnect\") {\n if (operand === true) return {};\n if (operand === false) return null;\n return operand;\n }\n\n // `upsert` already arrives as `{ where?, create, update }`, and `create`,\n // `connect` and `connectOrCreate` are already singular. Returned untouched\n // rather than listed, so an operand added later does not silently acquire a\n // translation it was never measured for.\n return operand;\n}\n",
|
|
20
|
-
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownRelationError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport type { ModelSchema, RelationSchema } from \"../schema\";\nimport { COUNT_KEY } from \"../relation-filters\";\nimport { type Fragment, concat, sql } from \"./fragment\";\nimport { correlate } from \"./correlate\";\nimport { compileWhere } from \"./where\";\n\n/**\n * `include: { _count: { select: { accounts: true } } }` -> a correlated\n * `count(*)` in the select list.\n *\n * The last item iteration 3 listed as out of scope and never rescheduled. It is\n * the same machinery relation filters use — a correlated subquery over the child,\n * aliased so a self-relation cannot shadow the outer table — projected instead of\n * predicated:\n *\n * select …, (select count(*) from \"Account\" as \"_c0\"\n * where \"_c0\".\"userId\" = \"User\".\"id\") as \"_count.accounts\"\n *\n * One statement, no extra round trip, and no row multiplication: a `group by`\n * against a to-many would fold the parents together and a join would duplicate\n * them, which is the same reason relation filters are `exists` rather than joins.\n */\n\nexport interface CountPlan {\n /** The relation being counted, as the caller named it. */\n as: string;\n /** The projected column, aliased so `shape` can find it in the raw row. */\n column: Fragment;\n /** The alias, which is also the raw row's key. */\n alias: string;\n}\n\n/**\n * Reads `_count` out of an `include` or a `select`.\n *\n * Returns an empty list when there is none, which is the overwhelmingly common\n * case and costs one property read.\n */\nexport function planRelationCounts(\n schema: ModelSchema,\n args: any,\n dialect: SqlDialect,\n operation: string,\n): CountPlan[] {\n const container = args?.include ?? args?.select;\n if (typeof container !== \"object\" || container === null) return [];\n\n const node = container[COUNT_KEY];\n if (node === undefined || node === false) return [];\n\n const selection = readCountSelection(schema, node, operation);\n const plans: CountPlan[] = [];\n\n // Sorted for the reason every walk here is: the plan cache canonicalises key\n // order, so two argument objects differing only in key order are one entry and\n // must produce one statement.\n for (const key of Object.keys(selection).sort()) {\n const value = selection[key];\n if (value === undefined || value === false) continue;\n\n const relation = schema.relations[key];\n if (!relation) {\n throw new UnknownRelationError(\n key,\n schema.name,\n Object.keys(schema.relations),\n );\n }\n\n plans.push(\n countPlan(schema, relation, value, dialect, operation, plans.length, args),\n );\n }\n\n return plans;\n}\n\nfunction countPlan(\n schema: ModelSchema,\n relation: RelationSchema,\n node: unknown,\n dialect: SqlDialect,\n operation: string,\n index: number,\n args: any,\n): CountPlan {\n const path = `_count.select.${relation.name}`;\n\n if (relation.kind !== \"many\") {\n // Prisma only counts to-many relations, and the reason is that the answer is\n // 0 or 1 — which the relation's own nullability already says.\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n `${relation.name} is a to-one relation. Counting it can only ever ` +\n `return 0 or 1, which is what its nullability already tells you.`,\n );\n }\n\n const source = correlate(\n schema,\n relation,\n dialect,\n `_c${index}`,\n `${dialect.quoteIdent(schema.table)}.`,\n operation,\n );\n\n const where = node === true ? undefined : (node as any)?.where;\n const container = args?.include !== undefined ? \"include\" : \"select\";\n const locate = (a: any) =>\n a?.[container]?.[COUNT_KEY]?.select?.[relation.name]?.where;\n\n const filter = compileWhere(\n source.child,\n where,\n { dialect, operation, qualifier: source.qualifier },\n locate,\n );\n\n const parts: Fragment[] = [\n sql(`(select count(*) from ${source.source} where ${source.correlation}`),\n ];\n if (filter) parts.push(sql(\" and \"), filter);\n // The alias carries a dot on purpose: it cannot collide with a column, since\n // an identifier that needs quoting to contain one could not have come from the\n // schema, and it keeps the raw row self-describing when a query is logged.\n parts.push(sql(`) as ${dialect.quoteIdent(`_count.${relation.name}`)}`));\n\n return {\n as: relation.name,\n alias: `_count.${relation.name}`,\n column: concat(...parts),\n };\n}\n\n
|
|
20
|
+
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownRelationError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport type { ModelSchema, RelationSchema } from \"../schema\";\nimport { COUNT_KEY, countableRelations } from \"../relation-filters\";\nimport { type Fragment, concat, sql } from \"./fragment\";\nimport { correlate } from \"./correlate\";\nimport { compileWhere } from \"./where\";\n\n/**\n * `include: { _count: { select: { accounts: true } } }` -> a correlated\n * `count(*)` in the select list.\n *\n * The last item iteration 3 listed as out of scope and never rescheduled. It is\n * the same machinery relation filters use — a correlated subquery over the child,\n * aliased so a self-relation cannot shadow the outer table — projected instead of\n * predicated:\n *\n * select …, (select count(*) from \"Account\" as \"_c0\"\n * where \"_c0\".\"userId\" = \"User\".\"id\") as \"_count.accounts\"\n *\n * One statement, no extra round trip, and no row multiplication: a `group by`\n * against a to-many would fold the parents together and a join would duplicate\n * them, which is the same reason relation filters are `exists` rather than joins.\n */\n\nexport interface CountPlan {\n /** The relation being counted, as the caller named it. */\n as: string;\n /** The projected column, aliased so `shape` can find it in the raw row. */\n column: Fragment;\n /** The alias, which is also the raw row's key. */\n alias: string;\n}\n\n/**\n * Reads `_count` out of an `include` or a `select`.\n *\n * Returns an empty list when there is none, which is the overwhelmingly common\n * case and costs one property read.\n */\nexport function planRelationCounts(\n schema: ModelSchema,\n args: any,\n dialect: SqlDialect,\n operation: string,\n): CountPlan[] {\n const container = args?.include ?? args?.select;\n if (typeof container !== \"object\" || container === null) return [];\n\n const node = container[COUNT_KEY];\n if (node === undefined || node === false) return [];\n\n const selection = readCountSelection(schema, node, operation);\n const plans: CountPlan[] = [];\n\n // Sorted for the reason every walk here is: the plan cache canonicalises key\n // order, so two argument objects differing only in key order are one entry and\n // must produce one statement.\n for (const key of Object.keys(selection).sort()) {\n const value = selection[key];\n if (value === undefined || value === false) continue;\n\n const relation = schema.relations[key];\n if (!relation) {\n throw new UnknownRelationError(\n key,\n schema.name,\n Object.keys(schema.relations),\n );\n }\n\n // A malformed operand is refused rather than counted, and the reason is the\n // policy walk rather than tidiness. `scopeCounts` reaches for `value.where`\n // through the same `typeof value !== \"object\"` test and `continue`s past\n // anything that fails it, so an operand like `1` or `\"true\"` carries no\n // scope — while `countPlan` reads `node?.where` as `undefined` and emits a\n // perfectly good unscoped `count(*)`. That is the one disagreement between\n // the two walks that this file's arrangement is supposed to make impossible,\n // and what it leaks is a number over rows the caller cannot read.\n //\n // Refused *here* rather than taught to `scopeCounts`, because this is where\n // the same malformation on a relation node is already refused — `include:\n // { accounts: 1 }` raises rather than compiling — which is what makes the\n // identical `continue` in `applyNestedPolicies` safe.\n if (value !== true && (typeof value !== \"object\" || Array.isArray(value))) {\n throw new InvalidArgumentError(\n `_count.select.${key}`,\n schema.name,\n operation,\n \"Expected true or an object holding 'where'.\",\n );\n }\n\n plans.push(\n countPlan(schema, relation, value, dialect, operation, plans.length, args),\n );\n }\n\n // A `_count` that names no relation it will actually count — `select: {}`, or\n // every relation switched off with a flag. Refused for the same mechanical\n // reason the `_count: true` shorthand is refused on a model with nothing to\n // count, and this is the other route to that state: `resolveSelection` counts\n // `_count` as *something selected*, so an empty plan list still clears its \"at\n // least one field\" check and then projects no columns, emitting\n // `select from \"User\"` for the driver to reject with a syntax error.\n //\n // Only under `select`. An `include` carries the model's default columns, so\n // the statement stays valid and a count of nothing is merely nothing.\n if (plans.length === 0 && args?.select) {\n throw new InvalidArgumentError(\n \"_count.select\",\n schema.name,\n operation,\n \"No relations to count, and '_count' is the only thing selected. \" +\n \"Name at least one relation, or select a column beside it.\",\n );\n }\n\n return plans;\n}\n\nfunction countPlan(\n schema: ModelSchema,\n relation: RelationSchema,\n node: unknown,\n dialect: SqlDialect,\n operation: string,\n index: number,\n args: any,\n): CountPlan {\n const path = `_count.select.${relation.name}`;\n\n if (relation.kind !== \"many\") {\n // Prisma only counts to-many relations, and the reason is that the answer is\n // 0 or 1 — which the relation's own nullability already says.\n throw new UnsupportedQueryError(\n path,\n schema.name,\n operation,\n `${relation.name} is a to-one relation. Counting it can only ever ` +\n `return 0 or 1, which is what its nullability already tells you.`,\n );\n }\n\n const source = correlate(\n schema,\n relation,\n dialect,\n `_c${index}`,\n `${dialect.quoteIdent(schema.table)}.`,\n operation,\n );\n\n const where = node === true ? undefined : (node as any)?.where;\n const container = args?.include !== undefined ? \"include\" : \"select\";\n const locate = (a: any) =>\n a?.[container]?.[COUNT_KEY]?.select?.[relation.name]?.where;\n\n const filter = compileWhere(\n source.child,\n where,\n { dialect, operation, qualifier: source.qualifier },\n locate,\n );\n\n const parts: Fragment[] = [\n sql(`(select count(*) from ${source.source} where ${source.correlation}`),\n ];\n if (filter) parts.push(sql(\" and \"), filter);\n // The alias carries a dot on purpose: it cannot collide with a column, since\n // an identifier that needs quoting to contain one could not have come from the\n // schema, and it keeps the raw row self-describing when a query is logged.\n parts.push(sql(`) as ${dialect.quoteIdent(`_count.${relation.name}`)}`));\n\n return {\n as: relation.name,\n alias: `_count.${relation.name}`,\n column: concat(...parts),\n };\n}\n\n/**\n * `_count: { select: { … } }`, or the `_count: true` shorthand expanded into it.\n *\n * The shorthand was refused until #394, and the refusal gave two reasons. The\n * first — \"it names no relation, so a policy has nowhere to attach\" — was about\n * *where* the expansion happens rather than whether it can: expanded here and\n * nowhere else, the policy walk would still see `true`, `scopeCounts` would\n * return it untouched, and every count would be unscoped. So `policy.ts` expands\n * it too, through the same `countableRelations`, and this stays the compiler's\n * own total-function copy for the same reason `include: { accounts: true }`\n * compiles when the compiler is called directly: scoping is `$exec`'s job,\n * uniformly, and the compiler compiles what it is handed.\n *\n * The second reason — what it returns changes when the schema grows a relation —\n * is true, and is Prisma's semantics rather than a defect this could fix. It is\n * documented at the shorthand in `docs/orm.md` instead of being answered with a\n * refusal.\n */\nfunction readCountSelection(\n schema: ModelSchema,\n node: unknown,\n operation: string,\n): Record<string, unknown> {\n if (node === true) {\n const countable = countableRelations(schema);\n\n // A model with nothing to count. Refused rather than answered with `{}`,\n // and not only for tidiness: `select: { _count: true }` alone would then\n // project no columns at all — `resolveSelection` counts `_count` as\n // something selected, so an empty expansion passes its \"at least one field\"\n // check and emits `select from \"User\"`, which is not valid SQL.\n if (countable.length === 0) {\n throw new UnsupportedQueryError(\n \"_count\",\n schema.name,\n operation,\n `${schema.name} has no to-many relations, so there is nothing for ` +\n `'_count: true' to count.`,\n );\n }\n\n return Object.fromEntries(countable.map((name) => [name, true]));\n }\n\n if (typeof node !== \"object\" || node === null || Array.isArray(node)) {\n throw new InvalidArgumentError(\n \"_count\",\n schema.name,\n operation,\n \"Expected an object holding 'select'.\",\n );\n }\n\n const selection = (node as Record<string, unknown>).select;\n if (\n typeof selection !== \"object\" ||\n selection === null ||\n Array.isArray(selection)\n ) {\n throw new InvalidArgumentError(\n \"_count.select\",\n schema.name,\n operation,\n \"Expected an object naming the relations to count.\",\n );\n }\n\n return selection as Record<string, unknown>;\n}\n\n",
|
|
21
21
|
"import { clientSideValue, hasClientSideValue } from \"../defaults\";\nimport type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n MissingRequiredValueError,\n ReturningUnsupportedError,\n UnknownFieldError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport { jsonNullKind } from \"../json-null\";\nimport type { Operation, QueryPlan } from \"../plan\";\nimport type { FieldSchema, ModelSchema } from \"../schema\";\nimport { buildRowShaper } from \"../shape\";\nimport {\n type Binder,\n type Fragment,\n bindValues,\n concat,\n joinFragments,\n param,\n render,\n sql,\n} from \"./fragment\";\nimport { fieldParam } from \"./cast\";\nimport {\n type ForeignKeyContribution,\n type NestedWritePlanning,\n planNestedWrites,\n} from \"./nested-writes\";\nimport { planRelations, strategiesOf } from \"./plan-relations\";\nimport { type CountPlan, planRelationCounts } from \"./relation-count\";\nimport { resolveSelection, withKeyFields } from \"./select\";\nimport { matchUniqueKey } from \"./unique\";\nimport { assertListDialect, compileWhere } from \"./where\";\n\n/**\n * The write surface: `create`, `createMany`, `update`, `updateMany`, `delete`,\n * `deleteMany`, `upsert`.\n *\n * Everything here obeys the same two rules the read compiler does, and for the\n * same reasons (invariant 2): the SQL text is a pure function of the argument\n * *shape*, and every value is a bound parameter. A `create` with the same field\n * set is one plan whatever the values are.\n *\n * Two decisions worth finding here rather than inferring from the code:\n *\n * **1. Row counts come from `RETURNING`, not from driver metadata.**\n * `updateMany` and `deleteMany` return `{ count }`, and the obvious source is\n * whatever the driver reports about the statement. Measured, that source is\n * undocumented: Bun's SQLite driver leaves `affectedRows` **null** on every\n * statement and puts the number on a `count` property instead. So the count is\n * the number of rows a `RETURNING <primary key>` gives back — one statement\n * shape on every dialect, exact by construction, and dependent on nothing\n * undocumented.\n *\n * `count` has since been measured on Postgres too, and it agrees: same property,\n * same value, `affectedRows` null on both, across `update`, `delete`, `insert`,\n * a statement matching nothing and one carrying `returning`. That does not\n * change the decision here — `RETURNING` is still exact and still asks the\n * driver for nothing — but it is what lets `DB.execute` report a *raw* write's\n * rowcount, where the statement is the caller's and there is no `RETURNING` to\n * add. See `facades/DB.ts`.\n * It costs one key column per affected row on the wire, which is a real cost on\n * a very large `deleteMany`; iteration 7 owns performance and can revisit it\n * with a benchmark rather than a guess.\n *\n * **2. `createMany` fills defaults explicitly rather than grouping rows.**\n * Prisma allows rows with different key sets in one call, and a single multi-row\n * `INSERT` cannot express that directly — every row must supply every column.\n * The column list is therefore the union of every row's keys, and a row missing\n * one gets its client-side default, or `NULL` if the column is nullable. The one\n * case that cannot be filled is a column with a *database* default that some\n * rows supply and others do not: `NULL` would override the default rather than\n * request it, and the `DEFAULT` keyword is not available — SQLite rejects it\n * inside a `VALUES` list (verified: `near \"DEFAULT\": syntax error`). That case\n * is refused with an error naming the column, rather than silently written wrong.\n */\n\n// `omit` rides along wherever a payload comes back, which is every write but\n// the three that return a count — Prisma types it the same way. It is resolved\n// by `resolveSelection`, so the `RETURNING` list narrows exactly as a read's\n// column list does and the omitted column is never read.\nexport const WRITE_ARGS: Record<string, Set<string>> = {\n create: new Set([\"data\", \"select\", \"include\", \"omit\"]),\n createMany: new Set([\"data\", \"skipDuplicates\"]),\n update: new Set([\"data\", \"where\", \"select\", \"include\", \"omit\"]),\n updateMany: new Set([\"data\", \"where\"]),\n delete: new Set([\"where\", \"select\", \"include\", \"omit\"]),\n deleteMany: new Set([\"where\"]),\n upsert: new Set([\"where\", \"create\", \"update\", \"select\", \"include\", \"omit\"]),\n};\n\n/** The writes that return one row, and raise when they match none. */\nconst SINGLE_ROW = new Set([\"create\", \"update\", \"delete\", \"upsert\"]);\n\n/** The writes that return `{ count }` rather than rows. */\nconst COUNTING = new Set([\"createMany\", \"updateMany\", \"deleteMany\"]);\n\nexport function isWriteOperation(op: Operation): boolean {\n return op in WRITE_ARGS;\n}\n\nexport function compileWrite(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n assertArgs(schema, op, args);\n\n // Every write reports its result — the row, or the number of rows — through\n // `RETURNING`. Asked rather than assumed so MySQL is a named gap.\n if (!dialect.supportsReturning) {\n throw new ReturningUnsupportedError(schema.name, op, dialect.name);\n }\n\n switch (op) {\n case \"create\":\n return compileCreate(schema, op, args, dialect);\n case \"createMany\":\n return compileCreateMany(schema, op, args, dialect);\n case \"update\":\n case \"updateMany\":\n return compileUpdate(schema, op, args, dialect);\n case \"delete\":\n case \"deleteMany\":\n return compileDelete(schema, op, args, dialect);\n case \"upsert\":\n return compileUpsert(schema, op, args, dialect);\n default:\n throw new UnsupportedQueryError(\n op,\n schema.name,\n op,\n `'${op}' is not a write operation. The writes are ` +\n `${Object.keys(WRITE_ARGS).sort().join(\", \")}.`,\n );\n }\n}\n\n// --- create ----------------------------------------------------------------\n\nfunction compileCreate(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n const nested = planNestedWrites(\n schema,\n args?.data,\n op,\n (callArgs) => callArgs?.data,\n dialect,\n );\n\n const columns = insertColumns(\n schema,\n args?.data,\n nested.contributions,\n op,\n dialect,\n (callArgs) => callArgs?.data,\n );\n\n const returning = returningClause(schema, args, dialect, op, nested);\n\n const statement = concat(\n sql(`insert into ${dialect.quoteIdent(schema.table)}`),\n valuesClause([columns], dialect),\n returning.clause,\n );\n\n return plan(schema, statement, dialect, op, returning, nested);\n}\n\n// --- createMany ------------------------------------------------------------\n\nfunction compileCreateMany(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n const rows = args?.data === undefined ? [] : listOf(args.data);\n\n // Before the empty-list shortcut below, so that an unsupported argument is\n // refused whether or not there was anything to write. Prisma rejects it on\n // SQLite for an empty list too, and validation that depends on how much data\n // happened to be supplied is the kind that passes in a test and fails in\n // production.\n const ignore = skipDuplicatesClause(schema, op, args, dialect);\n\n // Prisma returns `{ count: 0 }` for an empty list without touching the\n // database. See {@link zeroCountPlan} for how that is spelled as a plan.\n if (rows.length === 0) {\n return zeroCountPlan(schema, op, dialect);\n }\n\n const grid = createManyColumns(schema, rows, op, dialect);\n\n // `insert ... default values` inserts exactly one row and has no multi-row\n // spelling: `values (DEFAULT), (DEFAULT)` is rejected by SQLite, and the\n // zero-column list leaves nothing else to repeat. So a grid with no columns\n // and more than one row would quietly insert one — a wrong row count *and* a\n // wrong `{ count }`, from a statement that succeeds.\n //\n // Only reachable on a model where every field is autoincrement, database\n // default or nullable *and* no row supplies any of them, so the template's\n // schema cannot produce it. Refused by name anyway, because a silent wrong\n // count is the failure class this file is arranged to prevent.\n if (grid[0].length === 0 && rows.length > 1) {\n throw new UnsupportedQueryError(\n \"data\",\n schema.name,\n op,\n `All ${rows.length} rows are empty and ${schema.name} has no ` +\n `client-side default to fill, so there is no column to insert. A ` +\n `multi-row insert of nothing but database defaults cannot be ` +\n `expressed on both dialects. Call create ${rows.length} times, or ` +\n `set at least one field per row.`,\n );\n }\n\n const returning = returningClause(schema, undefined, dialect, op, undefined);\n\n const statement = concat(\n sql(`insert into ${dialect.quoteIdent(schema.table)}`),\n valuesClause(grid, dialect),\n ignore ?? sql(\"\"),\n returning.clause,\n );\n\n const { text, binders } = render(statement, dialect, { model: schema.name, operation: op });\n return {\n text,\n bind: bindValues(binders),\n // The rows a conflict skipped never reach `RETURNING`, so this is the\n // number *inserted* rather than the number supplied — which is what Prisma\n // returns, and what makes the count usable for \"how many were new\".\n shape: (returned) => ({ count: returned.length }),\n };\n}\n\n/**\n * `skipDuplicates`, or `null` when the caller did not ask for it.\n *\n * The whole point is that the check and the insert are one statement. Without\n * it a caller reads first to find out which rows exist, which is a second query\n * *and* a race: between the read and the insert a concurrent importer writes one\n * of them, and the insert fails on a unique violation anyway.\n *\n * Refused on a dialect that does not offer it, naming the dialect rather than\n * saying \"yet\" — the answer there is not \"wait\", it is \"Prisma does not offer\n * this on SQLite either, so neither do we\". See `SqlDialect.ignoreConflicts`\n * for why that is a parity decision rather than a gap.\n */\nfunction skipDuplicatesClause(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): Fragment | null {\n const requested = args?.skipDuplicates;\n if (requested === undefined) return null;\n\n if (typeof requested !== \"boolean\") {\n throw new InvalidArgumentError(\n \"skipDuplicates\",\n schema.name,\n op,\n `Expected true or false, got ${JSON.stringify(requested)}.`,\n );\n }\n\n const clause = dialect.ignoreConflicts();\n if (clause === null) {\n // Refused whatever the value, which is exactly what Prisma does: on SQLite\n // it reports `skipDuplicates` as an unknown argument for `false` as well as\n // for `true`. Accepting `false` because it happens to be a no-op would make\n // the two dialects disagree about which calls are legal.\n throw new UnsupportedQueryError(\n \"skipDuplicates\",\n schema.name,\n op,\n `'skipDuplicates' is not available on ${dialect.name}. Prisma does not ` +\n `offer it there either — it is a Postgres and MySQL argument. To ` +\n `import a batch that may overlap, write the rows one at a time and ` +\n `catch UniqueConstraintError, or move this model to Postgres.`,\n );\n }\n\n return requested ? clause : null;\n}\n\n/**\n * The column grid for a multi-row insert: one `WriteColumn[]` per row, every\n * row carrying the same fields in the same order.\n *\n * The order is the *schema's*, never the first row's key order. That is not a\n * tidiness point: with the column list taken from row one and the values taken\n * per row by key order, a second row whose keys were written in a different\n * order binds its values into the wrong columns. Same types, no error, wrong\n * data — the worst shape of bug this file could have. Every value is looked up\n * by field name, and there is a test for exactly this.\n */\nfunction createManyColumns(\n schema: ModelSchema,\n rows: unknown[],\n op: Operation,\n dialect: SqlDialect,\n): WriteColumn[][] {\n const supplied = rows.map((row, index) => {\n if (typeof row !== \"object\" || row === null || Array.isArray(row)) {\n throw new InvalidArgumentError(\n `data[${index}]`,\n schema.name,\n op,\n \"Expected an object.\",\n );\n }\n\n const keys = new Set<string>();\n for (const [key, value] of Object.entries(row as Record<string, unknown>)) {\n if (value === undefined) continue;\n if (key in schema.relations) {\n // Prisma's `createMany` takes unchecked input — scalars and foreign\n // keys only. A nested write there has no defined ordering across rows.\n throw new UnsupportedQueryError(\n `data.${key}`,\n schema.name,\n op,\n \"createMany cannot contain nested writes. Use create per row.\",\n );\n }\n if (!(key in schema.fields)) {\n throw new UnknownFieldError(key, schema.name, Object.keys(schema.fields));\n }\n keys.add(key);\n }\n return keys;\n });\n\n // The union, walked in schema order so the emitted column list depends only\n // on *which* fields appear, never on how any row was written.\n const union: FieldSchema[] = [];\n for (const field of Object.values(schema.fields)) {\n const inSome = supplied.some((keys) => keys.has(field.name));\n if (inSome || hasClientSideValue(field) || suppliesEmptyList(field)) {\n union.push(field);\n }\n }\n\n for (const field of union) {\n const missing = supplied.some((keys) => !keys.has(field.name));\n if (!missing) continue;\n\n if (hasClientSideValue(field)) continue;\n if (field.nullable) continue;\n // The empty list stands in for an absent one — see `insertColumns`. It also\n // resolves the \"some rows set it and others do not\" refusal below, which\n // exists because a single `VALUES` list cannot ask for a database default\n // per row. A list needs no default asked for: `{}` is a value, so the rows\n // that omitted it get one written rather than needing the statement split.\n //\n // `suppliesEmptyList` rather than `field.isList`, which is the whole of the\n // distinction: this stands in for a list that has **nothing else** to fall\n // back on. A list with a *database-side* default still cannot be expressed\n // per row, so it falls through to the refusal below rather than silently\n // acquiring `{}` — and one with a client-side default never reaches here,\n // because `hasClientSideValue` answered above.\n if (suppliesEmptyList(field)) continue;\n\n // A database-side default that only some rows override. `NULL` would\n // *overwrite* the default rather than request it, and SQLite has no\n // `DEFAULT` keyword inside a `VALUES` list to ask for it with.\n if (field.default) {\n throw new UnsupportedQueryError(\n `data.${field.name}`,\n schema.name,\n op,\n `Some rows set '${field.name}' and others leave it to the database ` +\n `default. A single multi-row insert cannot express both. Split the ` +\n `call, or set '${field.name}' on every row.`,\n );\n }\n\n const index = supplied.findIndex((keys) => !keys.has(field.name));\n throw new MissingRequiredValueError(\n schema.name,\n `${op}.data[${index}]`,\n field.name,\n );\n }\n\n for (const field of union) {\n if (field.isList) {\n assertListDialect(schema, field, `data.${field.name}`, op, dialect);\n }\n }\n\n return rows.map((row, index) =>\n union.map((field) => {\n if (!supplied[index].has(field.name)) {\n // **`suppliesEmptyList`, not `field.isList`**, and the difference is a\n // row that comes out wrong rather than a statement that fails.\n //\n // `@default([])` and `@default([\"seed\"])` are *client-side* defaults —\n // `kind: \"value\"`, which `isClientSideDefault` admits — so `create`\n // binds the declared value through `defaultBinder`. Asking `isList`\n // here put `{}` ahead of that, so one `createMany` row omitting a\n // defaulted list wrote the empty array where `create` wrote the\n // default, and where Prisma writes the default — so `create` and\n // `createMany` disagreed about one schema, silently, in the row.\n //\n // Invisible to the differential until the fixture changed: the template\n // declared `@default([])`, where the correct value and the wrong one are\n // the same array. It now declares a non-empty default, and the\n // `createMany` case supplies it on one row and omits it on the other.\n return {\n field,\n value: suppliesEmptyList(field)\n ? emptyList(field, dialect)\n : defaultBinder(field, dialect),\n };\n }\n\n if (field.isList) {\n // Compile-time, like `insertColumns` and `assignment` — this was the\n // one write path that let a bad operand reach the binder. `[\"set\"]`\n // because an insert takes no `push`, and a refusal naming `push` on the\n // operation where it is never legal is a puzzle rather than a next step.\n assertListOperand(schema, field, (row as any)?.[field.name], op, [\"set\"]);\n }\n\n // Per row, because two rows of one `createMany` may legitimately spell\n // the same list differently — `[\"a\"]` and `{ set: [\"a\"] }`. The plan key\n // records the whole `data` array's shape, so the two are already\n // different entries and this stays a compile-time decision.\n const setForm = isListSetOperand(field, (row as any)?.[field.name]);\n\n return {\n field,\n value: valueBinder(schema, op, field, dialect, (callArgs) => {\n const value = listOf(callArgs?.data)[index]?.[field.name];\n return setForm ? value?.set : value;\n }),\n };\n }),\n );\n}\n\n// --- update / updateMany ---------------------------------------------------\n\nfunction compileUpdate(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n const many = op === \"updateMany\";\n\n // `data: null` reaches here: `requiredArgs` asks only about `undefined`, and\n // `updateAssignments` admits a nullish `data` because `upsert`'s halves may\n // legitimately be absent. It used to land on \"At least one field must be\n // updated\", which was a poor message but a refusal. Now that an empty `data`\n // reads the row back, a null one would read it back too — a malformed call\n // answered with a row. Refused on the shape rather than on a Prisma code,\n // because Prisma's client rejects this at the type level and the query engine\n // never sees it, so there is no behaviour to match here, only one to not\n // invent.\n if (args?.data === null) {\n throw new InvalidArgumentError(\n \"data\",\n schema.name,\n op,\n \"Expected an object of the fields to set, like { name: 'new name' }. \" +\n \"An empty object is accepted and reads the row back unchanged; null \" +\n \"is not.\",\n );\n }\n\n if (!many) {\n matchUniqueKey(schema, args?.where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n }\n\n // Prisma's `updateMany` takes unchecked input — scalars and foreign keys, no\n // relation keys — and rejects one with `Unknown argument 'organization'`.\n // Refused by name here for the same reason `createMany` refuses it: without\n // this the key is neither executed nor reported, since `planNestedWrites`\n // never runs and `suppliedFields` skips relation keys silently.\n //\n // This guard carries more weight than it used to. A `data` of only a relation\n // key leaves no assignment behind, so it used to land on \"At least one field\n // must be updated\" — the wrong problem, but still a refusal. Now that an\n // empty `data` is a legitimate `{ count: 0 }` (see below), the same call would\n // instead *succeed*, having written nothing and said nothing. Remove this and\n // the failure mode goes from a misleading error to no error at all.\n if (many) {\n assertNoNestedWrites(\n schema,\n args?.data,\n op,\n \"data\",\n \"updateMany cannot contain nested writes — it has no single row to \" +\n \"attach them to. Use update per row.\",\n );\n }\n\n const nested = many\n ? undefined\n : planNestedWrites(schema, args?.data, op, (callArgs) => callArgs?.data, dialect);\n\n const assignments = updateAssignments(\n schema,\n args?.data,\n nested?.contributions ?? [],\n op,\n dialect,\n );\n\n const where = compileWhere(\n schema,\n args?.where,\n { dialect, operation: op },\n (callArgs) => callArgs?.where,\n );\n\n // MEASURED (Prisma 6.19.2, SQLite): `updateMany({ where, data: {} })` is\n // accepted and answers `{ count: 0 }` — with three rows in the table and two\n // matching the filter, again with a filter matching none, and again with no\n // `where` at all. The count is a *constant*, not a row count: Prisma's own\n // answer does not depend on how many rows the filter selects, and no row is\n // touched. So there is nothing here to derive from the filter, and the\n // cheapest honest match is the `createMany([])` plan — same shape, same\n // reason, same `{ count: <rows returned> }` shaping, no special case in the\n // choke point.\n //\n // The `where` above is compiled and then discarded on this path, deliberately:\n // an unknown field in a filter must be refused whether or not there happened\n // to be anything to write, for the reason `createMany` gives for validating\n // `skipDuplicates` ahead of its own empty-list shortcut — validation that\n // depends on how much data was supplied is the kind that passes in a test and\n // fails in production.\n if (many && assignments.length === 0) {\n return zeroCountPlan(schema, op, dialect);\n }\n\n // An `update` whose `data` sets no column has no `UPDATE … SET` to emit, and\n // there are two ways to get there. `Post.update({ where, data: { tags: {\n // connect: … } } })` changes the join table and nothing on `Post` itself; and\n // `data: {}` changes nothing at all. Prisma accepts both.\n //\n // So the row is *selected* instead. The nested steps need the parent's key\n // and the caller's `select` / `include` still has to be honoured, and both\n // come from the same `returning` list — which a select produces just as well\n // as an `update … returning` does. Same plan shape, same steps, one statement\n // that happens to read rather than write.\n //\n // The empty `data` used to be refused here, on the reasoning that with\n // neither an assignment nor a nested write there is genuinely nothing to do.\n // That is true of the *write* and false of the *call*. MEASURED, same client:\n // `post.update({ where: { id: 1 }, data: {} })` returns `{ id: 1, title:\n // \"p1\" }` with the row unchanged; with `include: { tags: true }` it returns\n // the tags as well; with `select: { title: true }` it returns `{ title:\n // \"p1\" }` and no `id`. A caller who passed an `include` asked a question with\n // a defined answer, and this select is already exactly that answer — which is\n // why the fix is deleting a condition rather than adding a branch.\n //\n // A miss is still fatal and costs nothing here: `{ where: { id: 99 }, data:\n // {} }` raises P2025, and `update` is in `ORTHROW`, so `RecordNotFoundError`\n // comes out of the existing machinery.\n //\n // Reachable on every model, including one carrying `@updatedAt`. That took a\n // change in `updateAssignments`: the stamp used to be unconditional, so it\n // was itself the assignment that kept this count off zero and made the whole\n // branch dead on the models most likely to want it. Prisma does not stamp a\n // call that sets no column — measured, see that function's docblock — so the\n // two fixes are the same fix. `many` is excluded by the branch above, so this\n // is `update` alone.\n const readInstead = assignments.length === 0;\n\n const returning = returningClause(schema, args, dialect, op, nested);\n\n const statement = readInstead\n ? concat(\n sql(`select `),\n returning.selected,\n sql(` from ${dialect.quoteIdent(schema.table)}`),\n where ? concat(sql(\" where \"), where) : sql(\"\"),\n )\n : concat(\n sql(`update ${dialect.quoteIdent(schema.table)} set `),\n joinFragments(assignments, \", \"),\n where ? concat(sql(\" where \"), where) : sql(\"\"),\n returning.clause,\n );\n\n return plan(schema, statement, dialect, op, returning, nested);\n}\n\n// --- delete / deleteMany ---------------------------------------------------\n\n/**\n * ~~KNOWN DIVERGENCE~~ — **fixed**, in `Model.$exec`, once iteration 5 existed.\n *\n * `delete` with an `include` on a cascading relation used to come back with the\n * children empty: the relation reads ran *after* the delete statement, and where\n * the schema declares `onDelete: Cascade` the database had already removed them.\n *\n * This note said the fix was \"to read the relations before the delete inside one\n * transaction, which is iteration 5's to provide — and once it does, this is the\n * case to write the test for\". Both happened:\n * `templates/saas-starter/app/models/delete-include.test.ts`.\n *\n * Nothing changed *here*. A `delete` with no relation to read still compiles to\n * one statement and opens no transaction; the read-then-delete pair lives at the\n * choke point, where a transaction is available and where the decision to open\n * one belongs.\n */\nfunction compileDelete(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n if (op === \"delete\") {\n matchUniqueKey(schema, args?.where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n }\n\n const where = compileWhere(\n schema,\n args?.where,\n { dialect, operation: op },\n (callArgs) => callArgs?.where,\n );\n\n const returning = returningClause(schema, args, dialect, op, undefined);\n\n const statement = concat(\n sql(`delete from ${dialect.quoteIdent(schema.table)}`),\n where ? concat(sql(\" where \"), where) : sql(\"\"),\n returning.clause,\n );\n\n return plan(schema, statement, dialect, op, returning, undefined);\n}\n\n// --- upsert ----------------------------------------------------------------\n\n/**\n * `insert ... on conflict (<key>) do update set ...`, which both dialects\n * support and which does in one statement what Prisma's `upsert` describes.\n *\n * The alternative — read, then branch to a create or an update — is two\n * statements with a race between them: two concurrent upserts of the same key\n * both see \"absent\" and both insert, and one gets a unique violation. Since\n * there is no transaction until iteration 5, the single-statement form is not\n * just faster here, it is the only correct one.\n *\n * The conflict target comes from the `where`'s unique key, so it is a schema\n * identifier like every other. Nested writes are refused inside an upsert:\n * they would have to run before an insert that may turn out to be an update,\n * and there is nothing sensible to do with the row they created if it does.\n */\nfunction compileUpsert(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n const key = matchUniqueKey(schema, args?.where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n\n // Since Prisma 5 a `WhereUniqueInput` may carry extra non-unique filters\n // beside the key, and they narrow the match further. `update` and `delete`\n // honour that for free: their whole `where` goes through `compileWhere`.\n //\n // An upsert cannot. Its `where` becomes an `on conflict (...)` target, which\n // is a *key*, not a predicate — there is nowhere to put `deletedAt: null`.\n // Compiling only the key part would mean `where: { publicId, deletedAt: null }`\n // updating a soft-deleted row that Prisma would have left alone (Prisma would\n // find no match, attempt the create, and hit a unique violation). Refused\n // rather than narrowed, for the same reason the create-omits-the-key shape a\n // few lines down is.\n // KNOWN DIFFERENCE, and deliberate: this also refuses a `where` naming *two\n // different unique keys* — `{ id: 1, publicId: \"p\" }` — which Prisma accepts.\n // `on conflict` takes one target, so honouring both is not expressible;\n // picking `id` and ignoring `publicId` is the same silent narrowing the rest\n // of this guard exists to remove. A migrating application does hit a compile\n // error on a call Prisma ran happily, which is why it is listed under known\n // differences in the plan rather than only here.\n //\n // Note which key gets *named* in that case is an artifact of declaration\n // order — `matchUniqueKey` returns the primary key first, then `uniques` in\n // schema order — not of anything the caller wrote. Fine for a message that\n // lists every other member by name and tells the caller to choose, and not\n // worth resolving, since there is no principled way to prefer one.\n const named = key.length > 1 ? key.join(\"_\") : key[0];\n const extra = Object.keys(args.where as Record<string, unknown>).filter(\n (name) => name !== named && args.where[name] !== undefined,\n );\n if (extra.length > 0) {\n throw new UnsupportedQueryError(\n \"where\",\n schema.name,\n op,\n `The where clause carries ${extra.join(\", \")} beside the unique key ` +\n `'${named}'. An upsert compiles its where into an 'on conflict' ` +\n `target, which can only be a key, so the extra ${\n extra.length === 1 ? \"filter would be\" : \"filters would be\"\n } silently dropped. Name exactly one unique key here — or, if you meant ` +\n `to filter further, use findFirst plus update / create.`,\n );\n }\n\n for (const branch of [\"create\", \"update\"] as const) {\n assertNoNestedWrites(\n schema,\n args?.[branch],\n op,\n branch,\n \"Nested writes inside an upsert are not implemented: they would have \" +\n \"to run before it is known whether the row is being inserted or \" +\n \"updated.\",\n );\n }\n\n // `on conflict` only fires if the row being inserted actually collides on the\n // target. `upsert({ where: { id: 1 }, create: { email } })` never can — the\n // `create` supplies no `id`, so the insert mints a fresh one and the update\n // branch is unreachable. Prisma means something different by that call: find\n // by `where`, then update or create. Expressing *that* takes a read and a\n // write with no transaction between them, which is iteration 5's to give.\n //\n // So the case is refused rather than silently turned into an insert. This is\n // narrow: the ordinary shape — `where: { email }, create: { email, ... }` —\n // supplies the key and works.\n const absent = upsertAbsentConflictKey(schema, args, key);\n if (absent.length > 0) {\n throw new UnsupportedQueryError(\n \"upsert\",\n schema.name,\n op,\n `The where clause selects on ${key.join(\", \")}, but 'create' does not ` +\n `set ${absent.join(\", \")}, so 'on conflict' cannot express it. ` +\n `Model.upsert runs this as a read and a write inside one transaction ` +\n `instead; reaching this means the statement was compiled directly.`,\n );\n }\n\n const columns = withConflictKeyCheck(\n insertColumns(\n schema,\n args?.create,\n [],\n op,\n dialect,\n (callArgs) => callArgs?.create,\n ),\n schema,\n key,\n op,\n dialect,\n );\n\n // Inside the conflict clause every column read on the right of an `=` has to\n // name its table, or Postgres cannot tell the existing row from `excluded`.\n const qualifier = `${dialect.quoteIdent(schema.table)}.`;\n\n const assignments = updateAssignments(\n schema,\n args?.update,\n [],\n op,\n dialect,\n (callArgs) => callArgs?.update,\n qualifier,\n );\n\n const target = joinFragments(\n key.map((name) => sql(dialect.quoteIdent(fieldOf(schema, name).column))),\n \", \",\n );\n\n // `update: {}` is legal in Prisma and means \"leave the existing row alone,\n // but return it\". `do nothing` would return no row at all, so the row is\n // assigned to itself: an unqualified column on the right of a `do update set`\n // reads the *existing* row on both dialects.\n const effective =\n assignments.length > 0\n ? assignments\n : [\n sql(\n `${dialect.quoteIdent(fieldOf(schema, key[0]).column)} = ` +\n `${qualifier}${dialect.quoteIdent(fieldOf(schema, key[0]).column)}`,\n ),\n ];\n\n const returning = returningClause(schema, args, dialect, op, undefined);\n\n const statement = concat(\n sql(`insert into ${dialect.quoteIdent(schema.table)}`),\n valuesClause([columns], dialect),\n sql(\" on conflict (\"),\n target,\n sql(\") do update set \"),\n joinFragments(effective, \", \"),\n returning.clause,\n );\n\n return plan(schema, statement, dialect, op, returning, undefined);\n}\n\n/**\n * Which of the conflict key's fields `create` leaves unset — empty when\n * `on conflict` can express the upsert.\n *\n * **Exported because two callers must agree about it**, and a second copy of the\n * rule would be a rule that can drift: `compileUpsert` throws when it is\n * non-empty, and `Model.$exec` diverts the same calls to a read-then-write\n * before ever compiling them. If the two disagreed, either a divertable call\n * would raise or a raising call would be diverted into SQL that cannot conflict.\n */\nexport function upsertAbsentConflictKey(\n schema: ModelSchema,\n args: any,\n key: string[],\n): string[] {\n const supplied = suppliedFields(schema, args?.create);\n return key.filter((name) => !supplied.has(name));\n}\n\n/**\n * The other half of making `on conflict` mean what Prisma's `upsert` means.\n *\n * Compilation can prove the conflict key is *present* in `create`, but not that\n * it holds the same value as `where` — values do not exist at compile time, and\n * putting them there would break the plan cache. So the check happens at bind\n * time, where values are exactly what is in scope.\n *\n * Without it, `upsert({ where: { email: \"a\" }, create: { email: \"b\" }, ... })`\n * inserts \"b\" and conflicts — or does not — on \"b\", while Prisma looks for \"a\".\n * That is a silent divergence on a write, which is the failure this whole file\n * is arranged to prevent. Loud is better.\n */\nfunction withConflictKeyCheck(\n columns: WriteColumn[],\n schema: ModelSchema,\n key: string[],\n op: Operation,\n dialect: SqlDialect,\n): WriteColumn[] {\n const keyed = new Set(key);\n\n return columns.map((column) => {\n if (!keyed.has(column.field.name)) return column;\n\n const locate = whereValue(key, column.field.name);\n\n return {\n field: column.field,\n value: (args, context) => {\n const inserted = column.value(args, context);\n const selected = dialect.encode(locate(args), column.field);\n\n if (!sameEncoded(inserted, selected)) {\n throw new UnsupportedQueryError(\n \"upsert\",\n schema.name,\n op,\n `'${column.field.name}' is ${describe(selected)} in ` +\n `the where clause but ${describe(inserted)} in ` +\n `'create'. An upsert looks the row up by the where clause and ` +\n `inserts what 'create' says, so the two must agree on the key.`,\n );\n }\n\n return inserted;\n },\n };\n });\n}\n\n/**\n * Do two *encoded* values stand for the same thing?\n *\n * Not `===`, because `encode` is a per-dialect pass-through for whatever the\n * driver binds natively, and what a driver binds natively is not always a\n * primitive. Postgres passes a `DateTime` through as the `Date` it was given,\n * and both dialects pass `Bytes` through as a `Uint8Array` — so the same\n * instant and the same bytes arrive here as two distinct objects, and identity\n * refuses a correct upsert with a message printing two equal-looking strings.\n *\n * That is exactly the SQLite/Postgres asymmetry this codebase keeps finding:\n * SQLite encodes `DateTime` to a number and never noticed.\n *\n * Everything else falls through to `!==`, which is right for the string,\n * number, boolean and bigint an encoder can produce. `NaN` is not reachable —\n * it cannot be a unique key value that also round-trips through a `where`.\n */\nfunction sameEncoded(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n const left = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);\n const right = new Uint8Array(b.buffer, b.byteOffset, b.byteLength);\n if (left.length !== right.length) return false;\n for (let i = 0; i < left.length; i++) {\n if (left[i] !== right[i]) return false;\n }\n return true;\n }\n\n return false;\n}\n\n/**\n * A value for an error message, distinct whenever `sameEncoded` says the two\n * values differ.\n *\n * That equivalence is the whole requirement, and it is easy to half-meet: the\n * first version of this stringified a `Date`, which made a genuine mismatch\n * read as `is X ... but X` and look like a framework bug rather than a wrong\n * argument. Two more ways to land back there:\n *\n * - Two different `Uint8Array`s of the same length both describing as\n * `\"2 bytes\"`. Hence the hex, truncated so a large blob does not fill the\n * message.\n * - `1n` and `1`, which `sameEncoded` separates and `String()` collapses.\n * Reachable because Prisma coerces a number into a `BigInt` field. Hence the\n * `typeof` suffix on anything that is not a string.\n */\nfunction describe(value: unknown): string {\n if (value instanceof Date) return JSON.stringify(value.toISOString());\n\n if (ArrayBuffer.isView(value)) {\n const bytes = new Uint8Array(\n value.buffer,\n value.byteOffset,\n value.byteLength,\n );\n // `Array.from` rather than a spread + `.map`: a `Uint8Array`'s own `map`\n // returns another `Uint8Array`, so the strings would be coerced back to\n // bytes and every one of them would become 0.\n const shown = Array.from(bytes.slice(0, 8), (byte) =>\n byte.toString(16).padStart(2, \"0\"),\n ).join(\"\");\n const ellipsis = bytes.length > 8 ? \"…\" : \"\";\n return `${bytes.length} bytes (0x${shown}${ellipsis})`;\n }\n\n if (typeof value === \"string\") return JSON.stringify(value);\n if (value === null || value === undefined) return String(value);\n\n return `${JSON.stringify(String(value))} (${typeof value})`;\n}\n\n/**\n * Reads one key field out of a `where`, in either of the two forms Prisma\n * accepts: named directly, or inside the compound object a composite\n * `@@unique` is addressed through (`{ username_provider: { username, ... } }`).\n */\nfunction whereValue(key: string[], field: string): (args: any) => unknown {\n const compound = key.length > 1 ? key.join(\"_\") : undefined;\n return (args) => {\n const where = args?.where;\n if (where === undefined || where === null) return undefined;\n if (compound !== undefined && where[compound] !== undefined) {\n return where[compound][field];\n }\n return where[field];\n };\n}\n\n// --- shared pieces ---------------------------------------------------------\n\ninterface WriteColumn {\n field: FieldSchema;\n value: Binder;\n}\n\n/**\n * `(cols) values (?, ?), (?, ?)`, or `default values` when the row supplies no\n * column at all — legal on both dialects, and the only way to insert a row made\n * entirely of database defaults.\n */\nfunction valuesClause(grid: WriteColumn[][], dialect: SqlDialect): Fragment {\n const columns = grid[0];\n if (columns.length === 0) return sql(\" default values\");\n\n const names = joinFragments(\n columns.map((column) => sql(dialect.quoteIdent(column.field.column))),\n \", \",\n );\n\n const tuples = grid.map((row) =>\n concat(\n sql(\"(\"),\n joinFragments(\n row.map((column) => fieldParam(column.field, dialect, column.value)),\n \", \",\n ),\n sql(\")\"),\n ),\n );\n\n return concat(\n sql(\" (\"),\n names,\n sql(\") values \"),\n joinFragments(tuples, \", \"),\n );\n}\n\n/**\n * Which columns an insert writes, and where each value comes from.\n *\n * The four sources, in the order they are consulted: a nested write that\n * resolved a foreign key, the caller's own `data`, a client-side default, and\n * the database. A required field that reaches the end of that list is an error\n * raised here, naming the field — rather than a `NOT NULL constraint failed`\n * from the driver naming a column and nothing else.\n */\nfunction insertColumns(\n schema: ModelSchema,\n data: unknown,\n contributions: readonly ForeignKeyContribution[],\n op: Operation,\n dialect: SqlDialect,\n locateData: (args: any) => any,\n): WriteColumn[] {\n if (data !== undefined && data !== null) {\n if (typeof data !== \"object\" || Array.isArray(data)) {\n throw new InvalidArgumentError(\n \"data\",\n schema.name,\n op,\n \"Expected an object.\",\n );\n }\n }\n\n const supplied = suppliedFields(schema, data);\n const contributed = new Map(\n contributions.map((contribution) => [contribution.field, contribution]),\n );\n\n for (const name of contributed.keys()) {\n if (supplied.has(name)) {\n throw new UnsupportedQueryError(\n `data.${name}`,\n schema.name,\n op,\n `'${name}' is set both directly and through a nested relation write. ` +\n `Prisma keeps those two forms exclusive; use one of them.`,\n );\n }\n }\n\n const columns: WriteColumn[] = [];\n\n for (const field of Object.values(schema.fields)) {\n const contribution = contributed.get(field.name);\n if (contribution) {\n columns.push({\n field,\n value: (args, context) =>\n dialect.encode(contribution.value(args, context), field),\n });\n continue;\n }\n\n if (supplied.has(field.name)) {\n if (field.isList) {\n assertListDialect(schema, field, `data.${field.name}`, op, dialect);\n assertListOperand(schema, field, (data as any)?.[field.name], op, [\"set\"]);\n }\n\n // `{ tags: { set: [...] } }` is what Prisma documents for a list, and it\n // is accepted in `create` as well as in `update` — where a bare array is\n // also accepted, and means the same thing. Unwrapped at *compile* time\n // rather than in the binder because the two spellings are two argument\n // shapes and so already two plan-cache entries; deciding it here keeps\n // the binder a pure function of the value it is handed.\n const setForm = isListSetOperand(field, (data as any)?.[field.name]);\n\n columns.push({\n field,\n value: valueBinder(schema, op, field, dialect, (args) => {\n const value = locateData(args)?.[field.name];\n return setForm ? value?.set : value;\n }),\n });\n continue;\n }\n\n if (hasClientSideValue(field)) {\n columns.push({ field, value: defaultBinder(field, dialect) });\n continue;\n }\n\n // Left out of the statement entirely: the database supplies it, either from\n // its own default or as NULL.\n if (field.default || field.nullable) continue;\n\n // **A scalar list is never missing**, whatever the schema says about\n // required-ness. Measured against a generated 6.19 client: `create({ data:\n // { id: 900 } })` on a model whose every list is `NOT NULL` with no\n // `@default` succeeds, and every one of them reads back as `[]`. So Prisma\n // treats \"no value\" as the empty list rather than as an omission, and a\n // column with no database default gives it no choice — leaving the column\n // out would violate the NOT NULL constraint.\n //\n // This was a `MissingRequiredValueError` until the differential harness ran:\n // four `create` cases refused a call Prisma answers. It is exactly the kind\n // of divergence no amount of reading the docs produces, because the docs\n // describe the *input type* — where the field is optional — and say nothing\n // about what is written when it is absent.\n if (field.isList) {\n // Asked *here* as well as on the supplied path above, because this branch\n // invents a value the caller never wrote — and an unasked dialect is how\n // `create({ data: { id: 1 } })` on SQLite compiled a statement binding\n // raw JS arrays for the driver to reject with a type error, where naming\n // the column would have said \"sqlite has no array type … It works on\n // postgres\". The check belongs to the *column*, not to the caller\n // mentioning it.\n assertListDialect(schema, field, `data.${field.name}`, op, dialect);\n columns.push({ field, value: emptyList(field, dialect) });\n continue;\n }\n\n throw new MissingRequiredValueError(schema.name, op, field.name);\n }\n\n return columns;\n}\n\n/**\n * Refuses an operator map a scalar list does not take — `{ increment: 1 }` —\n * at **compile** time.\n *\n * The value-shaped refusal in `valueBinder` would eventually catch it, and too\n * late: `isOperatorObject` answers false for an operator a list does not have,\n * so `{ counts: { increment: 1 } }` was read as a *value* and travelled all the\n * way to the binder before anything objected. Compile is a pure function of the\n * argument shape and this is a shape question, so it belongs here — the same\n * call `assertCompositeInOperand` records making for the same reason.\n *\n * Note this is unambiguous even for a `Json[]`, where an object is a plausible\n * element: the column's value is an *array*, so a bare object in this position\n * is never data. `isOperatorObject` relies on the same fact.\n */\nfunction assertListOperand(\n schema: ModelSchema,\n field: FieldSchema,\n value: unknown,\n op: Operation,\n /**\n * The operators legal in *this* position. An insert takes `set` only —\n * Prisma's create input for a list is `T[] | { set: T[] }`, with no `push`,\n * and there is nothing for a `push` to append to on a row that does not exist\n * yet.\n */\n allowed: readonly string[],\n): void {\n if (!field.isList) return;\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date ||\n ArrayBuffer.isView(value)\n ) {\n return;\n }\n\n const given = Object.keys(value as Record<string, unknown>).filter(\n (key) => (value as Record<string, unknown>)[key] !== undefined,\n );\n if (given.length === 1 && allowed.includes(given[0])) return;\n\n throw new UnsupportedQueryError(\n `data.${field.name}`,\n schema.name,\n op,\n `'${field.name}' is a scalar list, so it takes ${allowed.join(\" or \")} — ` +\n `or a bare array. Received ${\n given.length === 0 ? \"an empty object\" : `{ ${given.join(\", \")} }`\n }. The arithmetic operators apply to a number, not to a list of them.`,\n );\n}\n\n/**\n * `{ set: [...] }` on a scalar list, which is the spelling Prisma documents and\n * which an insert accepts as readily as an update.\n *\n * Unambiguous in a way the scalar `Json` case is not — see `isOperatorObject` —\n * because a list column's data form is always an array, so an object here can\n * only be the operator.\n */\nfunction isListSetOperand(field: FieldSchema, value: unknown): boolean {\n return (\n field.isList === true &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !ArrayBuffer.isView(value) &&\n Object.keys(value).length === 1 &&\n \"set\" in value\n );\n}\n\n/** The scalar fields a `data` object actually sets, validated against the schema. */\nfunction suppliedFields(\n schema: ModelSchema,\n data: unknown,\n): Set<string> {\n const out = new Set<string>();\n if (typeof data !== \"object\" || data === null) return out;\n\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n // Prisma treats an explicit `undefined` as absent, which is how conditional\n // writes are expressed in application code.\n if (value === undefined) continue;\n // Relations are the nested-write planner's business.\n if (key in schema.relations) continue;\n if (!(key in schema.fields)) {\n throw new UnknownFieldError(key, schema.name, Object.keys(schema.fields));\n }\n out.add(key);\n }\n\n return out;\n}\n\n/**\n * Refuse a `data` object that names a relation, for the operations that have no\n * nested-write planner behind them.\n *\n * `suppliedFields` skips relation keys rather than rejecting them, because on\n * `create` and `update` they are the nested planner's business. Everywhere else\n * that same skip is a silent drop, so those callers say so here — by name, and\n * before anything is compiled.\n */\nfunction assertNoNestedWrites(\n schema: ModelSchema,\n data: unknown,\n op: Operation,\n path: string,\n reason: string,\n): void {\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) return;\n\n for (const [name, value] of Object.entries(data as Record<string, unknown>)) {\n if (value === undefined) continue;\n if (name in schema.relations) {\n throw new UnsupportedQueryError(`${path}.${name}`, schema.name, op, reason);\n }\n }\n}\n\n/**\n * `set` assignments for an update, in schema order.\n *\n * `@updatedAt` is appended unless the caller set it explicitly. Applying it on\n * *create* as well is handled by `hasClientSideValue`; missing that half is the\n * easy and quiet version of this bug, since the column is usually NOT NULL and\n * only fails on the models where Prisma made it nullable.\n *\n * **The stamp needs a column beside it**, which is not what \"every write stamps\n * `@updatedAt`\" would suggest and is the rule Prisma actually follows. Measured\n * against 6.19.2/SQLite, seeding `updatedAt` to the epoch and reading it back:\n *\n * data: {} epoch not stamped\n * data: { profile: { create: … } } epoch not stamped\n * data: { profile: { update: … } } epoch not stamped\n * data: { name: \"real\" } now stamped\n * data: { organization: { connect: … } } now stamped\n * data: { organizationId: null } now stamped\n *\n * The first three write no column of *this* row — a to-one whose key is on the\n * child changes the child — and Prisma leaves the stamp alone for all three. So\n * the condition is \"this statement sets at least one other column\", which is\n * what `writesAColumn` asks, rather than \"this call happened\".\n *\n * Stamping unconditionally was load-bearing in the wrong direction twice. It\n * made #355's empty-`data` read unreachable on any model carrying the attribute\n * — the majority case, and the one the issue was filed from — because the stamp\n * *was* the assignment that kept `assignments.length` off zero. And it put a\n * timestamp Prisma does not write on every nested to-one write #354 added,\n * where the differential harness could not see it: `updatedAt` is volatile, so\n * both sides compare as the descriptor `\"date\"` and two different instants\n * match. It took a by-value assertion to catch.\n *\n * **KNOWN DIVERGENCE — an owning-side `disconnect` stamps here and does not in\n * Prisma.** Measured beside the rest: `data: { organization: { disconnect: true\n * } }` writes `organizationId = NULL` (verified, the column really is cleared)\n * and leaves `updatedAt` at the epoch, while `connect` one line above stamps\n * it. Both write the same column through the same operand family, so this is\n * Prisma disagreeing with itself rather than a rule to follow. gemi contributes\n * the null as an ordinary assignment and therefore stamps, which is the answer\n * `connect`, a hand-written `organizationId: null`, and every other column\n * write already give. Pre-existing, unchanged here, and matching it would mean\n * special-casing one operand to reproduce an inconsistency.\n *\n * **...and the *filter* arm (#359) carries it one step further: it stamps even\n * when it detaches nothing.** `nested-writes.ts`'s owning-side `disconnect`\n * defaults `context.resolved[fkField]` to the value already in the column and\n * pushes the contribution unconditionally — it has to, because the statement's\n * text cannot depend on a value read at bind time — so the assignment is in the\n * SET list whether or not the linked row matched. Measured on both sides\n * against a schema built for it, since the template's `Profile` has no\n * `@updatedAt` (Prisma 6.19.2, SQLite, a one-to-one whose *owner* carries the\n * attribute, `updatedAt` seeded to the epoch):\n *\n * disconnect: true update … set \"userId\" = ?\n * -> key nulled, updatedAt at the epoch\n * disconnect: { name: \"Ada\" } update … set \"userId\" = ? where … and\n * exists(select … where \"name\" = ? …)\n * -> key nulled, updatedAt at the epoch\n * disconnect: { name: \"Nobody\" } the same statement, matching zero rows\n * -> nothing written at all\n * disconnect: false no update statement at all\n * -> nothing written at all\n *\n * So Prisma never stamps through this operand, matching filter or not — that is\n * the paragraph above — and on a miss it writes *no row*, because the filter\n * rides inside the `UPDATE`'s own `where` as an `exists` subquery. gemi's plan\n * text is fixed at compile time and reads\n * `update \"User\" set \"organizationId\" = ?, \"updatedAt\" = ? where \"id\" = ?` for\n * every arm that writes, so `User.update({ where: { id: 1 }, data: {\n * organization: { disconnect: { name: \"Nobody\" } } } })` leaves\n * `organizationId` at 1 and moves `updatedAt` from the epoch to now: a call\n * that changed no column of the row still stamps it.\n *\n * **There is no test for `disconnect`'s stamp and there cannot be one in this\n * fixture**, which is why this docblock is the deliverable rather than a\n * pointer to one. The template's only one-to-one owner is `Profile`, which has\n * no `@updatedAt` column, and the differential harness lists `updatedAt` in its\n * volatile set (`differential.ts`), so both sides compare as the descriptor\n * `\"date\"` and two different instants match. The measurements above were taken\n * against a purpose-built schema, not against the template's. `User` carries\n * the attribute and is a *many*-to-one owner, which is the shape Prisma answers\n * by ignoring the operand outright — so there the divergence to compare against\n * is a different one.\n *\n * **The owning-side `upsert` (#391) is the third operand here and the one that\n * *is* pinned**, for exactly the reason the paragraph above cannot be. Its\n * update branch resolves the key to the value already in the column and writes\n * it back, on the identical mechanism — the create branch needs the column and\n * the branch is a run-time answer, so the assignment is unconditional. Prisma\n * honours this operand on a many-to-one, unlike `disconnect`, so `User` can ask\n * the question: `User.update({ where: { id: 1 }, data: { organization: {\n * upsert: { create, update } } } })` issues no `UPDATE` on `User` at all there\n * and leaves `updatedAt` at the epoch, where gemi writes `organizationId` back\n * and stamps. Asserted by value in `writes.differential.test.ts`'s \"where the\n * two clients still disagree\" — the harness's own comparison cannot see it, for\n * the volatility reason above.\n *\n * **The two statements are also a lost-update window**, which `disconnect: true`\n * does not have and Prisma does not have on either arm. The filter arm reads the\n * current key with a `findFirst` and writes it back in a *second* statement, so\n * under READ COMMITTED a concurrent transaction that `connect`s a different\n * partner in between has its value silently reverted — by the call that decided\n * to do nothing. Prisma's single guarded `UPDATE` above cannot lose it: there is\n * no read to be stale, and on a miss there is no write at all.\n */\nfunction updateAssignments(\n schema: ModelSchema,\n data: unknown,\n contributions: readonly ForeignKeyContribution[],\n op: Operation,\n dialect: SqlDialect,\n locateData: (args: any) => any = (args) => args?.data,\n /**\n * Prefix for a column read on the *right* of an assignment — `\"User\".`\n * inside an `on conflict do update`, empty in a plain `update`.\n *\n * Postgres puts both the target row and the proposed `excluded` row in scope\n * inside a conflict clause, so a bare `\"n\" = \"n\" + $1` there is rejected:\n * `column reference \"n\" is ambiguous`. SQLite accepts either form, and so\n * does Postgres in a plain `update` — verified against both — which is why\n * the qualifier is applied where it is needed rather than everywhere.\n */\n qualifier = \"\",\n): Fragment[] {\n if (data !== undefined && data !== null) {\n if (typeof data !== \"object\" || Array.isArray(data)) {\n throw new InvalidArgumentError(\n \"data\",\n schema.name,\n op,\n \"Expected an object.\",\n );\n }\n }\n\n const supplied = suppliedFields(schema, data);\n const contributed = new Map(\n contributions.map((contribution) => [contribution.field, contribution]),\n );\n\n // Asked before the loop rather than from `out.length`, so the answer does not\n // depend on where `@updatedAt` happens to sit in schema order: a model that\n // declares it first would otherwise see an empty `out` and skip a stamp it\n // owes. Both sets hold scalar field names only — `suppliedFields` skips\n // relation keys, which is exactly the distinction being drawn here.\n const writesAColumn = contributed.size > 0 || supplied.size > 0;\n\n const out: Fragment[] = [];\n\n for (const field of Object.values(schema.fields)) {\n const column = dialect.quoteIdent(field.column);\n const contribution = contributed.get(field.name);\n\n if (contribution) {\n out.push(\n concat(\n sql(`${column} = `),\n param((args, context) =>\n dialect.encode(contribution.value(args, context), field),\n ),\n ),\n );\n continue;\n }\n\n if (supplied.has(field.name)) {\n out.push(\n assignment(\n schema,\n field,\n column,\n `${qualifier}${column}`,\n data,\n op,\n dialect,\n (args) => locateData(args)?.[field.name],\n ),\n );\n continue;\n }\n\n // A write that sets a column stamps `@updatedAt`; one that sets none does\n // not, because there is no write to date. See the docblock's table.\n if (field.isUpdatedAt && writesAColumn) {\n out.push(\n concat(\n sql(`${column} = `),\n fieldParam(field, dialect, defaultBinder(field, dialect)),\n ),\n );\n }\n }\n\n return out;\n}\n\n/**\n * Prisma's update operators. `set` is the explicit spelling of a plain\n * assignment; the arithmetic four read the column and write it back, so they\n * are the one place a column name appears on the right of an `=`.\n *\n * `push` is the sixth and belongs to scalar lists only, so it lives beside them\n * rather than here — see {@link listOperators}. Keeping it out of this table is\n * what makes `{ tags: { increment: 1 } }` and `{ count: { push: 1 } }` both\n * errors that name the field's kind, rather than one of them compiling.\n */\nconst ARITHMETIC: Record<string, string> = {\n increment: \"+\",\n decrement: \"-\",\n multiply: \"*\",\n divide: \"/\",\n};\n\n/** The update operators a scalar list takes: `set` and `push`, and nothing else. */\nconst LIST_OPERATORS = [\"set\", \"push\"] as const;\n\nfunction listOperators(field: FieldSchema): readonly string[] {\n return field.isList ? LIST_OPERATORS : [\"set\", ...Object.keys(ARITHMETIC)];\n}\n\nfunction assignment(\n schema: ModelSchema,\n field: FieldSchema,\n /** The column as the assignment's target, always unqualified. */\n column: string,\n /** The same column read as a value — qualified inside a conflict clause. */\n source: string,\n data: unknown,\n op: Operation,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Fragment {\n const value = (data as Record<string, unknown>)[field.name];\n\n if (field.isList) {\n assertListDialect(schema, field, `data.${field.name}`, op, dialect);\n assertListOperand(schema, field, value, op, LIST_OPERATORS);\n }\n\n if (isOperatorObject(value, field)) {\n const keys = Object.keys(value as Record<string, unknown>).filter(\n (key) => (value as Record<string, unknown>)[key] !== undefined,\n );\n\n if (keys.length !== 1) {\n throw new UnsupportedQueryError(\n `data.${field.name}`,\n schema.name,\n op,\n `Expected exactly one of ${listOperators(field).join(\", \")}.`,\n );\n }\n\n const [key] = keys;\n const at = (args: any) => locate(args)?.[key];\n\n if (key === \"set\") {\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, valueBinder(schema, op, field, dialect, at)),\n );\n }\n\n if (key === \"push\") {\n // `array_cat(<column>, $1)` — the column on the right of an `=`, like the\n // arithmetic four below, and for the same reason: the new value is a\n // function of the old one.\n //\n // The operand is normalised to a list **at bind time**, because Prisma\n // accepts both `push: \"a\"` and `push: [\"a\", \"b\"]` and the two are the\n // same statement. That normalisation is also what lets the dialect use a\n // single-signature function: `||` would read the two spellings as\n // different operators — see `PostgresDialect.listPush`.\n return concat(\n sql(`${column} = `),\n dialect.listPush(\n source,\n fieldParam(\n field,\n dialect,\n valueBinder(schema, op, field, dialect, (args) => {\n const supplied = at(args);\n return Array.isArray(supplied) ? supplied : [supplied];\n }),\n ),\n ),\n );\n }\n\n return concat(\n sql(`${column} = ${source} ${ARITHMETIC[key]} `),\n fieldParam(field, dialect, valueBinder(schema, op, field, dialect, at)),\n );\n }\n\n return concat(\n sql(`${column} = `),\n fieldParam(field, dialect, valueBinder(schema, op, field, dialect, locate)),\n );\n}\n\n/**\n * True for `{ increment: 1 }`, false for a plain value.\n *\n * A `Json` column is excluded because `{ set: ... }` is a legal *value* there as\n * well as an operator, and there is no way to tell them apart structurally.\n * Prisma resolves the ambiguity through its types; we resolve it by treating a\n * Json column's object as data, which is the reading that never loses the\n * caller's value.\n *\n * **A `Json[]` is not excluded**, and the exclusion above is why: the ambiguity\n * it exists for cannot arise on a list. A `Json` column can legitimately hold\n * the object `{ set: 1 }`; a `Json[]` column holds an *array*, so an object\n * operand is never data there and reading it as an operator loses nothing.\n * Without this the one spelling Prisma documents for writing a list —\n * `{ tags: { set: [...] } }` — would have been stored as a single JSON object\n * on exactly the element type where that is a plausible-looking value.\n */\nfunction isOperatorObject(value: unknown, field: FieldSchema): boolean {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date ||\n ArrayBuffer.isView(value) ||\n (field.type === \"Json\" && !field.isList)\n ) {\n return false;\n }\n\n const operators = listOperators(field);\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length === 0) return false;\n return keys.every((key) => operators.includes(key));\n}\n\n/**\n * Every write value passes through here — `create`, `createMany`, `update`'s\n * `set` and its bare form, and `upsert` — which is what makes it the one place\n * a value-dependent refusal has to live.\n *\n * It throws at **bind** time rather than compile time, and that is forced\n * rather than chosen: compile is a pure function of the argument *shape* and\n * never sees a value (invariant 2), so a value nobody may write cannot be\n * detected there. The schema and operation are closed over instead, so the\n * error still says which field of which model on which operation — the context\n * `fieldParam` does not have, and the reason the refusal is not down there.\n */\nfunction valueBinder(\n schema: ModelSchema,\n op: Operation,\n field: FieldSchema,\n dialect: SqlDialect,\n locate: (args: any) => any,\n): Binder {\n return (args) => {\n const value = locate(args);\n\n // `AnyNull` means \"either kind of null\", which is a question about existing\n // rows and not something a column can hold. Prisma raises here too. Left\n // alone it has no enumerable properties, so it serialised to the jsonb\n // object `{}` — a plausible-looking value, silently wrong, with nothing\n // raised: #259, and the same silent mis-store #222 closed for the other two\n // sentinels.\n if (jsonNullKind(value) === \"any\") {\n throw new InvalidArgumentError(\n `data.${field.name}`,\n schema.name,\n op,\n `Prisma.AnyNull is a filter operand, not a value — Prisma rejects it ` +\n `in a write here too. Write Prisma.DbNull for a SQL NULL column, or ` +\n `Prisma.JsonNull for the JSON value null.`,\n );\n }\n\n // A list operand is checked here rather than left to `encode`, for the\n // reason this whole function exists: the dialect has the value and nothing\n // else, so its refusal can only report an ORM bug. The schema and operation\n // are closed over here, so this one says which field of which model.\n if (field.isList && value !== null && value !== undefined) {\n if (!Array.isArray(value)) {\n throw new InvalidArgumentError(\n `data.${field.name}`,\n schema.name,\n op,\n `'${field.name}' is a scalar list, so it takes an array — or ` +\n `{ set: [...] } / { push: … }. Received ${typeof value}.`,\n );\n }\n if (value.some((element) => jsonNullKind(element) === \"any\")) {\n throw new InvalidArgumentError(\n `data.${field.name}`,\n schema.name,\n op,\n `Prisma.AnyNull is a filter operand, not a value, and that does not ` +\n `change for being inside a list.`,\n );\n }\n }\n\n return dialect.encode(value, field);\n };\n}\n\n/**\n * `{}` for a scalar list nobody supplied — what Prisma writes, measured rather\n * than assumed. See the note in `insertColumns`.\n */\nfunction emptyList(field: FieldSchema, dialect: SqlDialect): Binder {\n return () => dialect.encode([], field);\n}\n\n/**\n * Whether an absent value for this field means \"write the empty list\" — a\n * scalar list with no database default of its own to fall back to.\n *\n * A list *with* a default stays out of the statement so the default fires,\n * which is the same rule every other field follows and produces the same rows.\n */\nfunction suppliesEmptyList(field: FieldSchema): boolean {\n return field.isList === true && !field.default && !field.nullable;\n}\n\nfunction defaultBinder(field: FieldSchema, dialect: SqlDialect): Binder {\n // Read per call, never at compile time: a cuid must differ per row and `now`\n // must be the instant of *this* operation, not of the compilation that may\n // have happened thousands of calls ago.\n return (_args, context) =>\n dialect.encode(clientSideValue(field, context.now), field);\n}\n\ninterface Returning {\n clause: Fragment;\n /** The same columns without the `returning` keyword, for a select. */\n selected: Fragment;\n fields: FieldSchema[];\n hidden?: string[];\n relations: ReturnType<typeof planRelations>[\"plans\"];\n counts: CountPlan[];\n}\n\n/**\n * The `RETURNING` list.\n *\n * For a row-returning write it is the caller's `select` — the same resolution a\n * read does — plus any key columns the relation planner or a nested `after`\n * step needs and the caller did not ask for. Those extra columns are stripped\n * from the result once they have been used, exactly as on the read path.\n *\n * For a counting write it is one column, because the count is the number of\n * rows that come back.\n */\nfunction returningClause(\n schema: ModelSchema,\n args: any,\n dialect: SqlDialect,\n op: Operation,\n nested: NestedWritePlanning | undefined,\n): Returning {\n if (COUNTING.has(op)) {\n return {\n clause: sql(` returning ${keyColumn(schema, dialect)}`),\n selected: sql(keyColumn(schema, dialect)),\n fields: [],\n relations: [],\n counts: [],\n };\n }\n\n const selection = resolveSelection(schema, args, op);\n const { plans, keyFields } = planRelations(schema, args, dialect, op);\n const { fields, hidden } = withKeyFields(schema, selection, [\n ...keyFields,\n ...(nested?.keyFields ?? []),\n ]);\n const counts = planRelationCounts(schema, args, dialect, op);\n\n const columns = joinFragments(\n [\n ...fields.map((field) => sql(dialect.quoteIdent(field.column))),\n // Last, for the same reason they go last on a read: the shaper reads\n // scalars by position and `_count` is attached afterwards from the raw\n // row. The reading `update` below projects the same list, so a `_count`\n // survives that path too.\n ...counts.map((count) => count.column),\n ],\n \", \",\n );\n\n return {\n clause: concat(sql(\" returning \"), columns),\n // The same list without the keyword, for the one statement that reads the\n // row rather than writing it — an `update` with no column to set, whether\n // because its `data` held only nested writes or because it was empty. See\n // `compileUpdate`.\n selected: columns,\n fields,\n hidden,\n relations: plans,\n counts,\n };\n}\n\n/**\n * The plan for a counting write that Prisma answers `{ count: 0 }` to without\n * touching the database: `createMany` with an empty list, and `updateMany` with\n * an empty `data`.\n *\n * A plan must have a statement, so there is one. A constant-false select is the\n * cheapest thing that yields zero rows on both dialects, and it keeps these\n * cases on exactly the same code path as every other write — no branch in the\n * choke point, no plan that is a plan in name only, and the count still comes\n * from the number of rows returned rather than from a hard-coded zero, so the\n * shaper is the shaper every other counting write uses.\n *\n * It costs one round trip that Prisma does not make. That is the price of the\n * uniformity above, and it is paid only by calls that asked for nothing.\n */\nfunction zeroCountPlan(\n schema: ModelSchema,\n op: Operation,\n dialect: SqlDialect,\n): QueryPlan {\n const key = keyColumn(schema, dialect);\n const { text, binders } = render(\n sql(`select ${key} from ${dialect.quoteIdent(schema.table)} where false`),\n dialect,\n { model: schema.name, operation: op },\n );\n return {\n text,\n bind: bindValues(binders),\n shape: (returned) => ({ count: returned.length }),\n };\n}\n\n/** The narrowest column that still identifies a row, for counting writes. */\nfunction keyColumn(schema: ModelSchema, dialect: SqlDialect): string {\n const name = schema.primaryKey[0] ?? Object.keys(schema.fields)[0];\n return dialect.quoteIdent(schema.fields[name].column);\n}\n\nfunction fieldOf(schema: ModelSchema, name: string): FieldSchema {\n const field = schema.fields[name];\n if (!field) {\n throw new UnknownFieldError(name, schema.name, Object.keys(schema.fields));\n }\n return field;\n}\n\nfunction plan(\n schema: ModelSchema,\n statement: Fragment,\n dialect: SqlDialect,\n op: Operation,\n returning: Returning,\n nested: NestedWritePlanning | undefined,\n): QueryPlan {\n const { text, binders } = render(statement, dialect, { model: schema.name, operation: op });\n\n const shaper = buildRowShaper(\n returning.fields,\n dialect,\n returning.relations.map((relation) => ({\n key: relation.as,\n kind: relation.kind,\n })),\n );\n\n const single = SINGLE_ROW.has(op);\n const counting = COUNTING.has(op);\n\n return {\n text,\n bind: bindValues(binders),\n relations: returning.relations.length > 0 ? returning.relations : undefined,\n strategies:\n returning.relations.length > 0\n ? strategiesOf(returning.relations)\n : undefined,\n hidden: returning.hidden,\n before: nested && nested.before.length > 0 ? nested.before : undefined,\n after: nested && nested.after.length > 0 ? nested.after : undefined,\n counts: returning.counts.length > 0 ? true : undefined,\n shape(rows) {\n // The count *is* the number of returned rows — see the note at the top of\n // this file on why it does not come from driver metadata.\n if (counting) return { count: rows.length };\n\n const shaped = shaper(rows);\n\n // `_count` came back as extra columns the shaper knows nothing about,\n // under aliases carrying a dot. Assembled into one object per row,\n // because that is the shape Prisma returns — and the same assembly\n // `compileRead` does, deliberately spelled the same way.\n if (returning.counts.length > 0) {\n for (let i = 0; i < shaped.length; i++) {\n const raw = (rows[i] as Record<string, unknown>) ?? {};\n const totals: Record<string, number> = {};\n for (const count of returning.counts) {\n totals[count.as] = Number(raw[count.alias] ?? 0);\n }\n shaped[i]._count = totals;\n }\n }\n // `null` when nothing matched. `$exec` turns that into\n // `RecordNotFoundError` for the operations Prisma raises on, where the\n // model's name is in scope for the message.\n return single ? (shaped[0] ?? null) : shaped;\n },\n };\n}\n\nfunction listOf(value: unknown): any[] {\n if (value === undefined || value === null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\nfunction assertArgs(schema: ModelSchema, op: Operation, args: any): void {\n if (args === undefined || args === null) {\n throw new UnsupportedQueryError(\n \"args\",\n schema.name,\n op,\n `${op} requires arguments.`,\n );\n }\n\n if (typeof args !== \"object\" || Array.isArray(args)) {\n throw new InvalidArgumentError(\n String(args),\n schema.name,\n op,\n \"Expected an object.\",\n );\n }\n\n if (args.select !== undefined && args.include !== undefined) {\n throw new UnsupportedQueryError(\n \"select + include\",\n schema.name,\n op,\n \"Prisma allows only one of them on the same query.\",\n );\n }\n\n const allowed = WRITE_ARGS[op];\n for (const key of Object.keys(args).sort()) {\n if (args[key] === undefined) continue;\n if (!allowed.has(key)) {\n throw new UnsupportedQueryError(\n key,\n schema.name,\n op,\n `${op} takes ${[...allowed].sort().join(\", \")}.`,\n );\n }\n }\n\n for (const required of requiredArgs(op)) {\n if (args[required] === undefined) {\n throw new UnsupportedQueryError(\n required,\n schema.name,\n op,\n `${op} requires '${required}'.`,\n );\n }\n }\n}\n\n/**\n * Which arguments Prisma makes non-optional, matched exactly.\n *\n * `updateMany` and `deleteMany` take an *optional* `where` — `deleteMany({})`\n * legitimately empties a table. Requiring one here would be a safety rail\n * Prisma does not have, and the differential harness would call it a\n * divergence, which is the right verdict: a guard belongs in a policy\n * (iteration 6), not in the compiler.\n */\nfunction requiredArgs(op: Operation): string[] {\n switch (op) {\n case \"create\":\n case \"createMany\":\n return [\"data\"];\n case \"update\":\n return [\"data\", \"where\"];\n case \"updateMany\":\n return [\"data\"];\n case \"delete\":\n return [\"where\"];\n case \"upsert\":\n return [\"where\", \"create\", \"update\"];\n default:\n return [];\n }\n}\n",
|
|
22
22
|
"import type { ModelSchema } from \"./schema\";\n\n/**\n * The one configuration where a `DateTime` read comes back as the wrong instant.\n *\n * `dialect/postgres.ts` records it as a KNOWN DIVERGENCE and `docs/orm.md` now\n * states the requirement — run Postgres deployments with `TZ=UTC`. Prisma maps\n * `DateTime` to `timestamp(3)`, and Bun decodes that column differently\n * depending on which wire protocol carried the statement, which in turn depends\n * on whether the query bound a parameter:\n *\n * TZ=America/New_York findMany() -> 2021-03-04T10:06:07.008Z\n * where id = $1 -> 2021-03-04T05:06:07.008Z\n *\n * A reader who has seen the documentation sets `TZ=UTC` and never meets this. A\n * reader who has not gets two different instants for the same row and no signal\n * at all — the values look plausible, nothing raises, and the difference is\n * exactly the machine's UTC offset, which is the kind of wrongness that reaches\n * a report or an invoice before anyone notices.\n *\n * So this says it once. The project's stated trade, from the `Json` encoder that\n * had the same shape of bug, is that \"a loud failure replaces a silent\n * mis-store\"; a warning is the most that can be done here, because the value is\n * already decoded by the time anything in this package sees it and it does not\n * carry which protocol produced it.\n *\n * **Not gated on `NODE_ENV`, unlike the slow-transaction warning.** That one is\n * a performance hint, and a hint is worth having only where somebody is\n * watching. This is a correctness fault, and production is exactly where an\n * unnoticed wrong timestamp costs something. It fires once per process, and\n * only when every condition below holds, so a correctly configured deployment\n * never sees it.\n *\n * Pure, and returns the message rather than printing it, so the conditions can\n * be tested without capturing console output or depending on the machine's\n * clock — `offsetMinutes` is a parameter for exactly that reason.\n */\nexport function protocolSkewWarning(\n dialect: string,\n schema: ModelSchema,\n text: string,\n values: readonly unknown[],\n offsetMinutes: number,\n): string | null {\n // Cheapest discriminators first: three of the four are a comparison, and the\n // field scan only runs for a parameterless Postgres select on a machine that\n // is not already UTC.\n if (dialect !== \"postgres\") return null;\n if (values.length > 0) return null;\n if (offsetMinutes === 0) return null;\n\n // A statement that binds nothing and returns no rows cannot show the skew.\n // `RETURNING` writes always bind at least the values they write, so in\n // practice this is the parameterless read.\n if (!/^\\s*select/i.test(text)) return null;\n\n const columns = Object.values(schema.fields)\n .filter((field) => field.type === \"DateTime\")\n .map((field) => field.name);\n\n if (columns.length === 0) return null;\n\n return (\n `[gemi] ${schema.name} was read with a query that binds no parameters, on ` +\n `Postgres, in a process whose clock is not UTC. Bun decodes ` +\n `timestamp(3) over the simple query protocol as local time, so ` +\n `${columns.length === 1 ? \"the column\" : \"columns\"} ` +\n `${columns.join(\", \")} will be off by this machine's UTC offset — the same ` +\n `row read through a query that binds a parameter returns a different ` +\n `instant. Set TZ=UTC on this process. See \"Run Postgres deployments with ` +\n `TZ=UTC\" in docs/orm.md. (Warned once.)`\n );\n}\n\n/**\n * A zone's UTC offset at one instant, asked of a *named* zone.\n *\n * `Date.prototype.getTimezoneOffset` can only answer for the ambient zone, so a\n * test — which runs under `TZ=UTC`, in CI and per the note above — cannot use\n * it to ask what `Europe/London` does in July. `Intl` can: formatting an\n * instant into a zone and reading the fields back as though they were UTC\n * recovers the offset, because the difference between the two *is* what the\n * zone added.\n *\n * With no zone it defers to the clock, which is the call site's path and avoids\n * making the process's own answer depend on `Intl` agreeing with `TZ`.\n */\nfunction offsetMinutesAt(instant: number, timeZone?: string): number {\n if (timeZone === undefined) return new Date(instant).getTimezoneOffset();\n\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hourCycle: \"h23\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n }).formatToParts(new Date(instant));\n\n const at = (type: string) =>\n Number(parts.find((part) => part.type === type)?.value);\n\n const local = Date.UTC(\n at(\"year\"),\n at(\"month\") - 1,\n at(\"day\"),\n at(\"hour\"),\n at(\"minute\"),\n at(\"second\"),\n );\n\n // `getTimezoneOffset`'s sign convention — minutes to add to local time to get\n // UTC, so positive west of Greenwich — because that is what the caller and\n // `protocolSkewWarning` above both already speak.\n return (instant - local) / 60_000;\n}\n\n/**\n * Whether this process's clock can be off UTC **at any point in the year**.\n *\n * The call site reads this once, at module load, so that a correctly configured\n * deployment pays a boolean per query rather than a `Date` allocation. The\n * thing that may be cached for the life of a process is the *zone*, though, and\n * not the offset it happens to have today:\n *\n * TZ=Europe/London January 0 July -60\n * TZ=Europe/Lisbon January 0 July -60\n * TZ=Africa/Accra January 0 July 0 (genuinely fixed)\n * TZ=UTC January 0 July 0\n *\n * Reading `new Date().getTimezoneOffset()` once would put London in the same\n * bucket as UTC for any process started between late October and late March,\n * and switch the diagnostic off for the whole of BST — when the skew is real.\n * That is the wrong way round: the entire audience for this warning is\n * deployments that did not set `TZ=UTC`.\n *\n * So the question is asked of the zone, by probing a year of it. Twelve probes\n * rather than the two that separate the table above, because northern-summer\n * DST is not the only shape a transition comes in — `Africa/Casablanca` moves\n * with Ramadan, which walks through the calendar — and twelve `Date`s at module\n * load is a cost paid once, against a rule this has to get right for years.\n *\n * `timeZone` exists so the predicate is answerable from a UTC machine, which is\n * the same move that made `protocolSkewWarning` testable: the call site passes\n * nothing and gets the clock.\n */\nexport function clockCouldSkew(timeZone?: string): boolean {\n // The current year, so a zone that has since abolished its DST is read as it\n // is now rather than as some pinned year remembers it.\n const year = new Date().getUTCFullYear();\n\n for (let month = 0; month < 12; month++) {\n if (offsetMinutesAt(Date.UTC(year, month, 1), timeZone) !== 0) return true;\n }\n\n return false;\n}\n\n/** Reports the skew at most once, and only while it is still possible. */\nexport type ProtocolSkewWarner = (\n dialect: string,\n schema: ModelSchema,\n text: string,\n values: readonly unknown[],\n) => string | null;\n\n/**\n * The call site's half of the warning: the gate, the once-per-process latch,\n * and nothing else.\n *\n * It lives here rather than as two module-level bindings in `Model.ts` because\n * of what CI can see. `Model.ts` needs a database to exercise, and the one\n * configuration CI runs — `TZ=UTC` — is the configuration where *neither*\n * branch of the gate can produce a warning. So a gate written inline is\n * invisible to the suite in both directions: inverting it, or deleting the line\n * that sets the latch, leaves every test green. Behind this seam both are\n * ordinary assertions, with no database and no dependence on the ambient clock.\n *\n * `offsetMinutes` is a function, and read per call rather than captured,\n * because caching it is the same mistake `clockCouldSkew` exists to avoid one\n * level up: a London process that cached a winter `0` would clear the gate and\n * then be silenced by `protocolSkewWarning`'s own `offsetMinutes === 0` test\n * all summer. Only a process that could skew ever reads the clock, and it stops\n * as soon as it has said so — which is exactly the deployment the cost is worth\n * paying for.\n */\nexport function createProtocolSkewWarner(\n couldSkew: boolean,\n offsetMinutes: () => number,\n): ProtocolSkewWarner {\n let warned = false;\n\n return (dialect, schema, text, values) => {\n if (!couldSkew || warned) return null;\n\n const warning = protocolSkewWarning(\n dialect,\n schema,\n text,\n values,\n offsetMinutes(),\n );\n\n // Latched on firing, not on asking: the first statement of a process is\n // rarely the parameterless read, and a query that could not have shown the\n // skew is no evidence that none will.\n if (warning !== null) warned = true;\n\n return warning;\n };\n}\n",
|
|
23
23
|
"import type { SqlDialect } from \"../dialect\";\nimport {\n InvalidArgumentError,\n UnknownFieldError,\n UnsupportedQueryError,\n} from \"../errors\";\nimport type { QueryPlan } from \"../plan\";\nimport type { FieldSchema, ModelSchema, ScalarType } from \"../schema\";\nimport {\n type Fragment,\n bindValues,\n concat,\n joinFragments,\n render,\n sql,\n} from \"./fragment\";\nimport { compileOrderBy, parseOrderBy } from \"./orderBy\";\nimport { pagination } from \"./paginate\";\nimport { compileWhere } from \"./where\";\n\n/**\n * `aggregate`, and the `select` form of `count`.\n *\n * The fourteenth operation, and the first read whose result is neither rows nor\n * a bare number. Its shape is Prisma's, verified against a generated client\n * rather than inferred from the docs — every claim in this file's comments is a\n * line of that probe's output.\n *\n * ## Why it is not just `count` with more functions\n *\n * Three things differ, and each one is a place a plausible implementation is\n * wrong:\n *\n * 1. **`_count` has two shapes.** `_count: true` returns a *number*;\n * `_count: { _all: true, email: true }` returns an object, and a per-field\n * count is `count(\"email\")` — the number of rows where that column is **not\n * null**, which is a different number from `count(*)` and is the whole point\n * of asking per field.\n * 2. **The empty set is not zeroes.** `_count` over no rows is `0`, but `_sum`,\n * `_avg`, `_min` and `_max` are all `null` — per field, inside their objects.\n * An implementation that coalesced to `0` would be wrong in the direction\n * nobody checks.\n * 3. **The driver's types are not the column's types.** `sum(integer)` is\n * `bigint` in Postgres and `avg(integer)` is `numeric`, and Bun hands both\n * back as *strings*. So the coercion cannot be `dialect.decode(value, field)`\n * — that decodes a value of the column's type, and an aggregate is not one.\n * See `coerce` below, where each rule is a measurement.\n *\n * ## Pagination\n *\n * `take` / `skip` describe the rows being aggregated, not the one row the\n * aggregate produces — exactly as they do for `count`, and for the same reason:\n * `limit` beside an aggregate caps the result, which is always one row. So a\n * paginated aggregate wraps its row query in a subquery, the same shape\n * `compileRead` uses. Verified against Prisma: `take: 2` with\n * `orderBy: { globalRole: \"asc\" }` over rows 0, 5, 10 sums to 5, not 15.\n */\n\n/** The aggregate functions Prisma exposes, in the order it returns them. */\nexport const KINDS = [\"_count\", \"_avg\", \"_sum\", \"_min\", \"_max\"] as const;\nexport type Kind = (typeof KINDS)[number];\n\nconst AGGREGATE_ARGS = new Set<string>([\n \"where\",\n \"orderBy\",\n \"take\",\n \"skip\",\n ...KINDS,\n]);\n\n/**\n * `_sum` and `_avg` need arithmetic, so Prisma restricts them to these.\n *\n * `Decimal` is listed for completeness and cannot occur: `emit.ts` refuses a\n * Decimal field at generation time, so no generated schema has one.\n */\nconst NUMERIC = new Set<ScalarType>([\"Int\", \"Float\", \"BigInt\", \"Decimal\"]);\n\n/**\n * `_min` / `_max` need an ordering. `Json` has none in either dialect, and\n * `Bytes` orders bytewise in a way Prisma does not expose — both are refused\n * rather than emitted and left to disagree.\n */\nconst UNORDERABLE = new Set<ScalarType>([\"Json\", \"Bytes\"]);\n\n/** The SQL function each kind compiles to. */\nexport const FUNCTION: Record<Kind, string> = {\n _count: \"count\",\n _avg: \"avg\",\n _sum: \"sum\",\n _min: \"min\",\n _max: \"max\",\n};\n\nexport interface Term {\n kind: Kind;\n /** Absent for `_count`'s `_all`, which is `count(*)`. */\n field?: FieldSchema;\n /** The key this term is written to inside its kind's object. */\n as: string;\n /** The column alias it comes back under. Positional, so it cannot collide. */\n alias: string;\n}\n\nexport function isAggregateOperation(op: string): boolean {\n return op === \"aggregate\";\n}\n\n/**\n * `aggregate`, and `count({ select })` — which is the same statement with a\n * flatter result.\n *\n * Prisma's `count({ select: { _all: true, email: true } })` returns\n * `{ _all: 3, email: 2 }`: no `_count` wrapper, because the operation already\n * says what the numbers are. It was refused here until now as \"aggregate\n * territory\", which was the right call while there was no aggregate to put it\n * beside; the two decisions belong together and this is the together.\n *\n * **No `ExecOptions`**, unlike every neighbouring read, and that is deliberate\n * rather than an omission: `strategy` chooses how an include tree loads and an\n * aggregate has no relations, `track` records where a row came from so `save`\n * can update it and an aggregate returns no rows. Accepting either and ignoring\n * it would be worse than not accepting it.\n */\nexport function compileAggregate(\n schema: ModelSchema,\n op: string,\n args: any,\n dialect: SqlDialect,\n): QueryPlan {\n const flat = op === \"count\";\n assertArgs(schema, op, args, flat);\n\n const terms = flat\n ? countSelectTerms(schema, op, args?.select)\n : aggregateTerms(schema, op, args);\n\n if (terms.length === 0) {\n throw new UnsupportedQueryError(\n op,\n schema.name,\n op,\n flat\n ? `A 'select' on a count must name at least one field, or '_all'.`\n : `An aggregate needs at least one of ${KINDS.join(\", \")}. Prisma ` +\n `rejects an empty one too.`,\n );\n }\n\n const where = compileWhere(\n schema,\n args?.where,\n { dialect, operation: op },\n (a) => a?.where,\n );\n const whereClause = where ? concat(sql(\" where \"), where) : sql(\"\");\n const from = sql(` from ${dialect.quoteIdent(schema.table)}`);\n\n const projection = joinFragments(\n terms.map((term) =>\n sql(\n `${FUNCTION[term.kind]}(${\n term.field ? dialect.quoteIdent(term.field.column) : \"*\"\n }) as ${dialect.quoteIdent(term.alias)}`,\n ),\n ),\n \", \",\n );\n\n // Parsed unconditionally, so that validation does not depend on whether a\n // *different* argument was also supplied — the same rule `count` follows.\n const parsed = parseOrderBy(schema, args?.orderBy, op, {\n dialect,\n locate: (a: any) => a?.orderBy,\n });\n const paginating = args?.take !== undefined || args?.skip !== undefined;\n\n let statement: Fragment;\n\n if (!paginating) {\n statement = concat(sql(\"select \"), projection, from, whereClause);\n } else {\n const { clause, terms: order } = pagination(\n schema,\n op,\n args,\n dialect,\n parsed,\n );\n const ordering = compileOrderBy(order, dialect);\n\n // The subquery selects every column an aggregate names — an `order by` may\n // reference columns beyond them, which is fine, since it is resolved\n // against the table rather than against the select list.\n //\n // With only `count(*)` there is no such column, so it selects the primary\n // key: the narrowest thing that keeps a row identity, which is what\n // `compileRead`'s paginated count does for the same reason.\n const columns = new Map<string, string>();\n for (const term of terms) {\n if (term.field) columns.set(term.field.column, term.field.column);\n }\n if (columns.size === 0) {\n const key = schema.primaryKey[0] ?? Object.keys(schema.fields)[0];\n const column = schema.fields[key]?.column ?? key;\n columns.set(column, column);\n }\n\n statement = concat(\n sql(\"select \"),\n projection,\n sql(\n ` from (select ${[...columns.values()]\n .map((column) => dialect.quoteIdent(column))\n .join(\", \")}`,\n ),\n from,\n whereClause,\n ordering ? concat(sql(\" order by \"), ordering) : sql(\"\"),\n clause,\n sql(`) as ${dialect.quoteIdent(\"sub\")}`),\n );\n }\n\n const { text, binders } = render(statement, dialect, {\n model: schema.name,\n operation: op,\n });\n\n return {\n text,\n bind: bindValues(binders),\n shape(rows) {\n const row = (rows as Record<string, unknown>[])[0] ?? {};\n\n if (flat) {\n const out: Record<string, unknown> = {};\n for (const term of terms)\n out[term.as] = coerce(term, row[term.alias], dialect);\n return out;\n }\n\n const out: Record<string, unknown> = {};\n for (const term of terms) {\n // `_count: true` is a number rather than an object, and it is the only\n // aggregate that can be either.\n if (term.kind === \"_count\" && term.as === BARE) {\n out._count = coerce(term, row[term.alias], dialect);\n continue;\n }\n const bucket = (out[term.kind] ??= {}) as Record<string, unknown>;\n bucket[term.as] = coerce(term, row[term.alias], dialect);\n }\n return out;\n },\n };\n}\n\n/** The `as` a bare `_count: true` carries, which no field name can be. */\nexport const BARE = \"\";\n\nexport function aggregateTerms(\n schema: ModelSchema,\n op: string,\n args: any,\n): Term[] {\n const terms: Term[] = [];\n\n for (const kind of KINDS) {\n const requested = args?.[kind];\n if (requested === undefined || requested === false) continue;\n\n if (kind === \"_count\" && requested === true) {\n terms.push({ kind, as: BARE, alias: alias(kind, terms.length) });\n continue;\n }\n\n if (\n typeof requested !== \"object\" ||\n requested === null ||\n Array.isArray(requested)\n ) {\n throw new InvalidArgumentError(\n kind,\n schema.name,\n op,\n kind === \"_count\"\n ? `Expected true or an object of fields.`\n : `Expected an object of fields.`,\n );\n }\n\n for (const key of Object.keys(requested).sort()) {\n const wanted = (requested as Record<string, unknown>)[key];\n if (wanted === undefined || wanted === false) continue;\n\n if (kind === \"_count\" && key === \"_all\") {\n terms.push({ kind, as: \"_all\", alias: alias(kind, terms.length) });\n continue;\n }\n\n const field = resolveField(schema, op, kind, key);\n assertAggregable(schema, op, kind, field);\n terms.push({ kind, field, as: key, alias: alias(kind, terms.length) });\n }\n }\n\n return terms;\n}\n\n/** `count({ select: { _all: true, email: true } })` — every term a `count`. */\nfunction countSelectTerms(\n schema: ModelSchema,\n op: string,\n select: any,\n): Term[] {\n if (typeof select !== \"object\" || select === null || Array.isArray(select)) {\n throw new InvalidArgumentError(\n \"select\",\n schema.name,\n op,\n `Expected an object of fields.`,\n );\n }\n\n const terms: Term[] = [];\n for (const key of Object.keys(select).sort()) {\n const wanted = select[key];\n if (wanted === undefined || wanted === false) continue;\n\n if (key === \"_all\") {\n terms.push({\n kind: \"_count\",\n as: \"_all\",\n alias: alias(\"_count\", terms.length),\n });\n continue;\n }\n\n const field = resolveField(schema, op, \"_count\", key);\n terms.push({\n kind: \"_count\",\n field,\n as: key,\n alias: alias(\"_count\", terms.length),\n });\n }\n return terms;\n}\n\n/**\n * Positional, so two terms can never collide however the model is named — a\n * field called `_all` would otherwise produce the same alias as `_count`'s own.\n * The kind stays in the name because a query log is read by a person.\n */\nconst alias = (kind: Kind, index: number) => `${kind}_${index}`;\n\nexport function resolveField(\n schema: ModelSchema,\n op: string,\n kind: Kind,\n name: string,\n): FieldSchema {\n const field = schema.fields[name];\n if (!field) {\n // A relation named here is a plausible mistake with an unhelpful default\n // message, so it gets its own.\n if (name in schema.relations) {\n throw new UnsupportedQueryError(\n `${kind}.${name}`,\n schema.name,\n op,\n `'${name}' is a relation. Aggregate its own model instead, or use ` +\n `'_count' inside an 'include' to count it per row.`,\n );\n }\n throw new UnknownFieldError(name, schema.name, Object.keys(schema.fields));\n }\n return field;\n}\n\nexport function assertAggregable(\n schema: ModelSchema,\n op: string,\n kind: Kind,\n field: FieldSchema,\n): void {\n if ((kind === \"_sum\" || kind === \"_avg\") && !NUMERIC.has(field.type)) {\n throw new UnsupportedQueryError(\n `${kind}.${field.name}`,\n schema.name,\n op,\n `'${field.name}' is a ${field.type}, and ${kind} needs a number. ` +\n `Prisma does not offer it on this field either.`,\n );\n }\n\n if ((kind === \"_min\" || kind === \"_max\") && UNORDERABLE.has(field.type)) {\n throw new UnsupportedQueryError(\n `${kind}.${field.name}`,\n schema.name,\n op,\n `'${field.name}' is a ${field.type}, which has no ordering the two ` +\n `dialects agree on.`,\n );\n }\n}\n\n/**\n * The driver's value for one aggregate, as the value Prisma returns.\n *\n * **Every line here is a measurement**, taken through Bun against Postgres 16\n * and SQLite, because the obvious rule — \"decode it as the column's type\" — is\n * wrong for three of the five kinds. What Postgres returns:\n *\n * count(*) \"2\" string\n * count(text) \"2\" string\n * sum(integer) \"4\" string <- bigint\n * sum(bigint) \"9007199254740995\" string\n * sum(double) 4 number\n * avg(integer) \"2.0000000000000000\" string <- numeric\n * avg(double) 2 number\n * min(integer) 1 number\n * max(text) \"b\" string\n * min(timestamp) Date object\n * max(bigint) \"9007199254740993\" string\n *\n * ...and over an empty set every one of them is `null` except the counts, which\n * are `\"0\"`.\n *\n * So:\n *\n * - **`_count` is always a number**, and always present. `Number(\"0\")` rather\n * than a coalesce, because the driver gives a string and `?? 0` would leave it\n * one.\n * - **`_avg` is always a number**, whatever the column is — Prisma returns a\n * float for the average of an `Int`, and Postgres hands back `numeric` text.\n * - **`_sum` keeps the column's type**, so it is the one kind where a `BigInt`\n * column matters: `sum(bigint)` crosses as an exact string, and `Number()` on\n * 9007199254740995 would silently drop the low bits. Same trap the lateral\n * strategy's `::text` cast exists for.\n * - **`_min` / `_max` are values of the column**, so here — and only here — the\n * dialect's own `decode` is exactly right. It is what turns SQLite's integer\n * milliseconds back into a `Date`.\n */\nexport function coerce(\n term: Term,\n value: unknown,\n dialect: SqlDialect,\n): unknown {\n if (term.kind === \"_count\") return Number(value ?? 0);\n\n // Every other aggregate is null over an empty set, and per field.\n if (value === null || value === undefined) return null;\n\n if (term.kind === \"_avg\") return Number(value);\n\n if (term.kind === \"_sum\") {\n const type = term.field?.type;\n if (type === \"BigInt\") return BigInt(String(value));\n // `Decimal` is **unreachable**, not merely untested: `emit.ts`'s\n // `UNSUPPORTED_SCALARS` refuses a Decimal field at generation time, so no\n // generated schema can carry one and neither this branch nor `Decimal`'s\n // membership of `NUMERIC` can be entered.\n //\n // Kept, and kept as a pass-through, because the day Decimal becomes\n // supported is the day this needs a real decision — Postgres returns\n // `sum(numeric)` as text, and whether that becomes a `Prisma.Decimal`, a\n // string or a number is the same question the generator declined to answer.\n // Silently `Number()`-ing it would answer it wrongly and lose exactly the\n // precision the type exists to keep.\n if (type === \"Decimal\") return value;\n return Number(value);\n }\n\n // `_min` / `_max` are values *of the column*, so here — and only here — the\n // dialect's own `decode` is exactly right. It is what turns SQLite's integer\n // milliseconds back into a `Date`, and Postgres's `bigint` text into a\n // `BigInt`. Without it a `_max: { createdAt: true }` comes back as\n // 1600000004000 where Prisma returns a `Date`, on SQLite only — which is the\n // shape of every bug this file's coercion table exists to prevent.\n return term.field ? dialect.decode(value, term.field) : value;\n}\n\nfunction assertArgs(\n schema: ModelSchema,\n op: string,\n args: any,\n flat: boolean,\n): void {\n if (args === undefined || args === null) {\n if (flat) return;\n throw new UnsupportedQueryError(\n op,\n schema.name,\n op,\n `An aggregate needs at least one of ${KINDS.join(\", \")}.`,\n );\n }\n\n if (typeof args !== \"object\" || Array.isArray(args)) {\n throw new InvalidArgumentError(\n String(args),\n schema.name,\n op,\n \"Expected an object.\",\n );\n }\n\n if (flat) return;\n\n for (const key of Object.keys(args).sort()) {\n if (args[key] === undefined) continue;\n if (AGGREGATE_ARGS.has(key)) continue;\n\n // `select` and `include` are the two a caller reaches for by habit, and\n // neither means anything here: an aggregate's shape is decided entirely by\n // which functions were asked for.\n if (key === \"select\" || key === \"include\") {\n throw new UnsupportedQueryError(\n key,\n schema.name,\n op,\n `An aggregate returns the functions it was given, so there is nothing ` +\n `to ${key === \"select\" ? \"select\" : \"include\"}. Prisma does not ` +\n `accept it either.`,\n );\n }\n\n throw new UnsupportedQueryError(\n key,\n schema.name,\n op,\n `${op} takes ${[...AGGREGATE_ARGS].sort().join(\", \")}.`,\n );\n }\n}\n",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"import type { SqlDialect } from \"../dialect\";\nimport { UnsupportedQueryError } from \"../errors\";\nimport type { Operation, QueryPlan } from \"../plan\";\nimport type { RelationStrategy } from \"./plan-relations\";\nimport type { ModelSchema } from \"../schema\";\nimport { compileAggregate, isAggregateOperation } from \"./aggregate\";\nimport { compileGroupBy, isGroupByOperation } from \"./group-by\";\nimport { compileRead, isReadOperation } from \"./read\";\nimport { compileWrite, isWriteOperation } from \"./write\";\n\n/**\n * Argument tree -> SQL. Pure: a function of the argument *shape* and the\n * dialect, never of the values (invariant 2). That is what makes the whole\n * compiler unit-testable with no database attached, and it is why the plan\n * cache can key on shape alone.\n */\nexport function compile(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n /**\n * Which relation strategy plans this query's include tree, if not the default.\n *\n * Reads only. A write's relations are loaded from its `returning` rows, and\n * `insert … returning` cannot carry a lateral join — so `compileWrite` has\n * nothing to do with a strategy and is not given one.\n */\n strategy?: RelationStrategy,\n): QueryPlan {\n // Before the read check, because `aggregate` is a read whose result is\n // neither rows nor a number and so shares none of `compileRead`'s shaping.\n if (isAggregateOperation(op)) return compileAggregate(schema, op, args, dialect);\n if (isGroupByOperation(op)) return compileGroupBy(schema, op, args, dialect);\n\n if (isReadOperation(op)) {\n return compileRead(schema, op, args, dialect, strategy);\n }\n if (isWriteOperation(op)) return compileWrite(schema, op, args, dialect);\n throw new UnsupportedQueryError(\n op,\n schema.name,\n op,\n `'${op}' is not an operation this ORM compiles — the reads, the writes, ` +\n `'aggregate' and 'groupBy' are, and a raw statement goes through ` +\n `'DB.query' or 'DB.execute'.`,\n );\n}\n\nexport { compileRead, isReadOperation };\nexport { compileAggregate, isAggregateOperation } from \"./aggregate\";\nexport { compileGroupBy, isGroupByOperation } from \"./group-by\";\nexport { compileWrite, isWriteOperation };\nexport {\n planNestedWrites,\n type ForeignKeyContribution,\n type NestedWritePlanning,\n} from \"./nested-writes\";\nexport { assertUniqueWhere, matchUniqueKey, uniqueKeys } from \"./unique\";\nexport { compileWhere } from \"./where\";\nexport { compileOrderBy, parseOrderBy } from \"./orderBy\";\nexport { resolveSelection } from \"./select\";\nexport {\n MAX_RELATION_DEPTH,\n attachRelations,\n batchedStrategy,\n planRelations,\n type RelationPlan,\n type RelationPlanning,\n type RelationRequest,\n type RelationStrategy,\n} from \"./plan-relations\";\nexport * from \"./fragment\";\n\nexport { lateralStrategy } from \"./lateral\";\n",
|
|
27
27
|
"import { compile } from \"./compile\";\nimport type { BindContext } from \"./compile/fragment\";\nimport type { NestedWriteStep, RelationPlan } from \"./compile/plan-relations\";\nimport type { SqlDialect } from \"./dialect\";\nimport { jsonNullKind } from \"./json-null\";\nimport type { RelationStrategy } from \"./compile/plan-relations\";\nimport type { ModelSchema } from \"./schema\";\n\n/**\n * The public operations. The raw operations are deliberately not among them:\n * they are excluded at the operation level rather than narrowed out of the\n * argument types, because narrowing Prisma's recursive where-inputs with `Omit`\n * is miserable.\n *\n * `aggregate` joined the list once there was a measured account of what Prisma\n * returns for one — see `compile/aggregate.ts`. `groupBy` followed in its own\n * change, for the reason this note gave for separating them: `having` is a\n * second predicate compiler over aggregate expressions rather than columns, and\n * `orderBy` carries a restriction no other operation has. See\n * `compile/group-by.ts`.\n */\nexport type Operation =\n | \"findUnique\"\n | \"findUniqueOrThrow\"\n | \"findFirst\"\n | \"findFirstOrThrow\"\n | \"findMany\"\n | \"count\"\n | \"aggregate\"\n | \"groupBy\"\n | \"create\"\n | \"createMany\"\n | \"update\"\n | \"updateMany\"\n | \"upsert\"\n | \"delete\"\n | \"deleteMany\";\n\n/**\n * Per-call options that are *not* part of the query.\n *\n * A second parameter rather than a key inside `args`, deliberately: `args` is\n * typed as Prisma's own `FindManyArgs` and friends, and intersecting every one\n * of them with a gemi-specific key would mean `Prisma.UserFindManyArgs` no longer\n * describes what the operation accepts. Keeping it outside leaves those types\n * usable verbatim, which is the DX parity the project is built on.\n *\n * It also keeps the plan cache honest: these do not affect the SQL, so they must\n * not affect the plan key, and they cannot if they never reach the compiler.\n */\nexport interface ExecOptions {\n /**\n * Which relation strategy loads this query's `include` tree.\n *\n * `\"batched\"` issues one query per include node; `\"lateral\"` folds them into\n * the root statement with a `LATERAL` join on Postgres, declining per node for\n * anything it cannot express. Omitted, `defaultStrategy` chooses.\n *\n * Unlike `track`, this **does** reach the compiler and **is** part of the plan\n * key — two strategies emit different SQL for the same arguments, so sharing a\n * plan between them would run one query's statement for the other's request.\n * That is the one thing a per-call option must not do, which is why this one is\n * threaded rather than kept out of the way like `track` is.\n */\n strategy?: \"batched\" | \"lateral\";\n /**\n * Record where each returned row came from, so `Model.save(row)` can update it.\n *\n * Off by default: it costs a `WeakMap` insert and a snapshot clone per row, and\n * iteration 7 measured shaping at ~55µs per 1000 rows — so the default path\n * does not pay for a feature most queries do not use.\n */\n track?: boolean;\n}\n\n/**\n * The output of compilation. `text` is a pure function of the argument\n * *shape*; `bind` is the only thing that ever sees a value. Splitting them is\n * what makes the plan cacheable, what will let Postgres reuse prepared\n * statements, and what makes injection structurally impossible.\n */\nexport interface QueryPlan {\n text: string;\n bind(args: any, context?: BindContext): unknown[];\n shape(rows: unknown[]): unknown;\n /**\n * Nested-write steps that run before the statement, contributing foreign keys\n * into the bind context, and after it, writing rows that reference the one\n * just created. Both left undefined for a query with no nested writes.\n */\n before?: NestedWriteStep[];\n after?: NestedWriteStep[];\n /**\n * The relation nodes this query's `include` / `select` asks for, one plan per\n * node. Empty — and left undefined — for a query with no relations, so the\n * choke point can skip the whole stage with one check.\n */\n relations?: RelationPlan[];\n /**\n * Which relation strategies this plan's own nodes used, deduplicated and\n * sorted. Undefined when the query has no relations.\n *\n * Exists because a silent planner is untestable: once more than one strategy\n * can be chosen, \"which one ran\" has to be answerable from outside, both for\n * tests and for debugging a query that is slower than expected.\n *\n * **This plan's own nodes only, and that is not a limitation to remove.** A\n * nested level is loaded by `$exec` on the *child* model, which compiles its\n * own plan and chooses its own strategy — so a depth-3 include is three plans\n * with three independent answers, and asking the root for all of them would\n * mean reporting decisions that have not been made yet. It also means a mixed\n * tree is expressible, which is the point of the strategy being per-node.\n */\n strategies?: string[];\n /**\n * Fields the query had to select to stitch relations, but which the caller's\n * `select` did not ask for. Dropped once the relations are attached.\n */\n hidden?: string[];\n /**\n * Whether this plan projects a `_count`. Undefined when it does not.\n *\n * A write needs this for the same reason it needs `relations`: a `delete`\n * with either one is read *before* the row goes, so the choke point has to\n * know there is something to read. A count is not a relation plan — it is a\n * column in the statement, not a second query — so it cannot be discovered by\n * looking at `relations`, and `include: { _count: … }` on its own leaves that\n * list empty.\n */\n counts?: boolean;\n}\n\n/**\n * The cache is bounded because one part of the key space is *not* finite per\n * application: on SQLite an `in` list expands to one placeholder per element,\n * so every distinct list length is its own plan — and list length is routinely\n * request-derived (`?ids=1,2,3` off a query string) or, from iteration 3,\n * derived from the number of parent rows a relation is being loaded for.\n * Unbounded, that is a slow memory leak reachable from untrusted input.\n *\n * Postgres binds the whole list to one parameter, so there the length is not\n * part of the key at all — see `collapsedList`.\n *\n * A coarser key cannot fix the SQLite side: collapsing lengths there would hand\n * a plan the wrong number of placeholders. Eviction is the only correct answer.\n *\n * Least-recently-used, implemented on `Map`'s insertion ordering: re-inserting\n * on a hit moves the entry to the end, so the first key `keys().next()` yields\n * is always the coldest. A miss past the cap evicts exactly one entry. The cap\n * is far above any realistic application's distinct query shapes, so a\n * well-behaved app never evicts at all.\n */\nconst MAX_CACHED_PLANS = 1000;\n\nconst cache = new Map<string, QueryPlan>();\nlet compiles = 0;\nlet hits = 0;\nlet evictions = 0;\n\n/**\n * A canonical description of an argument tree's *shape* — key paths, operators\n * and value kinds, never values. Keys are sorted so `{ where: { a, b } }` and\n * `{ where: { b, a } }` are one cache entry rather than two, and `undefined`\n * values are dropped because Prisma treats them as absent.\n *\n * The result is used directly as the cache key rather than being hashed: a\n * canonical string is a perfect hash, and a collision would mean running the\n * wrong SQL — not worth trading for shorter keys.\n */\n/**\n * Argument keys whose *values* are structural rather than parameters — they end\n * up in the SQL text, so two calls that differ only there are two different\n * queries and must be two different plans.\n *\n * Getting this wrong is silent: `orderBy: { id: \"asc\" }` and\n * `orderBy: { id: \"desc\" }` have identical *types*, so without this they would\n * share a cache entry and the second caller would get the first one's SQL. The\n * plan-cache discrimination tests exist to catch exactly that.\n */\nconst LITERAL_KEYS = new Set([\n \"orderBy\",\n \"select\",\n // `omit` is `select`'s complement and decides the same thing — which columns\n // the statement asks for — so it fails the same way and in the worse\n // direction. `omit: { password: true }` and `{ password: false }` both shape\n // to `boolean`, so whichever compiled first decided for the other: an admin\n // screen that keeps the column warms the cache, and the public endpoint that\n // asked to hide it gets the column back. The reverse order is harmless, which\n // is exactly the wrong asymmetry.\n \"omit\",\n \"include\",\n \"distinct\",\n \"mode\",\n // An aggregate's functions decide the *projection*, so they are structural\n // for exactly the reason `select` is — and they fail the same way. Without\n // them, `_count: { email: true }` and `_count: { email: false }` both shape to\n // `{_count:{email:boolean}}`, share one entry, and the second caller gets the\n // first one's statement: a column they switched off, counted anyway. `_count:\n // true` against `_count: false` is the same collision one level up.\n \"_count\",\n \"_avg\",\n \"_sum\",\n \"_min\",\n \"_max\",\n // `skipDuplicates: true` emits `on conflict do nothing` and `false` does not,\n // so the *value* is in the SQL text. Without it here both shape to `boolean`,\n // share one entry, and whichever call compiled first decides whether the\n // other one skips conflicts — an insert that raises where the caller asked it\n // not to, or worse, one that silently swallows a duplicate the caller wanted\n // to hear about.\n \"skipDuplicates\",\n // `groupBy`'s grouped columns, which reach the SQL as *identifiers* — both\n // the select list and the `group by`. `[\"role\"]` and `[\"locale\"]` have the\n // same shape, `[string]`, so without this they would be one cache entry and\n // the second caller would be grouped by the first caller's column. Silently:\n // the result is well-formed, just grouped by something else.\n \"by\",\n]);\n\n/**\n * The aggregate kinds, which mean **two different things by position**.\n *\n * As a *projection* — `_count: { email: true }` — their contents decide the\n * select list, so they are in {@link LITERAL_KEYS} and recorded verbatim.\n * Inside a `having` the same keys introduce a *comparison*, and its operand is\n * a bound parameter like any other.\n *\n * Nothing else in the walk is ambiguous this way, which is why this is a set\n * rather than a general rule: the position is what disambiguates, and only\n * these five keys have two positions.\n */\nconst AGGREGATE_KINDS = new Set([\"_count\", \"_avg\", \"_sum\", \"_min\", \"_max\"]);\n\nexport function canonicalShape(\n value: unknown,\n literal = false,\n /**\n * Set when the dialect binds an `in` list as a single parameter, so that the\n * list's *length* stops being part of the key. See `collapsedList`.\n */\n collapseLists = false,\n /**\n * Set inside a `having`, where an aggregate kind is an operator rather than a\n * projection selector.\n *\n * A separate flag rather than clearing `literal`, because clearing it would\n * be wrong: `mode` lives inside `where` — already a value subtree — and\n * *must* stay literal, since `insensitive` and `default` compile to `ilike`\n * and `like`. So \"nothing below a value key is structural\" is not the rule;\n * \"an aggregate kind below a `having` is not\" is.\n */\n inHaving = false,\n): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n\n const type = typeof value;\n // In a structural subtree the value itself is part of the query, so it is\n // recorded verbatim: \"asc\" and \"desc\" have to be two keys, and so do the\n // `true` and `false` of a `select`.\n if (type !== \"object\") return literal ? JSON.stringify(value) : type;\n\n if (value instanceof Date) return \"date\";\n\n /**\n * Prisma's Json null sentinels, each its own key.\n *\n * They carry no enumerable properties, so the object branch below recorded\n * all three — and a genuine empty Json object — as `{}`. They do not compile\n * alike: `DbNull` is `is null`, `JsonNull` and `{}` are `= ?` with different\n * bound values, and `AnyNull` is `is null or = ?`. So the first shape\n * compiled won the entry and every later one was answered with its text —\n * `JsonNull` served `is null` returns the SQL-NULL rows, and `DbNull` served\n * `= ?` binds NULL and matches nothing. Both silent, both wrong, and both\n * only reachable once two of them meet in one process (#266).\n *\n * This is invariant 2 read backwards. `binding.invariants.test.ts` asserts\n * that one shape with different values gives byte-identical SQL; the same\n * rule requires that different SQL means different shape, which is the half\n * nothing was checking.\n *\n * Imported rather than duplicated. `plan.ts` spells `$compositeIn` literally\n * to avoid depending on the compiler — `json-null.ts` is not the compiler but\n * a leaf module with no imports of its own, so this respects that rule\n * instead of making an exception to it.\n */\n const sentinel = jsonNullKind(value);\n if (sentinel) return `jsonNull:${sentinel}`;\n\n if (Array.isArray(value)) {\n // Element-wise by default, so the length is part of the shape. Usually that\n // is not a choice: `AND: [a, b]` and `AND: [a]` are different predicates,\n // `orderBy: [a, b]` is a different sort, and on SQLite `in: [a, b]`\n // compiles to `in (?, ?)` — collapsing any of them would hand a plan the\n // wrong SQL or the wrong number of placeholders.\n //\n // The exception is the `in` / `notIn` operand on a dialect that binds it as\n // one parameter, which `shapeOfMember` takes before this is reached.\n return `[${value\n .map((item) => canonicalShape(item, literal, collapseLists, inHaving))\n .join(\",\")}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(\n ([key, v]) =>\n `${key}:${shapeOfMember(key, v, literal, collapseLists, inHaving)}`,\n );\n return `{${entries.join(\",\")}}`;\n}\n\n/**\n * The keys whose operand is an array that binds as **one** parameter, so its\n * length never reaches the SQL text and must not reach the cache key either.\n *\n * `in` / `notIn` bind as one `= any($1)` on Postgres. So do a scalar list's\n * `hasEvery`, `hasSome` and `push` (#300) — `col @> $1`, `col && $1` and\n * `array_cat(col, $1)` are each one parameter however long the operand is, so\n * recording it element-wise mints one entry per distinct length, every one of\n * them holding SQL identical to its neighbours'. A `hasEvery` built from user\n * input is exactly the churn `collapsedList` exists to prevent.\n *\n * **Three names, and the two obvious omissions are deliberate.**\n *\n * `equals` and `set` are *overloaded*, and `set` is the one that would have\n * been a real bug rather than a missed optimisation: it is also a **relation**\n * operator — `data: { tags: { set: [{ id: 1 }, { id: 2 }] } }` rewrites a join\n * table, and that statement's text grows with the list. Collapsing it would\n * hand a plan the wrong number of placeholders, which is precisely the failure\n * the note above warns about for `OR`. Checked in `compile/nested-writes.ts`\n * rather than assumed from the name.\n *\n * Those three carry no such second meaning: `grep` finds them only in the\n * scalar-list filter set and the list write operators.\n *\n * **`path` is not a list of values at all, and reaches the same arithmetic from\n * a different direction (#301).** `where: { metadata: { path: [\"a\", \"b\"],\n * equals: … } }` binds the whole path as one `text[]` through `#>`, so every\n * depth compiles to the identical `(\"metadata\" #>> $1) = $2`. Measured over the\n * corpus: `[\"a\"]`, `[\"a\",\"b\"]` and `[\"a\",\"b\",\"c\"]` were three cache entries\n * holding one statement, and a path depth taken off a request is as ordinary as\n * a list length taken off one.\n *\n * SQLite needs nothing here and gets nothing: a path is a *string* there\n * (`\"$.a.b\"`), so depth was never in the shape to begin with, and\n * `collapseLists` is false on that dialect anyway.\n *\n * **`path` collapses only when every segment is a `string`, and that narrowing\n * is the whole safety argument rather than a fussy detail.** `collapsedList`\n * erases the elements as well as the count, so `[*]` says nothing about what is\n * *in* the array — while `assertPathShape` (`compile/where.ts`) refuses an\n * array whose segments are not each a string or a number. Collapse the two\n * together and the refusal stops being reachable on a cache hit, the `disconnect:\n * true`/`false` failure this file describes a few lines below, arriving from the\n * other side: a plan compiled for `[\"a\"]` served `[\"a\", null]`, `[[\"a\"]]` and\n * `[{ k: 1 }]` without recompiling, and `[[\"a\"]]` is the bad one — it flattens\n * to `{\"a\"}` and answers as if the caller had written `[\"a\"]`. Wrong rows, no\n * error. Measured through `getOrCompile` + `bind` on Postgres, and it is a\n * regression this collapse would have introduced: on `main` those three key\n * apart from `[\"a\"]` element-wise, so each is refused on every call.\n *\n * The predicate has to stay a **subset** of what `assertPathShape` accepts, not\n * an equal — a collapsed shape must never cover an argument the compiler would\n * refuse, but leaving an accepted one uncollapsed costs a cache entry and\n * nothing else. `string` is that subset today (`assertPathShape` also takes a\n * `number`, so a numeric segment simply keeps its element-wise shape) and it\n * stays one under #380, which narrows `JsonPath` to `readonly string[]`. It is\n * duplicated knowledge either way — `plan.ts` holds no dependency on the\n * compiler, deliberately — so `plan-key.invariants.test.ts` asserts the\n * subset relation directly, over the malformed shapes above.\n *\n * **The gate is `collapseLists` — that is `bindsListAsOneParameter`, a property\n * about `in` lists rather than about paths — and the conflation deserves\n * stating.** It is the right condition on both implemented dialects because the\n * array path *grammar* exists only where `jsonPathSyntax` is `\"array\"`, and the\n * one dialect with that grammar binds the array whole. A dialect that spelled a\n * path as an array but emitted one parameter per segment would make this wrong\n * in the dangerous direction — a plan reached with the wrong number of\n * placeholders, the trap this comment already describes for SQLite's `in` — and\n * would need a flag of its own. None exists to hang one on today that is not\n * speculative, and `plan-key.invariants.test.ts` walks both grammars on both\n * dialects asserting same-key-implies-same-SQL, so that is what would fail —\n * conditional on the new dialect being added to `DIALECTS` there, which is the\n * same condition every other property in that file already carries.\n *\n * **A *column* named `path` is the other collision, and it is harmless —\n * measured rather than assumed**, since `LIST_KEYS` matches by name at any\n * depth. Every position where a bare array can sit directly under such a key\n * binds as one parameter on Postgres: `where: { path: [...] }` on a Json column\n * is `\"path\" = $1::text::jsonb`, `equals: [...]` on a scalar list is\n * `\"path\" = $1`, and `data: { path: [...] }` is one `values` placeholder for\n * either. A bare-array *filter* on a scalar list is refused outright. So the\n * collapse is correct there rather than merely unreachable, which incidentally\n * closes a sliver of the case named next.\n *\n * **One case is still uncollapsed and needs a schema to fix.** A bare array as\n * a *write* value — `data: { tags: [\"a\", \"b\"] }` — is keyed by the **field\n * name**, so no fixed set can recognise it; telling it from `data: { AND: … }`\n * needs to know that `tags` is a list on this model, and `canonicalShape` is\n * deliberately schema-free. Left as churn rather than guessed at: the cost is\n * bounded by the LRU and the SQL is identical either way, where a wrong\n * collapse is a wrong statement. The filter side — which is where a\n * user-sized list actually arrives — is covered.\n */\nconst LIST_KEYS = new Set([\n \"in\",\n \"notIn\",\n \"hasEvery\",\n \"hasSome\",\n \"push\",\n \"path\",\n]);\n\n/**\n * The internal composite-`in` key — see `compile/where.ts`, which owns it.\n *\n * Spelled here rather than imported to keep `plan.ts` free of a dependency on\n * the compiler, the way it already is for every other key it recognises.\n */\nconst COMPOSITE_IN = \"$compositeIn\";\n\n/**\n * `in: [1, 2]` and `in: [1, 2, 3]` on Postgres are the same SQL text — the\n * whole array binds to `= any($1)` — so they must be the same cache entry.\n *\n * Recording them element-wise there is not *wrong*, but it mints one entry per\n * distinct list length, each holding SQL identical to its neighbours'. From\n * iteration 3 on that stops being a curiosity: every batched relation query is\n * an `in` over the parent keys, so the list length is the number of rows the\n * parent query returned, and a variably-sized parent set would churn the LRU on\n * every dialect rather than on the one that needs it.\n *\n * An empty list keeps its own key: `in: []` compiles to a constant-false\n * predicate rather than to `= any($1)`, which is a different text.\n *\n * **It covers `in` / `notIn` and nothing else, which leaves one gap worth\n * naming here rather than only where it happens.** A relation joining on more\n * than one field cannot be filtered with a single `in`, so the batched loader\n * builds an `OR` of `AND`s instead (see `childQuery`) — and an `OR`'s text\n * genuinely varies with its branch count, so it cannot be collapsed the way a\n * Postgres `= any($1)` can: a shared key would hand a plan the wrong number of\n * placeholders, which is the trap described above for SQLite. Measured over\n * parent counts 2, 3, 10, 50:\n *\n * sqlite composite: 4 keys single: 4 keys\n * postgres composite: 4 keys single: 1 key\n *\n * That gap is closed on Postgres by #97: a composite key binds one array per\n * *column* through `unnest`, so its text is fixed too, and `shapeOfMember`\n * collapses its tuple list on the same condition this function uses. SQLite has\n * no such form, keeps the `OR`, and churns as it always has — which is the same\n * sentence as above, and for the same reason.\n */\nfunction collapsedList(value: unknown[]): string {\n return value.length === 0 ? \"[]\" : \"[*]\";\n}\n\n/**\n * Keys that end the structural subtree. `select` and `include` are structural,\n * but a `where` nested inside one is filter *values* again — and recording\n * those verbatim would put user data into a long-lived global map and give\n * every distinct filter value its own cache entry.\n *\n * Live as of iteration 3: `include: { accounts: { where: { deletedAt: null } } }`\n * is one plan whatever the filter's values are, and the relation loader reads\n * those values back out of the *call's* argument tree rather than the compiled\n * plan's.\n */\nconst VALUE_KEYS = new Set([\"where\", \"cursor\", \"data\"]);\n\nfunction shapeOfMember(\n key: string,\n value: unknown,\n literal: boolean,\n collapseLists: boolean,\n inHaving: boolean,\n): string {\n // `take` is a parameter, but its *sign* is not: a negative take means \"the\n // last N\", which flips every ordering term and so changes the SQL text. The\n // magnitude stays out of the key, so `take: 10` and `take: 20` still share a\n // plan the way every other value does.\n if (key === \"take\" && typeof value === \"number\") {\n return `number:${Math.sign(value)}`;\n }\n // `skip` is a parameter with no structural half at all, and it needs saying\n // because a *relation node's* `skip` sits inside `include` — a literal\n // subtree, where a bare number would otherwise be recorded verbatim and mint\n // one plan entry per page. The root's `skip` never had the problem, which is\n // exactly why it went unnoticed until a node could carry one.\n if (key === \"skip\" && typeof value === \"number\") return \"number\";\n // `path` is the one member of `LIST_KEYS` whose *elements* are checked by the\n // compiler, so it is the one that cannot be collapsed unconditionally: `[*]`\n // erases the segment kinds, and `assertPathShape` refuses a segment that is\n // neither a string nor a number. A malformed path therefore keeps its\n // element-wise shape, keys apart from every valid one, and is refused on every\n // call rather than served by a plan compiled for a path it does not resemble.\n // See {@link LIST_KEYS}.\n if (collapseLists && LIST_KEYS.has(key) && Array.isArray(value)) {\n if (key !== \"path\" || value.every((segment) => typeof segment === \"string\")) {\n return collapsedList(value);\n }\n }\n /**\n * A composite `in`'s tuple list collapses on exactly the dialects where its\n * SQL text does not grow with it — the same condition, and the same reason,\n * as `collapsedList` for a single-column `in`.\n *\n * On Postgres the tuples become one array parameter per *column*, so every\n * parent count is one statement and must be one entry: without this a batched\n * composite `include` mints a plan per page size, which is #97 and the whole\n * point of the `unnest` form. On SQLite the key is never emitted — the loader\n * keeps the `OR`, whose text does grow — so the collapse cannot be reached\n * there to be wrong.\n *\n * The `fields` stay verbatim: they are *identifiers* in the emitted SQL, so\n * two relations joining on different columns must not share an entry. Only\n * the tuple list is collapsed.\n */\n if (key === COMPOSITE_IN) {\n const operand = value as { fields: unknown; values: unknown[] };\n return canonicalShape(\n collapseLists\n ? { fields: operand.fields, values: collapsedList(operand.values) }\n : value,\n true,\n collapseLists,\n );\n }\n\n /**\n * `disconnect: true` and `disconnect: false` are two different writes, and\n * nothing above tells them apart: they sit under `data`, which is a\n * {@link VALUE_KEYS} subtree, so both shape to `boolean` and share one entry.\n *\n * **On the owning side the boolean is structural — it decides the SET list\n * rather than a value bound into one**, and that is the whole of why the\n * guard has to exist. `disconnect: true` pushes a contribution for the\n * foreign key and `disconnect: false` pushes none, so the two spellings are\n * two assignment lists and therefore two statement *texts*, chosen once,\n * when the plan is built. Measured on `User.organization`, sqlite:\n *\n * data: { name, organization: { disconnect: true } }\n * -> update \"User\" set \"name\" = ?, \"organizationId\" = ?, \"updatedAt\" = ? …\n * data: { name, organization: { disconnect: false } }\n * -> update \"User\" set \"name\" = ?, \"updatedAt\" = ? …\n *\n * When the `disconnect` is the **only** member of `data` the `false` arm\n * leaves no assignment at all, and `compileUpdate` degenerates further, to a\n * bare `select` of the row. That is the special case, not the rule — say it\n * the other way round and a reader takes `{ name, disconnect: false }` to\n * drop the `name` write too.\n *\n * A cache **hit** skips compilation, so a hit that got the boolean wrong\n * runs the other spelling's statement, and nothing downstream can rescue it:\n * on this side the compiled plan *is* the decision.\n *\n * Note the worked example is deliberately *not* offered as parity with\n * Prisma. On a **many-to-one** — which `User.organization` is — Prisma\n * discards the operand and nulls the key for `disconnect: false`, and gemi\n * declines to reproduce that, since it is the same silent destructive write\n * #358 removed from this cache. `writes.differential.test.ts` pins the\n * divergence (\"where the two clients still disagree\"). The guard's argument\n * needs no agreement from Prisma: two statement texts is the whole of it.\n *\n * **The foreign side is not like it, and the contrast is what makes the key\n * load-bearing here and merely prudent there.** Where the child holds the\n * key the operand becomes a *statement the step runs*, and `toOneOperand`\n * re-reads the boolean out of the call at bind time — `listOf(null)` is no\n * statement — so a plan mis-served there still writes nothing. `delete`\n * shares this guard for that side's sake; on this side it is refused\n * outright, since deleting the far row through a `data` key would remove a\n * row the statement is not about.\n *\n * **The history, which is why the guard was added rather than why it stays.**\n * When #358 added it, `planOwningSide` still refused `operand !== true` at\n * compile time and then pushed a constant `value: () => null` for the one arm\n * it took — and the refusal was no protection at all, because a cache *hit*\n * skips compilation and so never re-runs it. A plan compiled from\n * `disconnect: true` served `disconnect: false` and nulled the foreign key on\n * a call that asked for nothing. Measured against the real client, so the\n * damage was the gap and not the guess. Measured on the one-to-one the\n * differential suite pins the grammar against, `Profile.user`:\n * `disconnect: false` with a child present leaves the row exactly as it was,\n * foreign key intact. That is the reference for the no-op — the many-to-one\n * of the worked example above is where the two clients part company, and\n * gemi answers one grammar one way on both shapes. #359 then implemented all\n * three arms and removed that refusal, which did not retire the guard — it\n * made it load-bearing a second way, since the two spellings now differ in\n * statement text and not only in what a contribution binds.\n *\n * **It cannot simply join {@link LITERAL_KEYS}, which is the same bug class\n * documented there twice already** — for `omit` and for `skipDuplicates`.\n * Those keys match by *name at any depth* and raise `literal` over the whole\n * subtree below them, so a to-many `disconnect: { id: 1 }` would record the\n * `1` verbatim and mint one cache entry per id — the unbounded growth\n * `VALUE_KEYS`' own comment exists to prevent, and user data in a long-lived\n * global map. Only the boolean spelling is structural, so only the boolean is\n * guarded; every other operand shape reaches the key through its structure,\n * as it always did.\n */\n if ((key === \"disconnect\" || key === \"delete\") && typeof value === \"boolean\") {\n return JSON.stringify(value);\n }\n\n if (VALUE_KEYS.has(key)) {\n return canonicalShape(value, false, collapseLists, inHaving);\n }\n\n /**\n * `having` is a predicate, so its operands are parameters — and unlike every\n * other value key it contains keys that {@link LITERAL_KEYS} would otherwise\n * re-raise one level down.\n *\n * Without this, `having: { role: { _count: { gt: 5 } } }` records `gt:5`\n * verbatim and mints one cache entry per threshold, each holding\n * byte-identical SQL. The cap is 1000 and a threshold off a query string is\n * ordinary, so it fills the cache and evicts every other query's plan — the\n * same pathology `plan.ts` already describes for `in`-list lengths, and the\n * thing `VALUE_KEYS`' own comment warns about: it would put user data into a\n * long-lived global map.\n *\n * The equivalent `where` — `{ role: { gt: 5 } }` — has always been one entry,\n * which is the behaviour this matches.\n */\n if (key === \"having\") return canonicalShape(value, false, collapseLists, true);\n\n // In a `having`, an aggregate kind is a comparison rather than a projection,\n // so it does not raise `literal` for its subtree.\n if (inHaving && AGGREGATE_KINDS.has(key)) {\n return canonicalShape(value, false, collapseLists, true);\n }\n\n return canonicalShape(\n value,\n literal || LITERAL_KEYS.has(key),\n collapseLists,\n inHaving,\n );\n}\n\n/**\n * Takes the dialect itself rather than its name: whether an `in` list's length\n * belongs in the key is a property of how that dialect *binds* the list, and\n * asking the dialect keeps `if (dialect === \"postgres\")` out of here the same\n * way the compiler keeps it out of itself.\n */\nexport function planKey(\n dialect: SqlDialect,\n model: string,\n op: Operation,\n args: unknown,\n /**\n * The relation strategy's name, because **different strategies emit different\n * SQL for the same arguments**.\n *\n * Leaving it out would let a query run under one strategy return a plan\n * compiled for the other — a lateral statement executed where the caller asked\n * for batched, or worse a batched one whose children are then never loaded\n * because `attachRelations` skips a plan carrying `root`. Silent wrong results\n * from a caching bug, which is the same failure shape iteration 6's policy\n * ordering had to avoid.\n *\n * Defaulted so every existing caller keys exactly as it did, which is what\n * keeps this from invalidating a warm cache.\n */\n strategy: string = \"batched\",\n): string {\n return `${dialect.name}:${strategy}:${model}:${op}:${canonicalShape(\n args,\n false,\n dialect.bindsListAsOneParameter,\n )}`;\n}\n\nexport function getOrCompile(\n schema: ModelSchema,\n op: Operation,\n args: any,\n dialect: SqlDialect,\n strategy?: RelationStrategy,\n): QueryPlan {\n const key = planKey(dialect, schema.name, op, args, strategy?.name);\n const cached = cache.get(key);\n if (cached) {\n hits++;\n // Re-insert to move this key to the end of `Map`'s insertion order, so the\n // oldest *unused* entry is the one eviction takes.\n cache.delete(key);\n cache.set(key, cached);\n return cached;\n }\n\n const plan = compile(schema, op, args, dialect, strategy);\n compiles++;\n\n if (cache.size >= MAX_CACHED_PLANS) {\n const coldest = cache.keys().next();\n if (!coldest.done) {\n cache.delete(coldest.value);\n evictions++;\n }\n }\n\n cache.set(key, plan);\n return plan;\n}\n\n/**\n * Public on purpose, not only as a test seam. `compiles` climbing in step with\n * `hits` means some query shape is not being reused — a metric worth graphing,\n * and the cheapest signal that a caller is accidentally varying its argument\n * shape per request. A non-zero `evictions` means the same thing more loudly:\n * the shape space has outgrown the cap, which for a normal application should\n * not happen.\n */\nexport function planCacheStats(): {\n size: number;\n compiles: number;\n hits: number;\n evictions: number;\n capacity: number;\n} {\n return {\n size: cache.size,\n compiles,\n hits,\n evictions,\n capacity: MAX_CACHED_PLANS,\n };\n}\n\n/**\n * Drops every compiled plan. Needed by tests that assert compile counts, and by\n * anything that reloads the generated schema in a running process.\n */\nexport function clearPlanCache(): void {\n cache.clear();\n compiles = 0;\n hits = 0;\n evictions = 0;\n}\n",
|
|
28
28
|
"import { currentConnectionName } from \"./context\";\nimport { UnsupportedQueryError } from \"./errors\";\nimport type { ModelSchema } from \"./schema\";\n\n/**\n * Row provenance: where a returned object came from, and what it looked like\n * when it arrived.\n *\n * This is the whole of invariant 5, and the reason it is opt-in. Queries return\n * plain objects — no proxies, no conditional return types, no signature that\n * changes depending on a flag — so `save(row)` needs somewhere *outside* the row\n * to remember which model and which primary key it belongs to. A `WeakMap` keyed\n * on the object is that somewhere, and it is the only shape that does not leak:\n * the entry goes when the row does.\n *\n * **The cost of that choice, stated up front because it is the first thing\n * anyone will hit.** Provenance is attached to an object *identity*. A row that\n * is spread (`{ ...user }`), cloned, or round-tripped through JSON is a\n * different object and has none. `save` raises in that case rather than\n * guessing, because the guess would be \"write every column\", and writing a\n * column the caller never fetched is how a partial select silently reverts data.\n *\n * Off by default. Iteration 7 measured shaping at ~55µs per 1000 rows, and a\n * WeakMap insert plus a snapshot clone per row is a real fraction of that — so\n * the default path must not pay for a feature most queries do not use.\n */\n\nexport interface Provenance {\n /** The model name, so `save` compiles against the right schema. */\n model: string;\n /**\n * The connection the row was read on, so `save` writes it back to the\n * database it came from.\n *\n * The one piece of ORM state that cannot live in the ambient scope, and the\n * reason it is recorded here instead. Everything else about a connection is\n * true for an async subtree; this is true of a *value* that outlives the\n * query that produced it — a row read on `analytics`, mutated three functions\n * later, and saved from a scope that never named a connection.\n *\n * Without it `save` compiled a correct `update` and sent it to the default\n * connection. In production, where two connections usually address the same\n * database with the same id space, that is not a failed write: it is the\n * *wrong row* updated, with no error to notice.\n */\n connection: string;\n /** The primary key values, captured at fetch time so a mutation cannot move the row. */\n key: Record<string, unknown>;\n /**\n * The values as fetched, for the columns that were fetched.\n *\n * Only those columns: a partially selected row can still be saved, it just\n * cannot write what it never read. That is the correct behaviour rather than a\n * limitation — the alternative is writing a default over a column that holds\n * something else.\n */\n snapshot: Record<string, unknown>;\n}\n\nconst provenance = new WeakMap<object, Provenance>();\n\n/**\n * Records provenance for a shaped row.\n *\n * Called only when the caller asked for it. The snapshot is a shallow copy of\n * the row's own scalar keys — shallow because a deep clone would have to decide\n * what to do with a `Json` column's nested object, and the dirty check compares\n * with `!==`, so a caller who mutates a nested object *in place* has changed\n * something this cannot see. That is documented rather than solved: solving it\n * means structural comparison per row per field, which is exactly the per-row\n * cost this feature is trying to keep off the default path.\n */\nexport function track(\n row: object,\n schema: ModelSchema,\n /**\n * Defaults to the connection in scope, which is the right answer for the only\n * caller that matters: `$exec` tracks inside the scope it entered, so a row\n * from `User.on(\"analytics\")` is stamped `analytics` with nothing passed.\n *\n * Explicit for `wrap`, which runs *after* that scope has closed and would\n * otherwise stamp every wrapped row with the default connection.\n */\n connection: string = currentConnectionName(),\n): void {\n const snapshot: Record<string, unknown> = {};\n const key: Record<string, unknown> = {};\n const source = row as Record<string, unknown>;\n\n for (const name of Object.keys(source)) {\n // The schema's own columns and nothing else. That covers the two things a\n // shaped row carries besides them — an attached relation, and a `_count` —\n // because neither is a field, and Prisma will not let a relation share a\n // name with one.\n //\n // This used to take a `relationKeys` list and skip those first. It never\n // changed the outcome: every name it excluded was excluded again on the\n // next line. What it did do was make the two call sites look like they\n // disagreed — `wrap` passed `[]`, `$exec` passed the plan's relations — and\n // give the reason for the exclusion to a line that was not performing it.\n // An attached child array in a snapshot would make every `save` look dirty,\n // since the relation loader replaces it; this is the line that prevents\n // that.\n if (!(name in schema.fields)) continue;\n snapshot[name] = source[name];\n }\n\n for (const name of schema.primaryKey) {\n key[name] = source[name];\n }\n\n provenance.set(row, { model: schema.name, connection, key, snapshot });\n}\n\nexport function provenanceOf(row: unknown): Provenance | undefined {\n // A fast path, not a correctness guard: `WeakMap.get` on a primitive returns\n // `undefined` rather than throwing, so removing this line would change\n // nothing an assertion could see. Recorded because a mutation of it survives\n // the suite, and a survivor with no test is normally worth chasing — this one\n // is not.\n if (row === null || typeof row !== \"object\") return undefined;\n return provenance.get(row);\n}\n\n/**\n * The columns whose value differs from the snapshot.\n *\n * Compared with `!==`, which is right for the scalars an encoder produces and\n * wrong for a `Date` — two Dates for the same instant are different objects. So\n * `Date` is compared by instant and typed arrays byte-wise, the same three cases\n * `sameEncoded` in the write compiler handles, and for the same reason: without\n * it, every save of a row carrying a timestamp would rewrite that timestamp.\n */\nexport function changedFields(\n row: object,\n /**\n * Required, not optional.\n *\n * The unfetched-column check below is `save`'s central safety guarantee, and an\n * optional schema would mean every caller that omitted it silently got the\n * permissive behaviour — the exact silent drop this function exists to refuse.\n * That is the same conclusion `render`'s `origin` reached on #49: optional\n * \"reintroduces in miniature the hole this check exists to close\".\n *\n * The argument is stronger here, because `changedFields` is exported from\n * `orm/index.ts`. An application computing its own diff would have got the old\n * semantics from a signature that read as though the schema were an extra, when\n * what it actually selected was whether the check ran at all.\n */\n schema: ModelSchema,\n): Record<string, unknown> {\n const record = provenanceOf(row);\n if (!record) return {};\n\n const source = row as Record<string, unknown>;\n const changed: Record<string, unknown> = {};\n\n for (const name of Object.keys(record.snapshot)) {\n if (!same(source[name], record.snapshot[name])) {\n changed[name] = source[name];\n }\n }\n\n // A value assigned to a column the query never fetched cannot be seen as\n // changed, because the diff walks the *snapshot's* keys — so it would be\n // silently dropped. That is the divergence class this codebase refuses\n // everywhere else: `save` returning happily having done less than it was told.\n //\n // The detection is exact rather than heuristic. A key on the row that the schema\n // declares as a field, is not a relation, and is *absent from the snapshot* can\n // only be an assignment to something unfetched — a fetched column is in the\n // snapshot by construction.\n assertNothingUnfetched(row, record, schema);\n\n return changed;\n}\n\nfunction assertNothingUnfetched(\n row: object,\n record: Provenance,\n schema: ModelSchema,\n): void {\n for (const name of Object.keys(row as Record<string, unknown>)) {\n if (name in record.snapshot) continue;\n if (!(name in schema.fields)) continue;\n if (name in schema.relations) continue;\n\n throw new UnsupportedQueryError(\n `save.${name}`,\n schema.name,\n \"save\",\n `'${name}' was not fetched by the query this row came from, so save ` +\n `cannot write it — the diff has nothing to compare it against, and ` +\n `writing it blind would overwrite whatever the column actually holds. ` +\n `Select '${name}' in the query, or update it explicitly with ` +\n `${schema.name}.update({ where, data: { ${name} } }).`,\n );\n }\n}\n\n/** Replaces the snapshot after a successful save, so a second save is a no-op. */\nexport function resnapshot(row: object, written: Record<string, unknown>): void {\n const record = provenanceOf(row);\n if (!record) return;\n\n for (const name of Object.keys(written)) {\n record.snapshot[name] = written[name];\n }\n}\n\n/**\n * Raised when `save` is handed something it cannot place.\n *\n * Separate from a generic error because the two causes have different fixes and\n * both are easy to hit: the query did not ask for tracking, or the object is a\n * copy of one that did.\n */\nexport function untracked(row: unknown, model: string): UnsupportedQueryError {\n const shape =\n row === null || row === undefined\n ? String(row)\n : Array.isArray(row)\n ? \"an array\"\n : typeof row;\n\n return new UnsupportedQueryError(\n \"save\",\n model,\n \"save\",\n `This object carries no provenance, so there is no row to update. Either ` +\n `the query did not ask for it — pass { track: true } as the second ` +\n `argument, e.g. ${model}.findUnique({ where }, { track: true }) — or this ` +\n `is a copy of a row that did. Provenance is keyed on object identity, so ` +\n `spreading, cloning or JSON round-tripping a row loses it. ` +\n `(Received ${shape}.)`,\n );\n}\n\n/** Test-only: provenance is a module-level WeakMap, and a test may need it empty. */\nexport function isTracked(row: unknown): boolean {\n return provenanceOf(row) !== undefined;\n}\n\n/**\n * Value equality for the dirty check. See `changedFields` for why it is not\n * `!==`.\n */\nfunction same(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n const left = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);\n const right = new Uint8Array(b.buffer, b.byteOffset, b.byteLength);\n if (left.length !== right.length) return false;\n for (let i = 0; i < left.length; i++) {\n if (left[i] !== right[i]) return false;\n }\n return true;\n }\n\n return false;\n}\n",
|
|
29
|
-
"import type { SQL, TransactionSQL } from \"bun\";\nimport type { DatabaseConnection } from \"../database/Connection\";\nimport { DatabaseManager } from \"../database/DatabaseManager\";\nimport { app } from \"../foundation/app\";\nimport { type BindContext, createBindContext } from \"./compile/fragment\";\nimport {\n currentConnectionName,\n currentTransaction,\n isSystemScope,\n runAsSystem,\n runAsUser,\n runOnConnection,\n withTransaction,\n} from \"./context\";\nimport {\n type FoldedRelation,\n type NestedWriteStep,\n type RelationExecutor,\n type RelationStrategy,\n attachRelations,\n} from \"./compile/plan-relations\";\nimport { resolveStrategy } from \"./compile/strategy\";\nimport { matchUniqueKey } from \"./compile/unique\";\nimport { upsertAbsentConflictKey } from \"./compile/write\";\nimport { dialectFor, type SqlDialect } from \"./dialect\";\nimport { clockCouldSkew, createProtocolSkewWarner } from \"./protocol-skew\";\nimport {\n MissingModelSchemaError,\n RecordNotFoundError,\n UnsupportedQueryError,\n UniqueConstraintError,\n ParameterLimitError,\n UnregisteredPolicyClassError,\n} from \"./errors\";\nimport {\n getOrCompile,\n type ExecOptions,\n type Operation,\n type QueryPlan,\n} from \"./plan\";\nimport {\n applyNestedPolicies,\n applyPolicies,\n applyRedaction,\n currentUser,\n isPreScoped,\n markOrmAuthored,\n markPreScoped,\n markRedactedAs,\n ormAuthoredFields,\n policiesFor,\n policyContext,\n redactedAs,\n NESTED_READ,\n type PolicyEntry,\n type PolicyContext,\n} from \"./policy\";\nimport {\n changedFields,\n provenanceOf,\n resnapshot,\n track,\n untracked,\n} from \"./provenance\";\nimport * as registry from \"./registry\";\nimport type { ModelSchema } from \"./schema\";\n\n/**\n * The base every generated model class extends.\n *\n * `$exec` is the framework's single choke point: it is the only place in the\n * ORM that touches the database, and the public operations on the generated\n * subclasses are one-line delegations to it. Nested relation reads and nested\n * writes recurse through it too. Everything cross-cutting hangs here — the plan\n * cache and constraint-error translation today, ambient transactions in\n * iteration 5, policies in iteration 6, plus slow-query logging and metrics\n * later. One operation that \"just does a quick insert directly\" silently\n * escapes all of it, which is why there is exactly one door.\n *\n * Framework internals take a `$` prefix so they cannot collide with anything an\n * application author adds to a model.\n */\n\n/** Operations Prisma raises on when nothing matched, rather than returning null. */\nconst ORTHROW = new Set([\n \"findFirstOrThrow\",\n \"findUniqueOrThrow\",\n // Prisma raises P2025 — \"No record was found for an update\" / \"...a delete\" —\n // rather than returning null, and the differential harness compares the fact\n // of throwing.\n \"update\",\n \"delete\",\n]);\n\n/**\n * `withTransaction` with the connection's configured warning threshold attached.\n *\n * Every transaction the ORM opens goes through here rather than calling\n * `withTransaction` directly, so `database.slowTransactionThreshold` is read in\n * one place instead of at each call site — and a call site added later cannot\n * quietly open a transaction that ignores the setting. `withTransaction` itself\n * takes the threshold as an argument on purpose; it knows nothing about the\n * container, and this is the seam where the two meet.\n *\n * The same argument now carries the connection's **name**: a pool cannot be\n * asked which one it is, and `withTransaction` has to know in order to tell a\n * nested transaction on the same connection (a savepoint) from one on another\n * (a refusal). Taking the whole connection rather than the manager is what\n * makes both come from the same object, so a named connection cannot end up\n * with the default's threshold.\n */\nfunction transact<T>(\n connection: DatabaseConnection,\n fn: (tx: TransactionSQL) => Promise<T>,\n): Promise<T> {\n return withTransaction(connection.sql, fn, {\n slowTransactionThreshold: connection.config.slowTransactionThreshold,\n connection: connection.name,\n });\n}\n\n/**\n * The classes `Model.on` has already built, keyed by the class it was called on\n * and then by connection name.\n *\n * `User.on(\"analytics\")` is a per-query call, so it can happen in a loop and in\n * a hot path; minting a class each time would allocate one per query and defeat\n * every identity comparison downstream — the policy-divergence guard's\n * `registered !== this` among them, which would then run `policiesFor` against\n * a class it had never seen before on every call.\n *\n * A `WeakMap` on the outside so a model class that goes out of scope takes its\n * bound variants with it, which matters for tests that define models inline.\n */\nconst boundToConnection = new WeakMap<object, Map<string, typeof Model>>();\n\nexport abstract class Model {\n /**\n * Protected, so `new UserModel()` is a type error.\n *\n * Not stylistic. The generated bases merge the row's columns into their\n * instance type via a same-named interface, which is what lets a method on a\n * subclass read `this.email` — and the cost of declaration merging is that\n * TypeScript does not check those properties are ever initialised. A directly\n * constructed instance would therefore type as carrying every column while\n * holding none.\n *\n * Closing the constructor removes that hazard rather than documenting it: the\n * only way to get an instance is `wrap`, which assigns a complete row. Every\n * other operation returns plain objects and never constructs one.\n */\n protected constructor() {}\n\n /** Assigned by the generated subclass from `app/models/generated/schema.ts`. */\n static $schema: ModelSchema;\n\n /**\n * Set to `true` by the generator on each base it emits, and by nothing else.\n *\n * `registerModels` has to tell a generated base from an application class\n * written over it, because when both are in one namespace the subclass is the\n * one that must own the name — electing the base *is* #316's leak. It used to\n * answer that by asking whether a class declared `$schema` itself, which is an\n * inference about how the generator happens to be written rather than a\n * statement by the generator, and a subclass that redeclared `static $schema`\n * read as a base because of it. This is the generator saying so.\n *\n * **`declare`, and it has to stay `declare`.** The property must not exist on\n * `Model` at runtime: `isGeneratedBase` reads `\"$generated\" in candidate` to\n * decide whether the artifacts in front of it carry the mark at all, and falls\n * back to the old inference for artifacts generated before this existed. A\n * `Model.$generated` of `undefined` would answer that question `true` for\n * every class, in every app, including the ones with no mark to read.\n * `registration.test.ts` pins it.\n *\n * **`?: true` and not `?: boolean`**, which is what makes a hand-written\n * `static $generated = false` the type error `isGeneratedBase` reads it as.\n * The cost is that the generator has to emit a non-widening initialiser —\n * `static readonly $generated = true`, since a mutable one widens to\n * `boolean` and every emitted class becomes a TS2417. That happened;\n * `tsconfig.generated.json` is the check that catches it now.\n */\n declare static $generated?: true;\n\n /**\n * The model's own policies, in the order they should apply.\n *\n * A list rather than the single `$policy` this replaced, because composition\n * is the normal case and the two ways of expressing it against one slot were\n * both bad. Spreading (`{ ...softDeletes(), ...mine }`) silently drops\n * whichever `scope` came first, and an intermediate base class per combination\n * means one throwaway class for every model a shared policy applies to — the\n * generated bases all differ, so a `TenantScoped` used on three models needed\n * three of them.\n *\n * Each level of the prototype chain contributes its own array and they\n * concatenate base first, so a shared model base can still impose a policy\n * that a subclass can only narrow. See `policiesFor`.\n *\n * Entries may be policy objects or classes; a class is instantiated once. The\n * generated `<Model>Policy` type gives an object literal here full contextual\n * typing, which a bare `$policies = [...]` does not get on its own.\n */\n static $policies?: readonly PolicyEntry[];\n\n /**\n * The connection this class's operations run on, set only by `on` below.\n *\n * `undefined` — which is what every model an application writes has — means\n * *the ambient connection*, not *the default one*. The two differ inside\n * `DB.connection(\"analytics\").transaction(...)`, where an unqualified query\n * has to join the open transaction rather than quietly reach for the hot\n * path's pool.\n */\n static $connection?: string;\n\n /**\n * The same model, reading and writing on a named connection.\n *\n * const rows = await Subscription.on(\"analytics\").findMany({ where })\n *\n * **Per query, not per model**, which is the shape the problem actually has:\n * the same `Subscription` is read on the hot path during sign-in and swept by\n * the nightly audit. A `static $connection = \"analytics\"` on the class would\n * force one of those two to be wrong, so the choice lives at the call site\n * and every query that does not make it stays on the default connection.\n *\n * What it returns is the model class with the connection bound to it, so the\n * whole typed surface — all fifteen operations, `transaction`, `save` — is\n * there unchanged and narrows exactly as it does on the class itself. The\n * connection reaches nested `include` reads and nested writes as well, which\n * an argument on `findMany` could not have done: those recurse through the\n * *target* model's `$exec` by way of the registry, so it is carried in the\n * ambient scope rather than in anyone's parameter list.\n *\n * **A transaction cannot span connections.** Naming one inside a transaction\n * open on another raises `CrossConnectionTransactionError` rather than\n * running the statement outside the transaction, where it would survive the\n * rollback. See that error for why refusing is the only honest answer.\n *\n * An unknown name raises `UnknownConnectionError` at the query, not here:\n * `on` is a pure lookup and does not resolve the container, so a model bound\n * in a module's top-level scope cannot force the database open at import\n * time.\n */\n static on<T extends typeof Model>(this: T, connection: string): T {\n let byName = boundToConnection.get(this);\n if (byName === undefined) boundToConnection.set(this, (byName = new Map()));\n\n const cached = byName.get(connection);\n if (cached !== undefined) return cached as T;\n\n // A subclass rather than a Proxy. Both would forward the operations, but a\n // subclass *is* a class: `policiesFor` walks the prototype chain with\n // `Object.hasOwn`, the generated statics are inherited by the language\n // rather than by a trap, and `$exec`'s `this` needs no special handling to\n // stay bound to it.\n const bound = class extends (this as unknown as typeof Model) {\n static $connection = connection;\n };\n\n // Otherwise the class expression takes its name from the binding above and\n // every error that names the model says \"bound\". `UnregisteredPolicyClassError`\n // reads `this.name` in particular, and it is exactly the kind of message\n // that has to name the class the caller wrote.\n Object.defineProperty(bound, \"name\", {\n value: (this as { name: string }).name,\n configurable: true,\n });\n\n byName.set(connection, bound);\n return bound as unknown as T;\n }\n\n /**\n * Runs `fn` with policies suspended, for code that has no user and knows it:\n * a cron tick, a queue worker, a seed script, a migration.\n *\n * Deliberately a wrapper rather than a flag or a fallback. Under\n * deny-by-default the alternative to writing this is an error, which is the\n * point — unscoped access is a sentence someone typed, never what happens\n * when a user fails to turn up.\n *\n * await Model.asSystem(() => User.findMany({}))\n */\n static asSystem<T>(fn: () => Promise<T>): Promise<T> {\n return runAsSystem(fn);\n }\n\n /**\n * Runs `fn` with policies scoped to `user`, for code that acts on somebody's\n * behalf without a request to read them from — a queue job, a scheduled\n * report, a test.\n *\n * The narrow counterpart to `asSystem`, and deliberately the easier of the\n * two to reach for. A worker handling \"send the invoice for organisation 7\"\n * acts *as* a user; giving it only `asSystem` would suspend policies outright\n * and leave it hand-scoping every query, which is the unscoped-by-accident\n * outcome deny-by-default exists to prevent.\n *\n * await Model.asUser(owner, () => Invoice.findMany({}))\n */\n static asUser<T>(user: unknown, fn: () => Promise<T>): Promise<T> {\n return runAsUser(user, fn);\n }\n\n /**\n * Persists the changes made to a *tracked* row: `update` with only the columns\n * whose value differs from what was fetched.\n *\n * const user = await User.findUnique({ where: { id } }, { track: true })\n * user.name = \"new name\"\n * await User.save(user) // update \"User\" set \"name\" = ?, … where \"id\" = ?\n *\n * Most of Eloquent's write ergonomics while returns stay plain objects — no\n * proxies, no conditional return types, no signature that changes with a flag.\n * That is invariant 5's whole claim, and this is the thing that tests it.\n *\n * Goes through `$exec(\"update\", …)` rather than around it, so policies,\n * `@updatedAt`, the ambient transaction and the plan cache all apply exactly as\n * they do to a hand-written update. The changed-column *set* is the plan's\n * shape and the values are parameters, so two saves touching the same columns\n * share one plan.\n *\n * Returns `null` when nothing changed, having issued no statement — a save of\n * an untouched row should not stamp `@updatedAt`.\n *\n * Raises when handed an object with no provenance. See `untracked` for why\n * that is a loud failure rather than a fallback to writing everything.\n *\n * **It writes back to the connection the row was read on**, which is the one\n * place a connection cannot be resolved from the ambient scope: a row read on\n * `analytics` is an ordinary object that outlives the scope that produced it,\n * and by the time it is saved — three functions later, from code that never\n * named a connection — the scope is gone. So the connection is part of the\n * row's provenance, exactly as the model and the primary key are, and for the\n * same reason. Left to the ambient default, `save` compiled a correct\n * `update` and sent it to the wrong database, where the same id usually names\n * a real and different row.\n *\n * Naming a *different* connection explicitly — `User.on(\"default\").save(row)`\n * for a row read on `analytics` — is a contradiction rather than an\n * instruction, and raises. Copying a row between connections is a write in\n * its own right: say it with `update`, where the `where` and the `data` are\n * both visible.\n */\n static async save<T extends object>(row: T): Promise<unknown> {\n const schema = this.$modelSchema();\n const record = provenanceOf(row);\n\n if (!record) throw untracked(row, schema.name);\n\n if (record.model !== schema.name) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row came from ${record.model}, not ${schema.name}. Save it ` +\n `through the model it was read from.`,\n );\n }\n\n if (\n this.$connection !== undefined &&\n this.$connection !== record.connection\n ) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row was read on the \"${record.connection}\" connection and this ` +\n `save names \"${this.$connection}\". A save writes the row back where ` +\n `it came from, so the two cannot both be honoured. Drop the ` +\n `\\`on(\"${this.$connection}\")\\`, or write it as an explicit ` +\n `${schema.name}.on(\"${this.$connection}\").update({ where, data }) if ` +\n `copying it across connections is what you meant.`,\n );\n }\n\n // A row selected without its primary key has `key = { id: undefined }`, and\n // `matchUniqueKey` drops undefined members — so the update fails with\n // \"update needs a unique field\", pointing at a `where` the caller never\n // wrote. Named here instead, where the actual mistake is knowable: this can\n // only mean the select omitted the key.\n const missingKey = schema.primaryKey.filter(\n (name) => record.key[name] === undefined,\n );\n if (missingKey.length > 0) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row was fetched without ${missingKey.join(\", \")}, so there is no ` +\n `way to identify which row to update. A tracked row needs its primary ` +\n `key: add ${missingKey.map((name) => `${name}: true`).join(\", \")} to ` +\n `the select, or drop the select to fetch every column.`,\n );\n }\n\n const changed = changedFields(row, schema);\n if (Object.keys(changed).length === 0) return null;\n\n // On the row's own connection, entered here rather than left to `$exec`:\n // `$exec` resolves the *ambient* name, and the whole point is that the row\n // outlived the scope that read it. Inside a transaction on another\n // connection this raises `CrossConnectionTransactionError` from `$exec`,\n // which is the correct answer — that update cannot join the transaction, so\n // it must not run at all.\n const updated = await runOnConnection(record.connection, () =>\n this.$exec(\"update\", {\n where: record.key,\n data: changed,\n }),\n );\n\n // Copy the *returned* row back over the caller's, not just the values sent.\n //\n // `@updatedAt` is stamped by the compiler and is therefore never in\n // `changed`, so without this the in-memory row keeps the timestamp it was\n // fetched with while the database holds a newer one — a caller reading\n // `user.updatedAt` after a successful save silently gets the old instant. The\n // same applies to anything else the database rewrote.\n //\n // Resnapshotting from the same source is what keeps the row and its snapshot\n // in agreement, so a second `save` is still a no-op.\n if (updated && typeof updated === \"object\" && !Array.isArray(updated)) {\n const fresh = updated as Record<string, unknown>;\n const target = row as Record<string, unknown>;\n const persisted: Record<string, unknown> = {};\n\n for (const name of Object.keys(fresh)) {\n if (!(name in schema.fields)) continue;\n target[name] = fresh[name];\n persisted[name] = fresh[name];\n }\n\n resnapshot(row, persisted);\n } else {\n resnapshot(row, changed);\n }\n\n return updated;\n }\n\n /**\n * Turns a **complete** row into an instance of this class, for code that wants\n * behaviour rather than data.\n *\n * const user = User.wrap(await User.findUniqueOrThrow({ where: { id } }))\n * user.displayName // a method on your subclass\n * await user.save()\n *\n * Explicit, never implicit, and that is the whole design. The moment queries\n * hydrate by default, the `select` conflict comes back: a method that reads\n * `this.email` on a row fetched as `select: { id: true }` is a runtime crash\n * the type system cannot see. Keeping `wrap` a call the author makes means\n * narrowing and behaviour never meet.\n *\n * **Completeness is required, and the requirement is not arbitrary.** The\n * generated signature takes the full scalar payload, so a `Pick` of it is a\n * compile error rather than a runtime surprise (there is a type test for\n * exactly that). It is the same constraint that makes `save()` work on the\n * result: a complete row is one this can snapshot in full, so an instance is\n * tracked without the caller asking. The type constraint and the save\n * capability are one constraint, not two.\n *\n * Note the instance is a *copy*: mutating it does not touch the row that was\n * passed in, and `save()` diffs against what `wrap` received.\n */\n static wrap(row: object): any {\n const schema = this.$modelSchema();\n const instance = new (this as unknown as new () => any)();\n\n Object.assign(instance, row);\n // Tracked on the instance, not the argument — `save()` on the instance has\n // to diff against the values it was constructed from.\n //\n // The connection is the argument's, when the argument has one. `wrap` runs\n // *after* the query's scope has closed, so the ambient name here is\n // whatever the caller happens to be in — usually the default — and a row\n // read on `analytics` would be wrapped into an instance whose `save()`\n // wrote to the hot path. Taken in order: an explicit `on`, then where the\n // row actually came from, then the ambient connection for a row that was\n // never tracked at all.\n track(\n instance,\n schema,\n this.$connection ??\n provenanceOf(row)?.connection ??\n currentConnectionName(),\n );\n\n return instance;\n }\n\n /**\n * Persists this instance's changes. The instance counterpart of the static, and\n * a one-line delegation to it so there is one implementation.\n */\n save(): Promise<unknown> {\n return (this.constructor as typeof Model).save(this);\n }\n\n static $modelSchema(): ModelSchema {\n const schema = this.$schema;\n if (!schema) throw new MissingModelSchemaError(this.name);\n return schema;\n }\n\n /**\n * Runs `fn` inside a transaction. Every ORM query in it — at any call depth,\n * through any number of services, including the nested reads an `include`\n * fans out into — joins it automatically.\n *\n * The callback takes **no argument**, and that is the whole feature. Handing\n * back a `tx` would put it in the signature of every function between here\n * and the query, which is precisely the threading Prisma's `$transaction`\n * forces and this exists to remove. If a raw query genuinely needs the\n * handle, `currentTransaction()` hands it over without putting it in anyone's\n * parameter list.\n *\n * Nesting is a savepoint: an inner failure rolls back to it and leaves the\n * outer transaction usable, so a caller that catches keeps going.\n *\n * await User.transaction(async () => {\n * const user = await User.create({ data: { email } })\n * await audit(user) // its queries are in the transaction too\n * })\n *\n * **KNOWN DIALECT ASYMMETRY — catching an error inside a transaction.**\n * The sentence above holds for a *nested* `Model.transaction`. It does not\n * hold for a bare statement: on Postgres any failed statement aborts the\n * whole transaction block, so catching it and carrying on loses everything.\n * SQLite does not care. Verified against Postgres 16 and SQLite:\n *\n * await Model.transaction(async () => {\n * try { await User.create({ data: { email } }) }\n * catch (e) { if (!(e instanceof UniqueConstraintError)) throw e }\n * await Audit.create({ ... }) // fine on SQLite; on Postgres this\n * }) // throws 'current transaction is\n * // aborted', and the whole transaction\n * // is lost\n *\n * That is a bug that passes in development on SQLite and takes out the\n * transaction in production on Postgres, with an error naming neither the\n * statement that failed nor the one that caused it.\n *\n * The fix is already here: wrap the fallible statement in a nested\n * `Model.transaction`, which makes it a savepoint, and rolling back to that\n * savepoint clears the aborted state. Works on both dialects.\n *\n * await Model.transaction(async () => {\n * try {\n * await Model.transaction(() => User.create({ data: { email } }))\n * } catch (e) { if (!(e instanceof UniqueConstraintError)) throw e }\n * await Audit.create({ ... }) // fine on both\n * })\n *\n * **One statement at a time.** Every query in scope runs on one reserved\n * connection, so `Promise.all` over several ORM calls inside the callback is\n * not safe here — the ordinary, encouraged thing everywhere else in a Bun\n * codebase. Await them in sequence. (`$exec` already runs its own nested\n * writes and relation reads sequentially for this reason.)\n *\n * **The connection is held for as long as the callback runs**, including\n * while it awaits things that are not queries. In development a transaction\n * still open after 2s warns — `database.slowTransactionThreshold` sets that\n * bound, or `false` switches it off. In production it just holds the\n * connection. Keep network and filesystem I/O outside.\n */\n // `async`, so that naming a connection this transaction cannot reach —\n // `Subscription.on(\"analytics\").transaction(...)` inside a transaction on the\n // hot path — *rejects* rather than throwing synchronously. The same reasoning\n // `DB.query` records: an API that does one sometimes and the other otherwise\n // is a footgun, and a `.catch()` would miss exactly this error.\n static async transaction<T>(fn: () => Promise<T>): Promise<T> {\n // `Subscription.on(\"analytics\").transaction(...)` opens on that connection,\n // and a bare `Model.transaction` opens on whatever is ambient — which is\n // the default connection unless something outside has already named one.\n // `withTransaction` refuses the mismatch; there is no second check here.\n const name = this.$connection ?? currentConnectionName();\n\n return transact(app(DatabaseManager).connection(name), () =>\n runOnConnection(name, () => fn()),\n );\n }\n\n /**\n * The choke point's outer half: which connection this operation runs on.\n *\n * Split from the body below so that the name is resolved and entered\n * **once**, around everything — the policy pass, the plan lookup, the nested\n * writes and every relation read that recurses back through here. The\n * alternative, resolving it inside, would have left each nested read to\n * rediscover it, and the one that did not would have run against the default\n * connection with no error to show for it.\n *\n * Recursive calls cost a comparison: the ambient name already matches, so\n * `runOnConnection` calls straight through without entering a second scope.\n *\n * `async` for the reason `transaction` is: an operation refused for naming a\n * connection the open transaction cannot reach has to reject like every other\n * failure `$exec` produces, rather than being the one that throws before the\n * promise exists.\n *\n * The cross-connection refusal is `runOnConnection`'s, not repeated here:\n * *entering* the connection is the only moment at which the scope still holds\n * both the open transaction and the name it belongs to, so that is where the\n * comparison has to live.\n */\n static async $exec(\n op: Operation,\n args: any = {},\n options?: ExecOptions,\n ): Promise<unknown> {\n return runOnConnection(this.$connection ?? currentConnectionName(), () =>\n this.$execute(op, args, options),\n );\n }\n\n private static async $execute(\n op: Operation,\n args: any = {},\n options?: ExecOptions,\n ): Promise<unknown> {\n const schema = this.$modelSchema();\n\n // Resolved per call, never captured at module scope: that is what keeps the\n // connection swappable in tests.\n //\n // Through `connection()` rather than off the manager directly, so that a\n // query on a named connection reads *that* pool's client and dialect. The\n // default connection is the manager itself, which is what keeps every\n // existing wrapper of it — the harnesses that Proxy `sql` to count\n // statements — looking at the object this executes through.\n const db = app(DatabaseManager).connection(currentConnectionName());\n const dialect = dialectFor(db.dialect);\n\n // The ambient-transaction hook, and the entire integration. It is one line\n // — and it covers every operation, every nested write and every relation\n // read — only because invariant 1 held: `$exec` is the single door. An\n // operation that acquired a private path to the database would show up\n // here as a statement silently running outside the transaction, committed\n // while its neighbours roll back.\n // `let`, because a multi-statement write opens a transaction of its own\n // further down and every statement after that point — including the\n // `executor.query` closure below, which captures this binding rather than\n // its value — has to run on the new handle rather than back on the pool.\n let conn = currentTransaction() ?? db.sql;\n\n // POLICIES, AND THE ORDER MATTERS MORE HERE THAN ANYWHERE ELSE IN THE ORM.\n //\n // Policies rewrite the argument tree, so they change the SQL. They must\n // therefore run *before* `getOrCompile`, which keys the plan cache on those\n // arguments. Reordered — compile first, scope after — two users with the\n // same query shape and different scopes would share one plan, and one of\n // them would run the other's SQL. That is a cross-tenant data leak produced\n // by a caching bug, and it would not look like one.\n //\n // A scope that injects a *value* keeps the same shape for every user, so\n // the plan is still shared and only the bound value differs. That is the\n // desired outcome, not a compromise, and `policy.plan-cache.test.ts` pins\n // both halves: same shape means one plan and different parameters, and a\n // scope whose shape varies by user means a different plan key.\n // `asSystem` suspends the whole hook, not just the no-user check: a script\n // that has said it is a script should not then be scoped to a user that\n // happens to be in the request store.\n const system = isSystemScope();\n const policies = system ? [] : policiesFor(this);\n let policy: PolicyContext | undefined;\n let effective = args;\n\n // POLICY-DIVERGENCE GUARD.\n //\n // A nested relation read resolves its target through the registry, so it\n // runs whatever is registered under this model's name — not necessarily the\n // class the caller queried. When those two disagree about *policies*, the\n // same policy applies to some queries and not others, silently. Both\n // directions are reachable and both are the same bug:\n //\n // policied class not registered -> root scoped, nested reads unscoped\n // policied class registered, but -> nested reads scoped, a direct query\n // the caller queries the base through the base unscoped\n //\n // The second is the one this check sat inside `policies.length > 0` and\n // therefore missed: querying `AccountModel` when `Account` owns the name\n // finds no policies on `AccountModel`, so the old placement never looked.\n // `AccountModel` and `Account` come out of the same barrel with near\n // identical names, so it needs no include and no mistake worth calling one.\n //\n // Keyed on the *divergence*, not on either class having policies. The\n // comparison is of the resolved policy chain rather than class identity: a\n // plain subclass of a registered, policied class inherits the same policy\n // objects in the same order, so nothing diverges and there is nothing to\n // refuse — checking identity rejected `class AdminUser extends User {}`, a\n // typed view, for policies it had not written.\n //\n // `!system` is load-bearing. Under `asSystem` policies are suspended by\n // design, so a seed script querying the generated base directly is correct\n // and must not raise.\n //\n // Cost on the common path: one `Map.get` and one reference compare, for a\n // model where nothing is registered under a different class.\n //\n // `inheritsPoliciesFrom` keeps that true for `Model.on(name)`, whose bound\n // subclass is never the registered class and so failed the reference\n // compare on *every* query — leaving each one to resolve the registered\n // chain and walk it twice to reach the same conclusion. A direct subclass\n // that declares no policies of its own has, by construction, the chain its\n // parent has: there is nothing to compare.\n if (!system) {\n const registered = registry.has(schema.name)\n ? registry.get<unknown>(schema.name)\n : undefined;\n\n if (\n registered !== undefined &&\n registered !== this &&\n !inheritsPoliciesFrom(this, registered)\n ) {\n const theirs = policiesFor(registered);\n const diverges =\n policies.length !== theirs.length ||\n policies.some((entry, index) => entry !== theirs[index]);\n\n if (diverges) {\n throw new UnregisteredPolicyClassError(\n schema.name,\n (registered as { name?: string }).name ?? String(registered),\n this.name,\n policies.length > 0 ? \"queried\" : \"registered\",\n );\n }\n }\n }\n\n // NESTED policies, applied to the argument tree before the plan key.\n //\n // A nested read under the batched strategy would acquire its own policies by\n // recursing through the child's `$exec` — but a lateral join has no such call,\n // so the child's policies would never be consulted and the subquery would be\n // unscoped. Applying them here, on the args, keeps the compiler pure and makes\n // the scope part of whatever SQL a strategy chooses to emit. See\n // `applyNestedPolicies` and `plans/orm/09-lateral-strategy.md`.\n //\n // `preScoped` is how the double application is avoided: the relation executor\n // marks its recursive calls, so a child whose args arrived already scoped does\n // not scope them again. Without it a batched include would `AND` the same\n // predicate twice — the same rows, but different SQL and a different plan key.\n const preScoped = isPreScoped(options);\n\n if (!system && !preScoped) {\n effective = applyNestedPolicies(\n schema,\n effective,\n currentUser(),\n system,\n (model) => {\n if (!registry.has(model)) return undefined;\n const target = registry.get<typeof Model>(model);\n const targetSchema = target.$schema;\n if (!targetSchema) return undefined;\n return { policies: policiesFor(target), schema: targetSchema };\n },\n );\n }\n\n // `upsert` whose `create` does not set the conflict key, which used to\n // raise — and which is decided **before** policies are applied, on purpose.\n //\n // The last of iteration 4's three \"not before iteration 5\" items. That note:\n // \"Prisma means find-then-write there; expressing that takes a read and a\n // write inside one transaction, which is iteration 5's.\"\n //\n // Checked against a generated Prisma 6 client rather than reasoned about,\n // because the semantics are surprising: `upsert({ where: { publicId: \"X\" },\n // create: { email } })` inserts a row whose `publicId` is **generated**, not\n // \"X\". The `where` selects; it does not contribute to the insert.\n //\n // **`on conflict` is kept wherever it works.** It is one atomic statement,\n // and read-then-write is not — two callers can both miss and both insert.\n // Prisma's upsert has that race and this inherits it, but only on calls that\n // previously raised: nothing that worked becomes racy.\n //\n // **Before policies, and that is what lets a scoped model upsert at all.**\n // `assertScopable` refuses to put a scope on an `upsert`, because its where\n // becomes an `on conflict` target and a target cannot carry a predicate.\n // That reason is exactly true of the `on conflict` path and false of this\n // one, which is three ordinary statements. Deciding here means the three run\n // as `findFirst`, `create` and `update`, each scoped normally by its own\n // `$exec` — so this branch is *not* marked pre-scoped, and a policied model\n // gets a working upsert instead of a refusal whose justification expired.\n //\n // A policy that branches on `context.operation` therefore sees the three it\n // actually runs rather than the one the caller named. That is the honest\n // reading: the operation really is three statements here.\n if (op === \"upsert\" && !preScoped && findThenWrite(schema, args, op)) {\n const { where, create, update, ...projection } = args;\n\n return transact(db, async () => {\n const found = await this.$exec(\"findFirst\", { where }, options);\n\n return found === null\n ? await this.$exec(\"create\", { data: create, ...projection }, options)\n : await this.$exec(\n \"update\",\n { where, data: update, ...projection },\n options,\n );\n });\n }\n\n if (policies.length > 0) {\n // Deny-by-default lives on the context's `user` accessor, not here: a\n // policy that never consults the user — a soft-delete scope, say — has\n // nothing to deny and must keep working with no request in sight. See\n // `policyContext`.\n //\n // `redactedAs` is the one thing that can make `context.operation` differ\n // from `op`, and it exists to *remove* a difference the caller can see: a\n // `delete` that has to read before it writes runs its pre-read as a\n // `findFirst` and hands that row back, so without this a `redact` keyed on\n // `\"delete\"` stopped firing the moment the call also carried an `include`\n // (#366). The row is the delete's return value; it is redacted as one.\n //\n // **Only on a pre-scoped call, which is what keeps it a redaction\n // concern.** `applyPolicies` below is skipped when `preScoped`, so on the\n // one call that sets this marker the context reaches nothing but\n // `applyRedaction`. Reading the marker unconditionally would leave a\n // shape — a future non-pre-scoped caller — where a `before` or a `scope`\n // could be handed an operation the statement is not, and `SCOPABLE` is\n // keyed on exactly that. The guard does not make that shape\n // unconstructible — `markRedactedAs(options, \"delete\")` on its own is\n // still a value anyone can build — it makes it *unread*, so the\n // consequence is absent rather than the shape. That is the whole of what\n // is claimed, and it is enough: the marker changes nothing on any call\n // that policies still rewrite.\n policy = policyContext(\n schema.name,\n (preScoped ? redactedAs(options) : undefined) ?? op,\n currentUser(),\n system,\n );\n\n // **The context is built even when pre-scoped; only the rewrite is\n // skipped.** `preScoped` means \"the scope is already in these args\" — not\n // \"this model has no policies\". Guarding the whole block on it left\n // `policy` undefined for every nested relation read, and `policy` is what\n // `applyRedaction` below is keyed on. So a `redact` protected a root query\n // and was skipped inside every `include`: scoped one way, unscoped the\n // other, which is the failure iteration 6 exists to prevent.\n //\n // Only `applyPolicies` is idempotency-sensitive. Re-running it would `AND`\n // the same predicate twice; re-running `redact` on an already-redacted row\n // is a no-op.\n if (!preScoped) {\n effective = applyPolicies(\n policies,\n policy,\n args,\n ormAuthoredFields(options),\n );\n }\n }\n\n // Which strategy plans the include tree. Named per call or chosen by\n // `defaultStrategy`, and either way it reaches the plan key — two strategies\n // emit different SQL for the same arguments, so sharing a plan between them\n // would run one request's statement for the other's.\n const strategy = resolveStrategy(options?.strategy, dialect, {\n model: schema.name,\n operation: op,\n });\n\n // `createMany` past the driver's parameter ceiling, which used to raise.\n //\n // Iteration 4 refused to chunk and said why: \"it would make this several\n // statements, which cannot be made atomic until transactions land.\" They\n // landed in iteration 5. So the split happens here, inside one transaction,\n // and the caller gets the same `{ count }` a single statement would have\n // returned.\n //\n // **Only on the call that would otherwise have failed.** The ceiling is\n // checked in `render`, so the ordinary path pays nothing for this — it is a\n // `catch`, not a size check on every write. A `createMany` small enough to\n // compile never enters it.\n if (op === \"createMany\" && Array.isArray(effective?.data)) {\n const chunks = chunkedCreateMany(\n schema,\n effective,\n dialect,\n strategy,\n op,\n );\n\n if (chunks !== null) {\n return transact(db, async () => {\n let count = 0;\n for (const data of chunks) {\n const written = (await this.$exec(\n \"createMany\",\n { ...effective, data },\n markPreScoped({ strategy: options?.strategy }) as never,\n )) as { count: number };\n count += written.count;\n }\n return { count };\n });\n }\n }\n\n const plan = getOrCompile(schema, op, effective, dialect, strategy);\n\n const executor: RelationExecutor = {\n // `markPreScoped`: this model's policies were already applied to\n // `relationArgs` by the parent's nested walk, so re-applying them here\n // would `AND` the same predicate twice — same rows, different SQL,\n // different plan key. The marker is a module-private Symbol and is not\n // exported, so it cannot become a way for an application to skip policies.\n // The strategy propagates too. Without it a nested `$exec` fell back to\n // `defaultStrategy`, so a query explicitly asking for `batched` got the\n // *default* for every level below the root — on Postgres that meant the\n // grandchild folded anyway and the statement count was one lower than the\n // caller asked for. Found by the query-count test, which is the only thing\n // that could have found it: the results were identical either way.\n exec: (model, operation, relationArgs, preScoped, ormAuthored) => {\n const base = preScoped\n ? markPreScoped({ strategy: options?.strategy })\n : { strategy: options?.strategy };\n return registry\n .get<typeof Model>(model)\n .$exec(\n operation as Operation,\n relationArgs,\n (ormAuthored && ormAuthored.length > 0\n ? markOrmAuthored(base, ormAuthored)\n : base) as never,\n );\n },\n // The one query with no model behind it — the implicit m-n join table —\n // resolves its connection here rather than reaching for the pool, so it\n // joins the transaction like everything else.\n query: (text, values) => conn.unsafe(text, values),\n };\n\n // One context per call, holding the instant every `now()` and `@updatedAt`\n // on this operation shares, plus whatever the `before` steps resolve.\n const context = createBindContext();\n\n // `delete` with an `include` on a **cascading** relation, which returned the\n // children empty until now.\n //\n // The relation reads run after the delete statement, so where the schema\n // declares `onDelete: Cascade` the database has already removed the children\n // by the time they are read. Prisma runs the whole thing in a transaction and\n // returns them as they were. `compileDelete` recorded this as \"not fixable at\n // this layer — the fix is to read the relations before the delete inside one\n // transaction, which is iteration 5's to provide\".\n //\n // Iteration 5 provided it. Read first, delete second, return what was read:\n //\n // - **A transaction, so the pair is atomic.** Without one, a delete that\n // fails after the read would leave the caller holding a row that still\n // exists. Nested inside a caller's transaction it is a savepoint, which is\n // what `withTransaction` already does.\n // - **`markPreScoped` on both**, because `effective` has been through this\n // model's policies once already; re-applying them would `AND` the same\n // predicate twice — same rows, different plan key.\n // - **The read is scoped as the delete was**, including its nested policies.\n // `effective` was rewritten by `applyPolicies` and `applyNestedPolicies`\n // under operation `\"delete\"`, and `markPreScoped` stops the pre-read\n // redoing either — so the `where` the `findFirst` runs is the delete's,\n // predicate for predicate.\n // - **`markRedactedAs`, so the row is redacted as the delete it belongs\n // to.** This bullet used to claim `context.operation` was already\n // `\"delete\"` here. It was not, and the row it was most wrong about was the\n // root one — the one returned. The pre-read is a `findFirst`, so\n // `policyContext` was built with `\"findFirst\"` and a `redact` keyed on\n // `\"delete\"` silently stopped firing as soon as the same call carried an\n // `include` (#366). The `delete` statement below *does* run under\n // `\"delete\"`, and its row is thrown away, so nothing observable came of\n // that half.\n //\n // The marker covers the returned row and nothing else. Nested reads are\n // *scoped* as `findMany` on both strategies — `NESTED_READ` in `policy.ts`\n // is a constant on purpose, because a read of another model is a read\n // whatever statement encloses it — and the marker does not reach them: the\n // relation executor rebuilds its options from `{ strategy }` rather than\n // forwarding these.\n //\n // Which name a nested row is *redacted* as is a second mechanism, and it\n // agrees with the first since #388. Both strategies answer `NESTED_READ`:\n // a **batched** child runs its own `$exec` under it, and a **folded**\n // (lateral, the Postgres default) child is handed the same constant by\n // `redactFolded` below, which redacts it on the parent's behalf because\n // its rows never enter its own `$exec`.\n //\n // Until #388 the folded path built its context from the enclosing\n // `$exec`'s `op` — on this call the pre-read, a `findFirst` — so the same\n // query over the same rows reported `findMany` on SQLite and `findFirst`\n // on Postgres. Neither value was ever the write, which is the part #366 is\n // about and the only part `delete-redact-operation.test.ts` pins under the\n // default strategy; `nested-redact-strategy.test.ts` pins the agreement.\n //\n // Only when there is something to read. A plain `delete` still compiles to\n // one statement and opens no transaction.\n //\n // `plan.counts` is here for the same hazard in its quietest form, and the\n // two dialects disagree about it. A `_count` compiles to a correlated\n // subquery inside the `RETURNING`, and where the schema cascades:\n //\n // postgres delete … returning (select count(*) from ch …) -> 3\n // sqlite delete … returning (select count(*) from ch …) -> 0\n //\n // Measured through Bun against a real `on delete cascade` on both. Postgres\n // evaluates the subquery against the pre-statement snapshot, which is what\n // Prisma returns; SQLite evaluates it after the cascade has run, so the\n // count is 0 — a *number*, so nothing looks missing and no error is raised.\n //\n // Reading first answers it the same way it already answers the `include`\n // case, and on both dialects rather than one. A count is not a relation\n // plan, so `relations` stays empty for an `include: { _count: … }` on its\n // own — hence the separate flag rather than a wider check.\n if (op === \"delete\" && (plan.relations !== undefined || plan.counts)) {\n // **Everything but the `where`, rather than the operands named one by\n // one.** The row this reads is the row the caller gets back — `return\n // before`, below — so an operand left out here is silently un-narrowed,\n // and nothing downstream will notice. That is #364: this rebuilt the\n // projection as `select` *or* `include`, `omit` was not among the names,\n // and a `delete` that asked to drop a column got it back as soon as the\n // same call also carried an `include`. A `delete` with no relation to read\n // never reaches this branch and projects through `resolveSelection`, which\n // had honoured `omit` all along — one operation, two paths, two answers.\n //\n // **Do not turn this back into named arms.** The rest is what makes the\n // next projection operand — Prisma's `relationLoadStrategy`, a `distinct`\n // on a write, whatever it turns out to be — arrive here for free instead\n // of arriving as the same bug with a different column name. The `upsert`\n // find-then-write branch a few hundred lines up spreads for the same\n // reason and was never affected by #364.\n //\n // Bounded, not hopeful. `assertArgs` (`compile/write.ts`) rejects any\n // operand outside `WRITE_ARGS.delete` — `where`, `select`, `include`,\n // `omit` — and the plan above is already compiled, so the rest holds\n // projection operands and nothing else. That set is a strict subset of\n // `findFirst`'s, so every one of them is a legal read operand. `omit` and\n // `select` cannot both be in it: `resolveSelection` refuses that pair, and\n // a warm plan cannot smuggle it past, since both are in `LITERAL_KEYS`\n // (`plan.ts`) and so key separately. An `undefined` operand is dropped from\n // the plan key too, so carrying one costs no second cache entry.\n const { where, ...projection } = effective;\n\n // The pool, not `conn`: when a transaction is already open `withTransaction`\n // savepoints against the ambient handle and ignores this argument, and\n // passing a transaction handle here would read as though we begin on it.\n return transact(db, async () => {\n const before = await this.$exec(\n \"findFirst\",\n { where, ...projection },\n // `op` rather than the literal `\"delete\"`: the branch is guarded on\n // it, so they are the same string, and taking it from the variable\n // keeps the two from drifting if the guard ever admits a second\n // operation that has to read before it writes.\n markRedactedAs(\n markPreScoped({ strategy: options?.strategy }),\n op,\n ) as never,\n );\n\n // `findFirst` shapes a miss to `null`; the caller asked for a delete, so\n // the error has to name that rather than the read this used underneath.\n if (before === null) throw new RecordNotFoundError(schema.name, op);\n\n await this.$exec(\n \"delete\",\n { where },\n markPreScoped({ strategy: options?.strategy }) as never,\n );\n\n return before;\n });\n }\n\n // A write with a nested `create` / `connect` runs more than one statement,\n // and those statements are one unit: the parent row and the children it was\n // asked for either all land or none do.\n //\n // This used to be left to the caller — \"atomic exactly when the caller\n // wrapped the call in `Model.transaction`, *not* implicitly\" — on the\n // reasoning that `$exec` cannot know whether it is one step of a larger unit\n // and that opening one per call would put a `BEGIN` around every query in\n // the framework. The second half of that is right and is why the condition\n // below is what it is; the first half does not survive contact with\n // policies. A nested write step runs the *child's* `$exec`, so the child's\n // policies are consulted mid-sequence, after the parent row is already\n // written. A child that denies therefore left a half-written parent behind,\n // and \"your policy stopped the write\" and \"your policy stopped half the\n // write\" are not the same promise.\n //\n // So: implicit, but only for the calls that are actually multi-statement.\n // A plain `create` still compiles to one statement and opens nothing, which\n // is what keeps the `BEGIN`-around-everything objection answered — and\n // inside a caller's own transaction `withTransaction` takes a savepoint\n // rather than nesting a second one.\n const finish = async (): Promise<unknown> => {\n // Re-resolved rather than reused: if the branch below opened a\n // transaction, every statement from here on belongs to it. Outside one\n // this is the same handle it already was.\n conn = currentTransaction() ?? conn;\n\n await runSteps(plan.before, effective, context, executor, []);\n\n // `unsafe` despite the name. Bun's tagged template cannot express a query\n // whose *shape* is dynamic, which every ORM query is. Safety here does not\n // come from the template syntax: it comes from the compiler's two rules —\n // identifiers only ever come from the generated schema, and every value is\n // a bound parameter. Do not \"fix\" this into a tagged template.\n const rows = await execute(\n conn,\n dialect,\n schema,\n op,\n plan.text,\n plan.bind(effective, context),\n );\n\n const result = this.$shape(plan, rows as unknown[]);\n\n // The plan shapes a single-row operation to `null` when nothing matched;\n // turning that into an error belongs here rather than in the plan, because\n // this is where the model's name is in scope for the message.\n if (result === null && ORTHROW.has(op)) {\n throw new RecordNotFoundError(schema.name, op);\n }\n\n // Rows that could not exist until this one did: the far side of a relation\n // whose foreign key lives on the child. Run before relations are attached,\n // so an `include` on the same call sees what was just written.\n await runSteps(plan.after, effective, context, executor, rowsOf(result));\n\n // ...and a `_count` on the same call has to be recomputed once they have,\n // for the same reason `include` is attached after them rather than before.\n //\n // A count is a correlated subquery inside the write's own `RETURNING`, so\n // it is evaluated at the instant the parent row is inserted — before any\n // `after` step has written a child. That produced a single response\n // contradicting itself:\n //\n // User.create({ data: { …, accounts: { create: [a, b] } },\n // include: { accounts: true, _count: { … } } })\n //\n // accounts.length 2 attached after the steps\n // _count 0 projected before them\n //\n // Both keys describe the same relation on the same row. The row itself was\n // never wrong — reading it back gives 2 — so this is the projection being\n // frozen, which is the mirror of the `delete` case above: there the count\n // is taken too late, here too early.\n //\n // **Only when there is something to be wrong about.** A write with no\n // `after` steps keeps the projected value and costs nothing extra; one\n // with both pays a single read. `plan.counts` is what makes that condition\n // cheap enough to ask on every write.\n //\n // **Between `runSteps` and the `hidden` deletion, and that is\n // load-bearing.** `select: { email, _count: … }` never asks for the\n // primary key, so the key the recount reads the row by is on it only\n // because the plan added it for the nested write and has not stripped it\n // yet. Move this after the strip and the recount loses its identifier;\n // move it before `runSteps` and there is nothing new to count.\n if (plan.counts && plan.after !== undefined) {\n await recountAfterSteps(\n schema,\n this as unknown as typeof Model,\n effective,\n rowsOf(result),\n options,\n );\n }\n\n // Relations are loaded after the root rows are shaped, one query per node\n // in the include tree. Each of those queries is `$exec` on the *related\n // model's own class*, recursively — not a private helper — so a nested read\n // is subject to everything a top-level read is.\n //\n // The planner is handed the database rather than reaching for it: that is\n // what keeps `compile/` free of a runtime import, and it is why the one\n // query with no model behind it — the implicit m-n join table — still runs\n // on the connection this call resolved.\n if (plan.relations !== undefined) {\n await attachRelations(\n plan.relations,\n plan.hidden,\n result,\n effective,\n executor,\n );\n } else if (plan.hidden !== undefined && plan.hidden.length > 0) {\n // A write can hide a key column without having any relation to attach:\n // a nested `after` step needs the parent's key returned, but the caller's\n // `select` never asked for it.\n for (const row of rowsOf(result)) {\n for (const key of plan.hidden) delete row[key];\n }\n }\n\n // A **folded** relation's rows never entered the child's `$exec`, so nothing\n // has run the child's `redact` over them. The comment below — \"a related row\n // was shaped by its own model's `$exec`\" — is true of the batched strategy\n // and false of the lateral one, which is precisely the kind of assumption\n // iteration 9 had to revisit for `scope`.\n //\n // `scope` survived the fold because policies rewrite the *argument tree*\n // before planning, and a scoped `where` lands inside the subquery. `redact`\n // cannot: it is a row transform in the shaping stage, with no argument to\n // rewrite. So the parent runs it on the child's behalf, which is the only\n // place that can.\n //\n // **`NESTED_READ`, not `op` — #388.** Running it here is a fact about where\n // the rows were shaped, not about what they are. The child is a read of\n // another model whatever statement encloses it, which is the whole reason\n // `applyNestedPolicies` scopes every nested node under the same constant,\n // and its docblock argues that at length. Handing the enclosing `op` down\n // made the *same* relation read, over the same rows, tell the child's\n // `redact` a different `context.operation` depending on which strategy\n // planned it: `findMany` batched, `findFirst` folded. A policy written as\n // `context.operation === \"findMany\"` therefore protected a child on SQLite\n // and leaked it on Postgres, for identical application code.\n if (plan.relations !== undefined && !system) {\n for (const relation of plan.relations) {\n if (relation.root === undefined) continue;\n redactFolded(\n {\n as: relation.as,\n model: relation.model,\n folded: relation.root.folded,\n },\n result,\n NESTED_READ,\n system,\n );\n }\n }\n\n // Redaction last, on the shaped result. After relations, not before: a\n // related row was shaped by its own model's `$exec` and has already been\n // through its own policy's `redact` — this one only owns its own rows.\n if (policy) applyRedaction(policies, policy, result);\n\n // Provenance, after redaction so a redacted field is not snapshotted as its\n // original value and then written back by `save`.\n //\n // Here rather than inside `$shape`, which is where the plan sketched it, for\n // one reason: `$shape` is the seam an `ActiveRecordModel` overrides to\n // return instances, and tracking there would make every such override\n // responsible for reimplementing it. Doing it at the choke point means an\n // override gets provenance for free — which is the same argument that put\n // everything else in `$exec`.\n if (options?.track === true) {\n for (const row of rowsOf(result)) track(row, schema);\n }\n\n return result;\n };\n\n const atomic =\n (plan.before !== undefined && plan.before.length > 0) ||\n (plan.after !== undefined && plan.after.length > 0);\n\n return atomic ? transact(db, finish) : finish();\n }\n\n /**\n * A static, not a module-level function, so subclassing is the extension\n * mechanism: a future `ActiveRecordModel` overrides this to build instances,\n * and every model extending it gets that with no change to the operations. It\n * is also where iteration 8 populates row provenance.\n */\n static $shape(plan: QueryPlan, rows: unknown[]): unknown {\n return plan.shape(rows);\n }\n}\n\n/**\n * Whether `queried` can only have the policies `registered` has.\n *\n * True for a direct subclass that declares none of its own — which is what\n * `Model.on(name)` builds, and also what `class AdminUser extends User {}` is.\n * `policiesFor` walks the prototype chain and takes each level's own\n * `$policies`; a level that declares none contributes nothing, so the walk from\n * here and the walk from the parent visit the same levels in the same order and\n * cannot disagree.\n *\n * Structural rather than a flag on the classes `on` mints, so the typed-view\n * subclass the divergence guard already argues should be allowed gets the same\n * short-circuit rather than paying for a second resolution of the chain.\n *\n * `$policy` — the removed name — is deliberately not checked: `policiesFor` has\n * already walked this class by the time this is called, and it raises on that\n * name at any level, so a class carrying it never reaches here.\n */\nfunction inheritsPoliciesFrom(queried: unknown, registered: unknown): boolean {\n return (\n Object.getPrototypeOf(queried) === registered &&\n !Object.hasOwn(queried as object, \"$policies\")\n );\n}\n\nasync function runSteps(\n steps: NestedWriteStep[] | undefined,\n args: any,\n context: BindContext,\n executor: RelationExecutor,\n rows: readonly Record<string, unknown>[],\n): Promise<void> {\n if (steps === undefined) return;\n // Sequentially, for the same reason relations load sequentially: inside an\n // ambient transaction every statement runs on one reserved connection, where\n // concurrent statements are not safe.\n for (const step of steps) {\n await step.run(args, context, executor, rows);\n }\n}\n\n/**\n * The skew warning, gated on this process's **zone** — resolved once, here.\n *\n * Reading the clock per call cost a `Date` allocation on the one path every\n * query takes — ~60ns, against under a nanosecond for the closed-over boolean\n * that replaces it — and the latch inside only ever closes on a *firing*, so\n * the deployment that is configured correctly and never warns paid it forever.\n *\n * `clockCouldSkew()` asks the question whose answer cannot change under a\n * running process: not \"is the offset zero today\", which is also true of\n * `Europe/London` every winter, but \"is this zone ever off UTC at all\". A UTC\n * process never enters the check; anything else stops entering once it has said\n * its piece, and reads the clock only until then — see `protocol-skew.ts`,\n * which owns both halves so that both can be tested from a UTC machine.\n */\nconst warnProtocolSkewOnce = createProtocolSkewWarner(clockCouldSkew(), () =>\n new Date().getTimezoneOffset(),\n);\n\n/**\n * Runs the statement and translates the failures that have a typed home.\n *\n * A unique violation is the one every application branches on, and every driver\n * reports it differently — SQLite as a message with a code, Postgres as a\n * SQLSTATE with a constraint name. Asking the dialect keeps that difference\n * behind the same seam as everything else, and turning it into an error that\n * names *fields* rather than columns is what makes it useful to a caller that\n * has never seen the database's names.\n */\nasync function execute(\n conn: Pick<SQL, \"unsafe\">,\n dialect: SqlDialect,\n schema: ModelSchema,\n op: Operation,\n text: string,\n values: unknown[],\n): Promise<unknown> {\n // Said once per process, and only for the configuration that silently returns\n // the wrong instant — see `protocol-skew.ts`. Printing is left here because\n // this is the layer allowed to talk to the operator; deciding is not, because\n // nothing that needs a database can be tested in the one configuration CI\n // runs.\n const warning = warnProtocolSkewOnce(dialect.name, schema, text, values);\n if (warning) console.warn(warning);\n\n try {\n return await conn.unsafe(text, values);\n } catch (error) {\n const violation = dialect.constraintViolation(error);\n if (!violation) throw error;\n\n throw new UniqueConstraintError(\n schema.name,\n op,\n fieldsForColumns(schema, violation.columns),\n violation.constraint,\n { cause: error },\n );\n }\n}\n\n/**\n * Driver column names back to Prisma field names, so the error reads in the\n * caller's vocabulary. A column with no matching field is reported as-is rather\n * than dropped: it is still the truest thing we know about the failure.\n */\nfunction fieldsForColumns(\n schema: ModelSchema,\n columns: readonly string[],\n): string[] {\n return columns.map((column) => {\n for (const field of Object.values(schema.fields)) {\n if (field.column === column) return field.name;\n }\n return column;\n });\n}\n\n/**\n * Re-reads the `_count` for rows whose children were written by an `after` step.\n *\n * One read per row rather than one for all of them, and that is not a\n * concession: every write that can carry both a `_count` and an `after` step is\n * a single-row operation — `create`, `update`, `upsert`. `createMany` takes no\n * `include` at all. So the loop runs once, and writing it as a loop keeps a\n * compound primary key expressible without an `in` list over tuples.\n *\n * **Pre-scoped, deliberately.** `effective` has already been through this\n * model's policies and `applyNestedPolicies` has already scoped the `_count`\n * node, so re-applying them would `AND` the same predicate twice — the same\n * rows, a different plan key. This is the same reasoning `delete`'s read-first\n * path uses, a few hundred lines up.\n */\nasync function recountAfterSteps(\n schema: ModelSchema,\n model: typeof Model,\n effective: any,\n rows: Record<string, unknown>[],\n options: unknown,\n): Promise<void> {\n const node = effective?.include?._count ?? effective?.select?._count;\n if (node === undefined || rows.length === 0) return;\n\n for (const row of rows) {\n // **Every component present, or nothing.** What the plan guarantees is on\n // the row is the *link* field — `planForeignSide` pushes `link.parentField`\n // into `keyFields`, which is the column the relation `references`, and that\n // is the primary key only by convention. Declare a relation\n // `references: [publicId]`, ask for `select: { email, _count }`, and `id` is\n // simply not there.\n //\n // The failure that would produce is the bad kind. `compileWhere` drops\n // `undefined` keys, so a `where` built entirely from missing components\n // compiles to **no predicate at all**:\n //\n // findFirst({ where: { id: undefined } }) -> select … from \"User\" limit ?\n //\n // — an arbitrary row, whose count is a plausible number rather than an\n // error. So an incomplete key means the projected value stands, which is\n // the same answer this already gives for a missing row: stale, not\n // invented. Nothing here can be salvaged by guessing.\n const where: Record<string, unknown> = {};\n let identified = schema.primaryKey.length > 0;\n for (const field of schema.primaryKey) {\n const value = row[field];\n if (value === undefined) {\n identified = false;\n break;\n }\n where[field] = value;\n }\n if (!identified) continue;\n\n const fresh = (await (model as any).$exec(\n \"findFirst\",\n { where, select: { _count: node } },\n markPreScoped({ strategy: (options as any)?.strategy }),\n )) as Record<string, unknown> | null;\n\n // `null` only if the row vanished between the write and this read, which\n // inside the write's own transaction it cannot. Leaving the projected value\n // alone is still the right fallback: it is stale, not invented.\n if (fresh && fresh._count !== undefined) row._count = fresh._count;\n }\n}\n\nfunction rowsOf(result: unknown): Record<string, unknown>[] {\n if (Array.isArray(result)) return result as Record<string, unknown>[];\n if (result === null || result === undefined) return [];\n if (typeof result !== \"object\") return [];\n return [result as Record<string, unknown>];\n}\n\n/**\n * Splits a `createMany` that would exceed the driver's parameter ceiling, or\n * returns `null` when it fits.\n *\n * The ceiling is enforced in `render`, so the only way to learn that a call is\n * too large is to try compiling it. That is deliberate rather than lazy: a size\n * check ahead of every write would cost every write, and the plan cache means\n * the compile is paid once per shape anyway.\n *\n * The chunk size comes from **binding one row**, not from dividing the reported\n * total. Division looks equivalent and is not: `required` includes whatever the\n * statement binds besides the rows, so on a shape with any fixed overhead it\n * understates the per-row cost and produces a chunk that is still too large.\n * Binding a single row asks the compiler the question directly.\n */\nfunction chunkedCreateMany(\n schema: ModelSchema,\n args: any,\n dialect: SqlDialect,\n strategy: RelationStrategy,\n op: Operation,\n): unknown[][] | null {\n const rows = args.data as unknown[];\n if (rows.length < 2) return null;\n\n try {\n getOrCompile(schema, op, args, dialect, strategy);\n return null;\n } catch (error) {\n if (!(error instanceof ParameterLimitError)) throw error;\n\n const single = { ...args, data: [rows[0]] };\n const perRow = getOrCompile(schema, op, single, dialect, strategy).bind(\n single,\n createBindContext(),\n ).length;\n\n // One row on its own over the ceiling is not a chunking problem — no split\n // can help, and the original error says the useful thing.\n if (perRow === 0 || perRow > error.limit) throw error;\n\n const size = Math.floor(error.limit / perRow);\n const chunks: unknown[][] = [];\n for (let at = 0; at < rows.length; at += size) {\n chunks.push(rows.slice(at, at + size));\n }\n return chunks;\n }\n}\n\n/**\n * Whether an `upsert` has to become a read and a write.\n *\n * True exactly when `create` leaves part of the conflict key unset, which is the\n * case `on conflict` cannot express — the insert could never collide on the\n * target, so the update branch would be unreachable.\n *\n * A `where` that names no unique key, or names several, is not this function's\n * to report: it returns false and lets the ordinary path raise the error it\n * already has for that, with the message it already has.\n */\nfunction findThenWrite(schema: ModelSchema, args: any, op: Operation): boolean {\n try {\n const key = matchUniqueKey(schema, args?.where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n return upsertAbsentConflictKey(schema, args, key).length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Runs a folded relation's own `redact` over the rows the strategy inlined, and\n * then its descendants' over theirs.\n *\n * Only for a plan carrying `root` — a batched child came back through its own\n * `$exec` and has already redacted itself, and doing it twice is harmless but\n * pointless. Only outside `asSystem`, like every other policy.\n *\n * **Recursive, because the fold is.** A lateral node folds its whole subtree into\n * one statement, so a grandchild's rows never enter its model's `$exec` either —\n * and stopping at depth 1 would leave exactly the rows nobody thinks to check\n * unredacted. `RootContribution.folded` is the shape of what was folded, which is\n * the only thing that makes the walk possible.\n *\n * The child's policies are resolved through the registry by name, so this obeys\n * the same rule every nested read does: whatever is registered under that name\n * is the class whose policies apply.\n */\nfunction redactFolded(\n relation: { as: string; model: string; folded?: readonly FoldedRelation[] },\n result: unknown,\n op: Operation,\n system: boolean,\n): void {\n const target = registry.has(relation.model)\n ? registry.get<unknown>(relation.model)\n : undefined;\n const policies = target ? policiesFor(target) : [];\n const nested = relation.folded ?? [];\n\n if (policies.length === 0 && nested.length === 0) return;\n\n const context =\n policies.length > 0\n ? policyContext(\n (target as { $schema?: { name?: string } }).$schema?.name ??\n relation.model,\n op,\n currentUser(),\n system,\n )\n : undefined;\n\n // Collected whether or not *this* level redacts anything: an unpolicied model\n // in the middle of the tree must not hide a policied one below it.\n const children: Record<string, unknown>[] = [];\n\n for (const parent of rowsOf(result)) {\n const rows = parent?.[relation.as];\n if (rows === undefined || rows === null) continue;\n if (context) applyRedaction(policies, context, rows);\n if (nested.length > 0) children.push(...rowsOf(rows));\n }\n\n for (const child of nested) redactFolded(child, children, op, system);\n}\n",
|
|
29
|
+
"import type { SQL, TransactionSQL } from \"bun\";\nimport type { DatabaseConnection } from \"../database/Connection\";\nimport { DatabaseManager } from \"../database/DatabaseManager\";\nimport { app } from \"../foundation/app\";\nimport { type BindContext, createBindContext } from \"./compile/fragment\";\nimport {\n currentConnectionName,\n currentTransaction,\n isSystemScope,\n runAsSystem,\n runAsUser,\n runOnConnection,\n withTransaction,\n} from \"./context\";\nimport {\n type FoldedRelation,\n type NestedWriteStep,\n type RelationExecutor,\n type RelationStrategy,\n attachRelations,\n} from \"./compile/plan-relations\";\nimport { resolveStrategy } from \"./compile/strategy\";\nimport { matchUniqueKey } from \"./compile/unique\";\nimport { upsertAbsentConflictKey } from \"./compile/write\";\nimport { dialectFor, type SqlDialect } from \"./dialect\";\nimport { clockCouldSkew, createProtocolSkewWarner } from \"./protocol-skew\";\nimport {\n MissingModelSchemaError,\n RecordNotFoundError,\n UnsupportedQueryError,\n UniqueConstraintError,\n ParameterLimitError,\n UnregisteredPolicyClassError,\n} from \"./errors\";\nimport {\n getOrCompile,\n type ExecOptions,\n type Operation,\n type QueryPlan,\n} from \"./plan\";\nimport {\n applyNestedPolicies,\n applyPolicies,\n applyRedaction,\n currentUser,\n isPreScoped,\n markOrmAuthored,\n markPreScoped,\n markRedactedAs,\n ormAuthoredFields,\n policiesFor,\n policyContext,\n redactedAs,\n NESTED_READ,\n type PolicyEntry,\n type PolicyContext,\n} from \"./policy\";\nimport {\n changedFields,\n provenanceOf,\n resnapshot,\n track,\n untracked,\n} from \"./provenance\";\nimport * as registry from \"./registry\";\nimport type { ModelSchema } from \"./schema\";\n\n/**\n * The base every generated model class extends.\n *\n * `$exec` is the framework's single choke point: it is the only place in the\n * ORM that touches the database, and the public operations on the generated\n * subclasses are one-line delegations to it. Nested relation reads and nested\n * writes recurse through it too. Everything cross-cutting hangs here — the plan\n * cache and constraint-error translation today, ambient transactions in\n * iteration 5, policies in iteration 6, plus slow-query logging and metrics\n * later. One operation that \"just does a quick insert directly\" silently\n * escapes all of it, which is why there is exactly one door.\n *\n * Framework internals take a `$` prefix so they cannot collide with anything an\n * application author adds to a model.\n */\n\n/** Operations Prisma raises on when nothing matched, rather than returning null. */\nconst ORTHROW = new Set([\n \"findFirstOrThrow\",\n \"findUniqueOrThrow\",\n // Prisma raises P2025 — \"No record was found for an update\" / \"...a delete\" —\n // rather than returning null, and the differential harness compares the fact\n // of throwing.\n \"update\",\n \"delete\",\n]);\n\n/**\n * `withTransaction` with the connection's configured warning threshold attached.\n *\n * Every transaction the ORM opens goes through here rather than calling\n * `withTransaction` directly, so `database.slowTransactionThreshold` is read in\n * one place instead of at each call site — and a call site added later cannot\n * quietly open a transaction that ignores the setting. `withTransaction` itself\n * takes the threshold as an argument on purpose; it knows nothing about the\n * container, and this is the seam where the two meet.\n *\n * The same argument now carries the connection's **name**: a pool cannot be\n * asked which one it is, and `withTransaction` has to know in order to tell a\n * nested transaction on the same connection (a savepoint) from one on another\n * (a refusal). Taking the whole connection rather than the manager is what\n * makes both come from the same object, so a named connection cannot end up\n * with the default's threshold.\n */\nfunction transact<T>(\n connection: DatabaseConnection,\n fn: (tx: TransactionSQL) => Promise<T>,\n): Promise<T> {\n return withTransaction(connection.sql, fn, {\n slowTransactionThreshold: connection.config.slowTransactionThreshold,\n connection: connection.name,\n });\n}\n\n/**\n * The classes `Model.on` has already built, keyed by the class it was called on\n * and then by connection name.\n *\n * `User.on(\"analytics\")` is a per-query call, so it can happen in a loop and in\n * a hot path; minting a class each time would allocate one per query and defeat\n * every identity comparison downstream — the policy-divergence guard's\n * `registered !== this` among them, which would then run `policiesFor` against\n * a class it had never seen before on every call.\n *\n * A `WeakMap` on the outside so a model class that goes out of scope takes its\n * bound variants with it, which matters for tests that define models inline.\n */\nconst boundToConnection = new WeakMap<object, Map<string, typeof Model>>();\n\nexport abstract class Model {\n /**\n * Protected, so `new UserModel()` is a type error.\n *\n * Not stylistic. The generated bases merge the row's columns into their\n * instance type via a same-named interface, which is what lets a method on a\n * subclass read `this.email` — and the cost of declaration merging is that\n * TypeScript does not check those properties are ever initialised. A directly\n * constructed instance would therefore type as carrying every column while\n * holding none.\n *\n * Closing the constructor removes that hazard rather than documenting it: the\n * only way to get an instance is `wrap`, which assigns a complete row. Every\n * other operation returns plain objects and never constructs one.\n */\n protected constructor() {}\n\n /** Assigned by the generated subclass from `app/models/generated/schema.ts`. */\n static $schema: ModelSchema;\n\n /**\n * Set to `true` by the generator on each base it emits, and by nothing else.\n *\n * `registerModels` has to tell a generated base from an application class\n * written over it, because when both are in one namespace the subclass is the\n * one that must own the name — electing the base *is* #316's leak. It used to\n * answer that by asking whether a class declared `$schema` itself, which is an\n * inference about how the generator happens to be written rather than a\n * statement by the generator, and a subclass that redeclared `static $schema`\n * read as a base because of it. This is the generator saying so.\n *\n * **`declare`, and it has to stay `declare`.** The property must not exist on\n * `Model` at runtime: `isGeneratedBase` reads `\"$generated\" in candidate` to\n * decide whether the artifacts in front of it carry the mark at all, and falls\n * back to the old inference for artifacts generated before this existed. A\n * `Model.$generated` of `undefined` would answer that question `true` for\n * every class, in every app, including the ones with no mark to read.\n * `registration.test.ts` pins it.\n *\n * **`?: true` and not `?: boolean`**, which is what makes a hand-written\n * `static $generated = false` the type error `isGeneratedBase` reads it as.\n * The cost is that the generator has to emit a non-widening initialiser —\n * `static readonly $generated = true`, since a mutable one widens to\n * `boolean` and every emitted class becomes a TS2417. That happened;\n * `tsconfig.generated.json` is the check that catches it now.\n */\n declare static $generated?: true;\n\n /**\n * The model's own policies, in the order they should apply.\n *\n * A list rather than the single `$policy` this replaced, because composition\n * is the normal case and the two ways of expressing it against one slot were\n * both bad. Spreading (`{ ...softDeletes(), ...mine }`) silently drops\n * whichever `scope` came first, and an intermediate base class per combination\n * means one throwaway class for every model a shared policy applies to — the\n * generated bases all differ, so a `TenantScoped` used on three models needed\n * three of them.\n *\n * Each level of the prototype chain contributes its own array and they\n * concatenate base first, so a shared model base can still impose a policy\n * that a subclass can only narrow. See `policiesFor`.\n *\n * Entries may be policy objects or classes; a class is instantiated once. The\n * generated `<Model>Policy` type gives an object literal here full contextual\n * typing, which a bare `$policies = [...]` does not get on its own.\n */\n static $policies?: readonly PolicyEntry[];\n\n /**\n * The connection this class's operations run on, set only by `on` below.\n *\n * `undefined` — which is what every model an application writes has — means\n * *the ambient connection*, not *the default one*. The two differ inside\n * `DB.connection(\"analytics\").transaction(...)`, where an unqualified query\n * has to join the open transaction rather than quietly reach for the hot\n * path's pool.\n */\n static $connection?: string;\n\n /**\n * The same model, reading and writing on a named connection.\n *\n * const rows = await Subscription.on(\"analytics\").findMany({ where })\n *\n * **Per query, not per model**, which is the shape the problem actually has:\n * the same `Subscription` is read on the hot path during sign-in and swept by\n * the nightly audit. A `static $connection = \"analytics\"` on the class would\n * force one of those two to be wrong, so the choice lives at the call site\n * and every query that does not make it stays on the default connection.\n *\n * What it returns is the model class with the connection bound to it, so the\n * whole typed surface — all fifteen operations, `transaction`, `save` — is\n * there unchanged and narrows exactly as it does on the class itself. The\n * connection reaches nested `include` reads and nested writes as well, which\n * an argument on `findMany` could not have done: those recurse through the\n * *target* model's `$exec` by way of the registry, so it is carried in the\n * ambient scope rather than in anyone's parameter list.\n *\n * **A transaction cannot span connections.** Naming one inside a transaction\n * open on another raises `CrossConnectionTransactionError` rather than\n * running the statement outside the transaction, where it would survive the\n * rollback. See that error for why refusing is the only honest answer.\n *\n * An unknown name raises `UnknownConnectionError` at the query, not here:\n * `on` is a pure lookup and does not resolve the container, so a model bound\n * in a module's top-level scope cannot force the database open at import\n * time.\n */\n static on<T extends typeof Model>(this: T, connection: string): T {\n let byName = boundToConnection.get(this);\n if (byName === undefined) boundToConnection.set(this, (byName = new Map()));\n\n const cached = byName.get(connection);\n if (cached !== undefined) return cached as T;\n\n // A subclass rather than a Proxy. Both would forward the operations, but a\n // subclass *is* a class: `policiesFor` walks the prototype chain with\n // `Object.hasOwn`, the generated statics are inherited by the language\n // rather than by a trap, and `$exec`'s `this` needs no special handling to\n // stay bound to it.\n const bound = class extends (this as unknown as typeof Model) {\n static $connection = connection;\n };\n\n // Otherwise the class expression takes its name from the binding above and\n // every error that names the model says \"bound\". `UnregisteredPolicyClassError`\n // reads `this.name` in particular, and it is exactly the kind of message\n // that has to name the class the caller wrote.\n Object.defineProperty(bound, \"name\", {\n value: (this as { name: string }).name,\n configurable: true,\n });\n\n byName.set(connection, bound);\n return bound as unknown as T;\n }\n\n /**\n * Runs `fn` with policies suspended, for code that has no user and knows it:\n * a cron tick, a queue worker, a seed script, a migration.\n *\n * Deliberately a wrapper rather than a flag or a fallback. Under\n * deny-by-default the alternative to writing this is an error, which is the\n * point — unscoped access is a sentence someone typed, never what happens\n * when a user fails to turn up.\n *\n * await Model.asSystem(() => User.findMany({}))\n */\n static asSystem<T>(fn: () => Promise<T>): Promise<T> {\n return runAsSystem(fn);\n }\n\n /**\n * Runs `fn` with policies scoped to `user`, for code that acts on somebody's\n * behalf without a request to read them from — a queue job, a scheduled\n * report, a test.\n *\n * The narrow counterpart to `asSystem`, and deliberately the easier of the\n * two to reach for. A worker handling \"send the invoice for organisation 7\"\n * acts *as* a user; giving it only `asSystem` would suspend policies outright\n * and leave it hand-scoping every query, which is the unscoped-by-accident\n * outcome deny-by-default exists to prevent.\n *\n * await Model.asUser(owner, () => Invoice.findMany({}))\n */\n static asUser<T>(user: unknown, fn: () => Promise<T>): Promise<T> {\n return runAsUser(user, fn);\n }\n\n /**\n * Persists the changes made to a *tracked* row: `update` with only the columns\n * whose value differs from what was fetched.\n *\n * const user = await User.findUnique({ where: { id } }, { track: true })\n * user.name = \"new name\"\n * await User.save(user) // update \"User\" set \"name\" = ?, … where \"id\" = ?\n *\n * Most of Eloquent's write ergonomics while returns stay plain objects — no\n * proxies, no conditional return types, no signature that changes with a flag.\n * That is invariant 5's whole claim, and this is the thing that tests it.\n *\n * Goes through `$exec(\"update\", …)` rather than around it, so policies,\n * `@updatedAt`, the ambient transaction and the plan cache all apply exactly as\n * they do to a hand-written update. The changed-column *set* is the plan's\n * shape and the values are parameters, so two saves touching the same columns\n * share one plan.\n *\n * Returns `null` when nothing changed, having issued no statement — a save of\n * an untouched row should not stamp `@updatedAt`.\n *\n * Raises when handed an object with no provenance. See `untracked` for why\n * that is a loud failure rather than a fallback to writing everything.\n *\n * **It writes back to the connection the row was read on**, which is the one\n * place a connection cannot be resolved from the ambient scope: a row read on\n * `analytics` is an ordinary object that outlives the scope that produced it,\n * and by the time it is saved — three functions later, from code that never\n * named a connection — the scope is gone. So the connection is part of the\n * row's provenance, exactly as the model and the primary key are, and for the\n * same reason. Left to the ambient default, `save` compiled a correct\n * `update` and sent it to the wrong database, where the same id usually names\n * a real and different row.\n *\n * Naming a *different* connection explicitly — `User.on(\"default\").save(row)`\n * for a row read on `analytics` — is a contradiction rather than an\n * instruction, and raises. Copying a row between connections is a write in\n * its own right: say it with `update`, where the `where` and the `data` are\n * both visible.\n */\n static async save<T extends object>(row: T): Promise<unknown> {\n const schema = this.$modelSchema();\n const record = provenanceOf(row);\n\n if (!record) throw untracked(row, schema.name);\n\n if (record.model !== schema.name) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row came from ${record.model}, not ${schema.name}. Save it ` +\n `through the model it was read from.`,\n );\n }\n\n if (\n this.$connection !== undefined &&\n this.$connection !== record.connection\n ) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row was read on the \"${record.connection}\" connection and this ` +\n `save names \"${this.$connection}\". A save writes the row back where ` +\n `it came from, so the two cannot both be honoured. Drop the ` +\n `\\`on(\"${this.$connection}\")\\`, or write it as an explicit ` +\n `${schema.name}.on(\"${this.$connection}\").update({ where, data }) if ` +\n `copying it across connections is what you meant.`,\n );\n }\n\n // A row selected without its primary key has `key = { id: undefined }`, and\n // `matchUniqueKey` drops undefined members — so the update fails with\n // \"update needs a unique field\", pointing at a `where` the caller never\n // wrote. Named here instead, where the actual mistake is knowable: this can\n // only mean the select omitted the key.\n const missingKey = schema.primaryKey.filter(\n (name) => record.key[name] === undefined,\n );\n if (missingKey.length > 0) {\n throw new UnsupportedQueryError(\n \"save\",\n schema.name,\n \"save\",\n `This row was fetched without ${missingKey.join(\", \")}, so there is no ` +\n `way to identify which row to update. A tracked row needs its primary ` +\n `key: add ${missingKey.map((name) => `${name}: true`).join(\", \")} to ` +\n `the select, or drop the select to fetch every column.`,\n );\n }\n\n const changed = changedFields(row, schema);\n if (Object.keys(changed).length === 0) return null;\n\n // On the row's own connection, entered here rather than left to `$exec`:\n // `$exec` resolves the *ambient* name, and the whole point is that the row\n // outlived the scope that read it. Inside a transaction on another\n // connection this raises `CrossConnectionTransactionError` from `$exec`,\n // which is the correct answer — that update cannot join the transaction, so\n // it must not run at all.\n const updated = await runOnConnection(record.connection, () =>\n this.$exec(\"update\", {\n where: record.key,\n data: changed,\n }),\n );\n\n // Copy the *returned* row back over the caller's, not just the values sent.\n //\n // `@updatedAt` is stamped by the compiler and is therefore never in\n // `changed`, so without this the in-memory row keeps the timestamp it was\n // fetched with while the database holds a newer one — a caller reading\n // `user.updatedAt` after a successful save silently gets the old instant. The\n // same applies to anything else the database rewrote.\n //\n // Resnapshotting from the same source is what keeps the row and its snapshot\n // in agreement, so a second `save` is still a no-op.\n if (updated && typeof updated === \"object\" && !Array.isArray(updated)) {\n const fresh = updated as Record<string, unknown>;\n const target = row as Record<string, unknown>;\n const persisted: Record<string, unknown> = {};\n\n for (const name of Object.keys(fresh)) {\n if (!(name in schema.fields)) continue;\n target[name] = fresh[name];\n persisted[name] = fresh[name];\n }\n\n resnapshot(row, persisted);\n } else {\n resnapshot(row, changed);\n }\n\n return updated;\n }\n\n /**\n * Turns a **complete** row into an instance of this class, for code that wants\n * behaviour rather than data.\n *\n * const user = User.wrap(await User.findUniqueOrThrow({ where: { id } }))\n * user.displayName // a method on your subclass\n * await user.save()\n *\n * Explicit, never implicit, and that is the whole design. The moment queries\n * hydrate by default, the `select` conflict comes back: a method that reads\n * `this.email` on a row fetched as `select: { id: true }` is a runtime crash\n * the type system cannot see. Keeping `wrap` a call the author makes means\n * narrowing and behaviour never meet.\n *\n * **Completeness is required, and the requirement is not arbitrary.** The\n * generated signature takes the full scalar payload, so a `Pick` of it is a\n * compile error rather than a runtime surprise (there is a type test for\n * exactly that). It is the same constraint that makes `save()` work on the\n * result: a complete row is one this can snapshot in full, so an instance is\n * tracked without the caller asking. The type constraint and the save\n * capability are one constraint, not two.\n *\n * Note the instance is a *copy*: mutating it does not touch the row that was\n * passed in, and `save()` diffs against what `wrap` received.\n */\n static wrap(row: object): any {\n const schema = this.$modelSchema();\n const instance = new (this as unknown as new () => any)();\n\n Object.assign(instance, row);\n // Tracked on the instance, not the argument — `save()` on the instance has\n // to diff against the values it was constructed from.\n //\n // The connection is the argument's, when the argument has one. `wrap` runs\n // *after* the query's scope has closed, so the ambient name here is\n // whatever the caller happens to be in — usually the default — and a row\n // read on `analytics` would be wrapped into an instance whose `save()`\n // wrote to the hot path. Taken in order: an explicit `on`, then where the\n // row actually came from, then the ambient connection for a row that was\n // never tracked at all.\n track(\n instance,\n schema,\n this.$connection ??\n provenanceOf(row)?.connection ??\n currentConnectionName(),\n );\n\n return instance;\n }\n\n /**\n * Persists this instance's changes. The instance counterpart of the static, and\n * a one-line delegation to it so there is one implementation.\n */\n save(): Promise<unknown> {\n return (this.constructor as typeof Model).save(this);\n }\n\n static $modelSchema(): ModelSchema {\n const schema = this.$schema;\n if (!schema) throw new MissingModelSchemaError(this.name);\n return schema;\n }\n\n /**\n * Runs `fn` inside a transaction. Every ORM query in it — at any call depth,\n * through any number of services, including the nested reads an `include`\n * fans out into — joins it automatically.\n *\n * The callback takes **no argument**, and that is the whole feature. Handing\n * back a `tx` would put it in the signature of every function between here\n * and the query, which is precisely the threading Prisma's `$transaction`\n * forces and this exists to remove. If a raw query genuinely needs the\n * handle, `currentTransaction()` hands it over without putting it in anyone's\n * parameter list.\n *\n * Nesting is a savepoint: an inner failure rolls back to it and leaves the\n * outer transaction usable, so a caller that catches keeps going.\n *\n * await User.transaction(async () => {\n * const user = await User.create({ data: { email } })\n * await audit(user) // its queries are in the transaction too\n * })\n *\n * **KNOWN DIALECT ASYMMETRY — catching an error inside a transaction.**\n * The sentence above holds for a *nested* `Model.transaction`. It does not\n * hold for a bare statement: on Postgres any failed statement aborts the\n * whole transaction block, so catching it and carrying on loses everything.\n * SQLite does not care. Verified against Postgres 16 and SQLite:\n *\n * await Model.transaction(async () => {\n * try { await User.create({ data: { email } }) }\n * catch (e) { if (!(e instanceof UniqueConstraintError)) throw e }\n * await Audit.create({ ... }) // fine on SQLite; on Postgres this\n * }) // throws 'current transaction is\n * // aborted', and the whole transaction\n * // is lost\n *\n * That is a bug that passes in development on SQLite and takes out the\n * transaction in production on Postgres, with an error naming neither the\n * statement that failed nor the one that caused it.\n *\n * The fix is already here: wrap the fallible statement in a nested\n * `Model.transaction`, which makes it a savepoint, and rolling back to that\n * savepoint clears the aborted state. Works on both dialects.\n *\n * await Model.transaction(async () => {\n * try {\n * await Model.transaction(() => User.create({ data: { email } }))\n * } catch (e) { if (!(e instanceof UniqueConstraintError)) throw e }\n * await Audit.create({ ... }) // fine on both\n * })\n *\n * **One statement at a time.** Every query in scope runs on one reserved\n * connection, so `Promise.all` over several ORM calls inside the callback is\n * not safe here — the ordinary, encouraged thing everywhere else in a Bun\n * codebase. Await them in sequence. (`$exec` already runs its own nested\n * writes and relation reads sequentially for this reason.)\n *\n * **The connection is held for as long as the callback runs**, including\n * while it awaits things that are not queries. In development a transaction\n * still open after 2s warns — `database.slowTransactionThreshold` sets that\n * bound, or `false` switches it off. In production it just holds the\n * connection. Keep network and filesystem I/O outside.\n */\n // `async`, so that naming a connection this transaction cannot reach —\n // `Subscription.on(\"analytics\").transaction(...)` inside a transaction on the\n // hot path — *rejects* rather than throwing synchronously. The same reasoning\n // `DB.query` records: an API that does one sometimes and the other otherwise\n // is a footgun, and a `.catch()` would miss exactly this error.\n static async transaction<T>(fn: () => Promise<T>): Promise<T> {\n // `Subscription.on(\"analytics\").transaction(...)` opens on that connection,\n // and a bare `Model.transaction` opens on whatever is ambient — which is\n // the default connection unless something outside has already named one.\n // `withTransaction` refuses the mismatch; there is no second check here.\n const name = this.$connection ?? currentConnectionName();\n\n return transact(app(DatabaseManager).connection(name), () =>\n runOnConnection(name, () => fn()),\n );\n }\n\n /**\n * The choke point's outer half: which connection this operation runs on.\n *\n * Split from the body below so that the name is resolved and entered\n * **once**, around everything — the policy pass, the plan lookup, the nested\n * writes and every relation read that recurses back through here. The\n * alternative, resolving it inside, would have left each nested read to\n * rediscover it, and the one that did not would have run against the default\n * connection with no error to show for it.\n *\n * Recursive calls cost a comparison: the ambient name already matches, so\n * `runOnConnection` calls straight through without entering a second scope.\n *\n * `async` for the reason `transaction` is: an operation refused for naming a\n * connection the open transaction cannot reach has to reject like every other\n * failure `$exec` produces, rather than being the one that throws before the\n * promise exists.\n *\n * The cross-connection refusal is `runOnConnection`'s, not repeated here:\n * *entering* the connection is the only moment at which the scope still holds\n * both the open transaction and the name it belongs to, so that is where the\n * comparison has to live.\n */\n static async $exec(\n op: Operation,\n args: any = {},\n options?: ExecOptions,\n ): Promise<unknown> {\n return runOnConnection(this.$connection ?? currentConnectionName(), () =>\n this.$execute(op, args, options),\n );\n }\n\n private static async $execute(\n op: Operation,\n args: any = {},\n options?: ExecOptions,\n ): Promise<unknown> {\n const schema = this.$modelSchema();\n\n // Resolved per call, never captured at module scope: that is what keeps the\n // connection swappable in tests.\n //\n // Through `connection()` rather than off the manager directly, so that a\n // query on a named connection reads *that* pool's client and dialect. The\n // default connection is the manager itself, which is what keeps every\n // existing wrapper of it — the harnesses that Proxy `sql` to count\n // statements — looking at the object this executes through.\n const db = app(DatabaseManager).connection(currentConnectionName());\n const dialect = dialectFor(db.dialect);\n\n // The ambient-transaction hook, and the entire integration. It is one line\n // — and it covers every operation, every nested write and every relation\n // read — only because invariant 1 held: `$exec` is the single door. An\n // operation that acquired a private path to the database would show up\n // here as a statement silently running outside the transaction, committed\n // while its neighbours roll back.\n // `let`, because a multi-statement write opens a transaction of its own\n // further down and every statement after that point — including the\n // `executor.query` closure below, which captures this binding rather than\n // its value — has to run on the new handle rather than back on the pool.\n let conn = currentTransaction() ?? db.sql;\n\n // POLICIES, AND THE ORDER MATTERS MORE HERE THAN ANYWHERE ELSE IN THE ORM.\n //\n // Policies rewrite the argument tree, so they change the SQL. They must\n // therefore run *before* `getOrCompile`, which keys the plan cache on those\n // arguments. Reordered — compile first, scope after — two users with the\n // same query shape and different scopes would share one plan, and one of\n // them would run the other's SQL. That is a cross-tenant data leak produced\n // by a caching bug, and it would not look like one.\n //\n // A scope that injects a *value* keeps the same shape for every user, so\n // the plan is still shared and only the bound value differs. That is the\n // desired outcome, not a compromise, and `policy.plan-cache.test.ts` pins\n // both halves: same shape means one plan and different parameters, and a\n // scope whose shape varies by user means a different plan key.\n // `asSystem` suspends the whole hook, not just the no-user check: a script\n // that has said it is a script should not then be scoped to a user that\n // happens to be in the request store.\n const system = isSystemScope();\n const policies = system ? [] : policiesFor(this);\n let policy: PolicyContext | undefined;\n let effective = args;\n\n // POLICY-DIVERGENCE GUARD.\n //\n // A nested relation read resolves its target through the registry, so it\n // runs whatever is registered under this model's name — not necessarily the\n // class the caller queried. When those two disagree about *policies*, the\n // same policy applies to some queries and not others, silently. Both\n // directions are reachable and both are the same bug:\n //\n // policied class not registered -> root scoped, nested reads unscoped\n // policied class registered, but -> nested reads scoped, a direct query\n // the caller queries the base through the base unscoped\n //\n // The second is the one this check sat inside `policies.length > 0` and\n // therefore missed: querying `AccountModel` when `Account` owns the name\n // finds no policies on `AccountModel`, so the old placement never looked.\n // `AccountModel` and `Account` come out of the same barrel with near\n // identical names, so it needs no include and no mistake worth calling one.\n //\n // Keyed on the *divergence*, not on either class having policies. The\n // comparison is of the resolved policy chain rather than class identity: a\n // plain subclass of a registered, policied class inherits the same policy\n // objects in the same order, so nothing diverges and there is nothing to\n // refuse — checking identity rejected `class AdminUser extends User {}`, a\n // typed view, for policies it had not written.\n //\n // `!system` is load-bearing. Under `asSystem` policies are suspended by\n // design, so a seed script querying the generated base directly is correct\n // and must not raise.\n //\n // Cost on the common path: one `Map.get` and one reference compare, for a\n // model where nothing is registered under a different class.\n //\n // `inheritsPoliciesFrom` keeps that true for `Model.on(name)`, whose bound\n // subclass is never the registered class and so failed the reference\n // compare on *every* query — leaving each one to resolve the registered\n // chain and walk it twice to reach the same conclusion. A direct subclass\n // that declares no policies of its own has, by construction, the chain its\n // parent has: there is nothing to compare.\n if (!system) {\n const registered = registry.has(schema.name)\n ? registry.get<unknown>(schema.name)\n : undefined;\n\n if (\n registered !== undefined &&\n registered !== this &&\n !inheritsPoliciesFrom(this, registered)\n ) {\n const theirs = policiesFor(registered);\n const diverges =\n policies.length !== theirs.length ||\n policies.some((entry, index) => entry !== theirs[index]);\n\n if (diverges) {\n throw new UnregisteredPolicyClassError(\n schema.name,\n (registered as { name?: string }).name ?? String(registered),\n this.name,\n policies.length > 0 ? \"queried\" : \"registered\",\n );\n }\n }\n }\n\n // NESTED policies, applied to the argument tree before the plan key.\n //\n // A nested read under the batched strategy would acquire its own policies by\n // recursing through the child's `$exec` — but a lateral join has no such call,\n // so the child's policies would never be consulted and the subquery would be\n // unscoped. Applying them here, on the args, keeps the compiler pure and makes\n // the scope part of whatever SQL a strategy chooses to emit. See\n // `applyNestedPolicies` and `plans/orm/09-lateral-strategy.md`.\n //\n // `preScoped` is how the double application is avoided: the relation executor\n // marks its recursive calls, so a child whose args arrived already scoped does\n // not scope them again. Without it a batched include would `AND` the same\n // predicate twice — the same rows, but different SQL and a different plan key.\n const preScoped = isPreScoped(options);\n\n if (!system && !preScoped) {\n effective = applyNestedPolicies(\n schema,\n effective,\n currentUser(),\n system,\n (model) => {\n if (!registry.has(model)) return undefined;\n const target = registry.get<typeof Model>(model);\n const targetSchema = target.$schema;\n if (!targetSchema) return undefined;\n return { policies: policiesFor(target), schema: targetSchema };\n },\n );\n }\n\n // `upsert` whose `create` does not set the conflict key, which used to\n // raise — and which is decided **before** policies are applied, on purpose.\n //\n // The last of iteration 4's three \"not before iteration 5\" items. That note:\n // \"Prisma means find-then-write there; expressing that takes a read and a\n // write inside one transaction, which is iteration 5's.\"\n //\n // Checked against a generated Prisma 6 client rather than reasoned about,\n // because the semantics are surprising: `upsert({ where: { publicId: \"X\" },\n // create: { email } })` inserts a row whose `publicId` is **generated**, not\n // \"X\". The `where` selects; it does not contribute to the insert.\n //\n // **`on conflict` is kept wherever it works.** It is one atomic statement,\n // and read-then-write is not — two callers can both miss and both insert.\n // Prisma's upsert has that race and this inherits it, but only on calls that\n // previously raised: nothing that worked becomes racy.\n //\n // **Before policies, and that is what lets a scoped model upsert at all.**\n // `assertScopable` refuses to put a scope on an `upsert`, because its where\n // becomes an `on conflict` target and a target cannot carry a predicate.\n // That reason is exactly true of the `on conflict` path and false of this\n // one, which is three ordinary statements. Deciding here means the three run\n // as `findFirst`, `create` and `update`, each scoped normally by its own\n // `$exec` — so this branch is *not* marked pre-scoped, and a policied model\n // gets a working upsert instead of a refusal whose justification expired.\n //\n // A policy that branches on `context.operation` therefore sees the three it\n // actually runs rather than the one the caller named. That is the honest\n // reading: the operation really is three statements here.\n if (op === \"upsert\" && !preScoped && findThenWrite(schema, args, op)) {\n const { where, create, update, ...projection } = args;\n\n return transact(db, async () => {\n const found = await this.$exec(\"findFirst\", { where }, options);\n\n return found === null\n ? await this.$exec(\"create\", { data: create, ...projection }, options)\n : await this.$exec(\n \"update\",\n { where, data: update, ...projection },\n options,\n );\n });\n }\n\n if (policies.length > 0) {\n // Deny-by-default lives on the context's `user` accessor, not here: a\n // policy that never consults the user — a soft-delete scope, say — has\n // nothing to deny and must keep working with no request in sight. See\n // `policyContext`.\n //\n // `redactedAs` is the one thing that can make `context.operation` differ\n // from `op`, and it exists to *remove* a difference the caller can see: a\n // `delete` that has to read before it writes runs its pre-read as a\n // `findFirst` and hands that row back, so without this a `redact` keyed on\n // `\"delete\"` stopped firing the moment the call also carried an `include`\n // (#366). The row is the delete's return value; it is redacted as one.\n //\n // **Only on a pre-scoped call, which is what keeps it a redaction\n // concern.** `applyPolicies` below is skipped when `preScoped`, so on the\n // one call that sets this marker the context reaches nothing but\n // `applyRedaction`. Reading the marker unconditionally would leave a\n // shape — a future non-pre-scoped caller — where a `before` or a `scope`\n // could be handed an operation the statement is not, and `SCOPABLE` is\n // keyed on exactly that. The guard does not make that shape\n // unconstructible — `markRedactedAs(options, \"delete\")` on its own is\n // still a value anyone can build — it makes it *unread*, so the\n // consequence is absent rather than the shape. That is the whole of what\n // is claimed, and it is enough: the marker changes nothing on any call\n // that policies still rewrite.\n policy = policyContext(\n schema.name,\n (preScoped ? redactedAs(options) : undefined) ?? op,\n currentUser(),\n system,\n );\n\n // **The context is built even when pre-scoped; only the rewrite is\n // skipped.** `preScoped` means \"the scope is already in these args\" — not\n // \"this model has no policies\". Guarding the whole block on it left\n // `policy` undefined for every nested relation read, and `policy` is what\n // `applyRedaction` below is keyed on. So a `redact` protected a root query\n // and was skipped inside every `include`: scoped one way, unscoped the\n // other, which is the failure iteration 6 exists to prevent.\n //\n // Only `applyPolicies` is idempotency-sensitive. Re-running it would `AND`\n // the same predicate twice; re-running `redact` on an already-redacted row\n // is a no-op.\n if (!preScoped) {\n effective = applyPolicies(\n policies,\n policy,\n effective,\n ormAuthoredFields(options),\n );\n }\n }\n\n // Which strategy plans the include tree. Named per call or chosen by\n // `defaultStrategy`, and either way it reaches the plan key — two strategies\n // emit different SQL for the same arguments, so sharing a plan between them\n // would run one request's statement for the other's.\n const strategy = resolveStrategy(options?.strategy, dialect, {\n model: schema.name,\n operation: op,\n });\n\n // `createMany` past the driver's parameter ceiling, which used to raise.\n //\n // Iteration 4 refused to chunk and said why: \"it would make this several\n // statements, which cannot be made atomic until transactions land.\" They\n // landed in iteration 5. So the split happens here, inside one transaction,\n // and the caller gets the same `{ count }` a single statement would have\n // returned.\n //\n // **Only on the call that would otherwise have failed.** The ceiling is\n // checked in `render`, so the ordinary path pays nothing for this — it is a\n // `catch`, not a size check on every write. A `createMany` small enough to\n // compile never enters it.\n if (op === \"createMany\" && Array.isArray(effective?.data)) {\n const chunks = chunkedCreateMany(\n schema,\n effective,\n dialect,\n strategy,\n op,\n );\n\n if (chunks !== null) {\n return transact(db, async () => {\n let count = 0;\n for (const data of chunks) {\n const written = (await this.$exec(\n \"createMany\",\n { ...effective, data },\n markPreScoped({ strategy: options?.strategy }) as never,\n )) as { count: number };\n count += written.count;\n }\n return { count };\n });\n }\n }\n\n const plan = getOrCompile(schema, op, effective, dialect, strategy);\n\n const executor: RelationExecutor = {\n // `markPreScoped`: this model's policies were already applied to\n // `relationArgs` by the parent's nested walk, so re-applying them here\n // would `AND` the same predicate twice — same rows, different SQL,\n // different plan key. The marker is a module-private Symbol and is not\n // exported, so it cannot become a way for an application to skip policies.\n // The strategy propagates too. Without it a nested `$exec` fell back to\n // `defaultStrategy`, so a query explicitly asking for `batched` got the\n // *default* for every level below the root — on Postgres that meant the\n // grandchild folded anyway and the statement count was one lower than the\n // caller asked for. Found by the query-count test, which is the only thing\n // that could have found it: the results were identical either way.\n exec: (model, operation, relationArgs, preScoped, ormAuthored) => {\n const base = preScoped\n ? markPreScoped({ strategy: options?.strategy })\n : { strategy: options?.strategy };\n return registry\n .get<typeof Model>(model)\n .$exec(\n operation as Operation,\n relationArgs,\n (ormAuthored && ormAuthored.length > 0\n ? markOrmAuthored(base, ormAuthored)\n : base) as never,\n );\n },\n // The one query with no model behind it — the implicit m-n join table —\n // resolves its connection here rather than reaching for the pool, so it\n // joins the transaction like everything else.\n query: (text, values) => conn.unsafe(text, values),\n };\n\n // One context per call, holding the instant every `now()` and `@updatedAt`\n // on this operation shares, plus whatever the `before` steps resolve.\n const context = createBindContext();\n\n // `delete` with an `include` on a **cascading** relation, which returned the\n // children empty until now.\n //\n // The relation reads run after the delete statement, so where the schema\n // declares `onDelete: Cascade` the database has already removed the children\n // by the time they are read. Prisma runs the whole thing in a transaction and\n // returns them as they were. `compileDelete` recorded this as \"not fixable at\n // this layer — the fix is to read the relations before the delete inside one\n // transaction, which is iteration 5's to provide\".\n //\n // Iteration 5 provided it. Read first, delete second, return what was read:\n //\n // - **A transaction, so the pair is atomic.** Without one, a delete that\n // fails after the read would leave the caller holding a row that still\n // exists. Nested inside a caller's transaction it is a savepoint, which is\n // what `withTransaction` already does.\n // - **`markPreScoped` on both**, because `effective` has been through this\n // model's policies once already; re-applying them would `AND` the same\n // predicate twice — same rows, different plan key.\n // - **The read is scoped as the delete was**, including its nested policies.\n // `effective` was rewritten by `applyPolicies` and `applyNestedPolicies`\n // under operation `\"delete\"`, and `markPreScoped` stops the pre-read\n // redoing either — so the `where` the `findFirst` runs is the delete's,\n // predicate for predicate.\n // - **`markRedactedAs`, so the row is redacted as the delete it belongs\n // to.** This bullet used to claim `context.operation` was already\n // `\"delete\"` here. It was not, and the row it was most wrong about was the\n // root one — the one returned. The pre-read is a `findFirst`, so\n // `policyContext` was built with `\"findFirst\"` and a `redact` keyed on\n // `\"delete\"` silently stopped firing as soon as the same call carried an\n // `include` (#366). The `delete` statement below *does* run under\n // `\"delete\"`, and its row is thrown away, so nothing observable came of\n // that half.\n //\n // The marker covers the returned row and nothing else. Nested reads are\n // *scoped* as `findMany` on both strategies — `NESTED_READ` in `policy.ts`\n // is a constant on purpose, because a read of another model is a read\n // whatever statement encloses it — and the marker does not reach them: the\n // relation executor rebuilds its options from `{ strategy }` rather than\n // forwarding these.\n //\n // Which name a nested row is *redacted* as is a second mechanism, and it\n // agrees with the first since #388. Both strategies answer `NESTED_READ`:\n // a **batched** child runs its own `$exec` under it, and a **folded**\n // (lateral, the Postgres default) child is handed the same constant by\n // `redactFolded` below, which redacts it on the parent's behalf because\n // its rows never enter its own `$exec`.\n //\n // Until #388 the folded path built its context from the enclosing\n // `$exec`'s `op` — on this call the pre-read, a `findFirst` — so the same\n // query over the same rows reported `findMany` on SQLite and `findFirst`\n // on Postgres. Neither value was ever the write, which is the part #366 is\n // about and the only part `delete-redact-operation.test.ts` pins under the\n // default strategy; `nested-redact-strategy.test.ts` pins the agreement.\n //\n // Only when there is something to read. A plain `delete` still compiles to\n // one statement and opens no transaction.\n //\n // `plan.counts` is here for the same hazard in its quietest form, and the\n // two dialects disagree about it. A `_count` compiles to a correlated\n // subquery inside the `RETURNING`, and where the schema cascades:\n //\n // postgres delete … returning (select count(*) from ch …) -> 3\n // sqlite delete … returning (select count(*) from ch …) -> 0\n //\n // Measured through Bun against a real `on delete cascade` on both. Postgres\n // evaluates the subquery against the pre-statement snapshot, which is what\n // Prisma returns; SQLite evaluates it after the cascade has run, so the\n // count is 0 — a *number*, so nothing looks missing and no error is raised.\n //\n // Reading first answers it the same way it already answers the `include`\n // case, and on both dialects rather than one. A count is not a relation\n // plan, so `relations` stays empty for an `include: { _count: … }` on its\n // own — hence the separate flag rather than a wider check.\n if (op === \"delete\" && (plan.relations !== undefined || plan.counts)) {\n // **Everything but the `where`, rather than the operands named one by\n // one.** The row this reads is the row the caller gets back — `return\n // before`, below — so an operand left out here is silently un-narrowed,\n // and nothing downstream will notice. That is #364: this rebuilt the\n // projection as `select` *or* `include`, `omit` was not among the names,\n // and a `delete` that asked to drop a column got it back as soon as the\n // same call also carried an `include`. A `delete` with no relation to read\n // never reaches this branch and projects through `resolveSelection`, which\n // had honoured `omit` all along — one operation, two paths, two answers.\n //\n // **Do not turn this back into named arms.** The rest is what makes the\n // next projection operand — Prisma's `relationLoadStrategy`, a `distinct`\n // on a write, whatever it turns out to be — arrive here for free instead\n // of arriving as the same bug with a different column name. The `upsert`\n // find-then-write branch a few hundred lines up spreads for the same\n // reason and was never affected by #364.\n //\n // Bounded, not hopeful. `assertArgs` (`compile/write.ts`) rejects any\n // operand outside `WRITE_ARGS.delete` — `where`, `select`, `include`,\n // `omit` — and the plan above is already compiled, so the rest holds\n // projection operands and nothing else. That set is a strict subset of\n // `findFirst`'s, so every one of them is a legal read operand. `omit` and\n // `select` cannot both be in it: `resolveSelection` refuses that pair, and\n // a warm plan cannot smuggle it past, since both are in `LITERAL_KEYS`\n // (`plan.ts`) and so key separately. An `undefined` operand is dropped from\n // the plan key too, so carrying one costs no second cache entry.\n const { where, ...projection } = effective;\n\n // The pool, not `conn`: when a transaction is already open `withTransaction`\n // savepoints against the ambient handle and ignores this argument, and\n // passing a transaction handle here would read as though we begin on it.\n return transact(db, async () => {\n const before = await this.$exec(\n \"findFirst\",\n { where, ...projection },\n // `op` rather than the literal `\"delete\"`: the branch is guarded on\n // it, so they are the same string, and taking it from the variable\n // keeps the two from drifting if the guard ever admits a second\n // operation that has to read before it writes.\n markRedactedAs(\n markPreScoped({ strategy: options?.strategy }),\n op,\n ) as never,\n );\n\n // `findFirst` shapes a miss to `null`; the caller asked for a delete, so\n // the error has to name that rather than the read this used underneath.\n if (before === null) throw new RecordNotFoundError(schema.name, op);\n\n await this.$exec(\n \"delete\",\n { where },\n markPreScoped({ strategy: options?.strategy }) as never,\n );\n\n return before;\n });\n }\n\n // A write with a nested `create` / `connect` runs more than one statement,\n // and those statements are one unit: the parent row and the children it was\n // asked for either all land or none do.\n //\n // This used to be left to the caller — \"atomic exactly when the caller\n // wrapped the call in `Model.transaction`, *not* implicitly\" — on the\n // reasoning that `$exec` cannot know whether it is one step of a larger unit\n // and that opening one per call would put a `BEGIN` around every query in\n // the framework. The second half of that is right and is why the condition\n // below is what it is; the first half does not survive contact with\n // policies. A nested write step runs the *child's* `$exec`, so the child's\n // policies are consulted mid-sequence, after the parent row is already\n // written. A child that denies therefore left a half-written parent behind,\n // and \"your policy stopped the write\" and \"your policy stopped half the\n // write\" are not the same promise.\n //\n // So: implicit, but only for the calls that are actually multi-statement.\n // A plain `create` still compiles to one statement and opens nothing, which\n // is what keeps the `BEGIN`-around-everything objection answered — and\n // inside a caller's own transaction `withTransaction` takes a savepoint\n // rather than nesting a second one.\n const finish = async (): Promise<unknown> => {\n // Re-resolved rather than reused: if the branch below opened a\n // transaction, every statement from here on belongs to it. Outside one\n // this is the same handle it already was.\n conn = currentTransaction() ?? conn;\n\n await runSteps(plan.before, effective, context, executor, []);\n\n // `unsafe` despite the name. Bun's tagged template cannot express a query\n // whose *shape* is dynamic, which every ORM query is. Safety here does not\n // come from the template syntax: it comes from the compiler's two rules —\n // identifiers only ever come from the generated schema, and every value is\n // a bound parameter. Do not \"fix\" this into a tagged template.\n const rows = await execute(\n conn,\n dialect,\n schema,\n op,\n plan.text,\n plan.bind(effective, context),\n );\n\n const result = this.$shape(plan, rows as unknown[]);\n\n // The plan shapes a single-row operation to `null` when nothing matched;\n // turning that into an error belongs here rather than in the plan, because\n // this is where the model's name is in scope for the message.\n if (result === null && ORTHROW.has(op)) {\n throw new RecordNotFoundError(schema.name, op);\n }\n\n // Rows that could not exist until this one did: the far side of a relation\n // whose foreign key lives on the child. Run before relations are attached,\n // so an `include` on the same call sees what was just written.\n await runSteps(plan.after, effective, context, executor, rowsOf(result));\n\n // ...and a `_count` on the same call has to be recomputed once they have,\n // for the same reason `include` is attached after them rather than before.\n //\n // A count is a correlated subquery inside the write's own `RETURNING`, so\n // it is evaluated at the instant the parent row is inserted — before any\n // `after` step has written a child. That produced a single response\n // contradicting itself:\n //\n // User.create({ data: { …, accounts: { create: [a, b] } },\n // include: { accounts: true, _count: { … } } })\n //\n // accounts.length 2 attached after the steps\n // _count 0 projected before them\n //\n // Both keys describe the same relation on the same row. The row itself was\n // never wrong — reading it back gives 2 — so this is the projection being\n // frozen, which is the mirror of the `delete` case above: there the count\n // is taken too late, here too early.\n //\n // **Only when there is something to be wrong about.** A write with no\n // `after` steps keeps the projected value and costs nothing extra; one\n // with both pays a single read. `plan.counts` is what makes that condition\n // cheap enough to ask on every write.\n //\n // **Between `runSteps` and the `hidden` deletion, and that is\n // load-bearing.** `select: { email, _count: … }` never asks for the\n // primary key, so the key the recount reads the row by is on it only\n // because the plan added it for the nested write and has not stripped it\n // yet. Move this after the strip and the recount loses its identifier;\n // move it before `runSteps` and there is nothing new to count.\n if (plan.counts && plan.after !== undefined) {\n await recountAfterSteps(\n schema,\n this as unknown as typeof Model,\n effective,\n rowsOf(result),\n options,\n );\n }\n\n // Relations are loaded after the root rows are shaped, one query per node\n // in the include tree. Each of those queries is `$exec` on the *related\n // model's own class*, recursively — not a private helper — so a nested read\n // is subject to everything a top-level read is.\n //\n // The planner is handed the database rather than reaching for it: that is\n // what keeps `compile/` free of a runtime import, and it is why the one\n // query with no model behind it — the implicit m-n join table — still runs\n // on the connection this call resolved.\n if (plan.relations !== undefined) {\n await attachRelations(\n plan.relations,\n plan.hidden,\n result,\n effective,\n executor,\n );\n } else if (plan.hidden !== undefined && plan.hidden.length > 0) {\n // A write can hide a key column without having any relation to attach:\n // a nested `after` step needs the parent's key returned, but the caller's\n // `select` never asked for it.\n for (const row of rowsOf(result)) {\n for (const key of plan.hidden) delete row[key];\n }\n }\n\n // A **folded** relation's rows never entered the child's `$exec`, so nothing\n // has run the child's `redact` over them. The comment below — \"a related row\n // was shaped by its own model's `$exec`\" — is true of the batched strategy\n // and false of the lateral one, which is precisely the kind of assumption\n // iteration 9 had to revisit for `scope`.\n //\n // `scope` survived the fold because policies rewrite the *argument tree*\n // before planning, and a scoped `where` lands inside the subquery. `redact`\n // cannot: it is a row transform in the shaping stage, with no argument to\n // rewrite. So the parent runs it on the child's behalf, which is the only\n // place that can.\n //\n // **`NESTED_READ`, not `op` — #388.** Running it here is a fact about where\n // the rows were shaped, not about what they are. The child is a read of\n // another model whatever statement encloses it, which is the whole reason\n // `applyNestedPolicies` scopes every nested node under the same constant,\n // and its docblock argues that at length. Handing the enclosing `op` down\n // made the *same* relation read, over the same rows, tell the child's\n // `redact` a different `context.operation` depending on which strategy\n // planned it: `findMany` batched, `findFirst` folded. A policy written as\n // `context.operation === \"findMany\"` therefore protected a child on SQLite\n // and leaked it on Postgres, for identical application code.\n if (plan.relations !== undefined && !system) {\n for (const relation of plan.relations) {\n if (relation.root === undefined) continue;\n redactFolded(\n {\n as: relation.as,\n model: relation.model,\n folded: relation.root.folded,\n },\n result,\n NESTED_READ,\n system,\n );\n }\n }\n\n // Redaction last, on the shaped result. After relations, not before: a\n // related row was shaped by its own model's `$exec` and has already been\n // through its own policy's `redact` — this one only owns its own rows.\n if (policy) applyRedaction(policies, policy, result);\n\n // Provenance, after redaction so a redacted field is not snapshotted as its\n // original value and then written back by `save`.\n //\n // Here rather than inside `$shape`, which is where the plan sketched it, for\n // one reason: `$shape` is the seam an `ActiveRecordModel` overrides to\n // return instances, and tracking there would make every such override\n // responsible for reimplementing it. Doing it at the choke point means an\n // override gets provenance for free — which is the same argument that put\n // everything else in `$exec`.\n if (options?.track === true) {\n for (const row of rowsOf(result)) track(row, schema);\n }\n\n return result;\n };\n\n const atomic =\n (plan.before !== undefined && plan.before.length > 0) ||\n (plan.after !== undefined && plan.after.length > 0);\n\n return atomic ? transact(db, finish) : finish();\n }\n\n /**\n * A static, not a module-level function, so subclassing is the extension\n * mechanism: a future `ActiveRecordModel` overrides this to build instances,\n * and every model extending it gets that with no change to the operations. It\n * is also where iteration 8 populates row provenance.\n */\n static $shape(plan: QueryPlan, rows: unknown[]): unknown {\n return plan.shape(rows);\n }\n}\n\n/**\n * Whether `queried` can only have the policies `registered` has.\n *\n * True for a direct subclass that declares none of its own — which is what\n * `Model.on(name)` builds, and also what `class AdminUser extends User {}` is.\n * `policiesFor` walks the prototype chain and takes each level's own\n * `$policies`; a level that declares none contributes nothing, so the walk from\n * here and the walk from the parent visit the same levels in the same order and\n * cannot disagree.\n *\n * Structural rather than a flag on the classes `on` mints, so the typed-view\n * subclass the divergence guard already argues should be allowed gets the same\n * short-circuit rather than paying for a second resolution of the chain.\n *\n * `$policy` — the removed name — is deliberately not checked: `policiesFor` has\n * already walked this class by the time this is called, and it raises on that\n * name at any level, so a class carrying it never reaches here.\n */\nfunction inheritsPoliciesFrom(queried: unknown, registered: unknown): boolean {\n return (\n Object.getPrototypeOf(queried) === registered &&\n !Object.hasOwn(queried as object, \"$policies\")\n );\n}\n\nasync function runSteps(\n steps: NestedWriteStep[] | undefined,\n args: any,\n context: BindContext,\n executor: RelationExecutor,\n rows: readonly Record<string, unknown>[],\n): Promise<void> {\n if (steps === undefined) return;\n // Sequentially, for the same reason relations load sequentially: inside an\n // ambient transaction every statement runs on one reserved connection, where\n // concurrent statements are not safe.\n for (const step of steps) {\n await step.run(args, context, executor, rows);\n }\n}\n\n/**\n * The skew warning, gated on this process's **zone** — resolved once, here.\n *\n * Reading the clock per call cost a `Date` allocation on the one path every\n * query takes — ~60ns, against under a nanosecond for the closed-over boolean\n * that replaces it — and the latch inside only ever closes on a *firing*, so\n * the deployment that is configured correctly and never warns paid it forever.\n *\n * `clockCouldSkew()` asks the question whose answer cannot change under a\n * running process: not \"is the offset zero today\", which is also true of\n * `Europe/London` every winter, but \"is this zone ever off UTC at all\". A UTC\n * process never enters the check; anything else stops entering once it has said\n * its piece, and reads the clock only until then — see `protocol-skew.ts`,\n * which owns both halves so that both can be tested from a UTC machine.\n */\nconst warnProtocolSkewOnce = createProtocolSkewWarner(clockCouldSkew(), () =>\n new Date().getTimezoneOffset(),\n);\n\n/**\n * Runs the statement and translates the failures that have a typed home.\n *\n * A unique violation is the one every application branches on, and every driver\n * reports it differently — SQLite as a message with a code, Postgres as a\n * SQLSTATE with a constraint name. Asking the dialect keeps that difference\n * behind the same seam as everything else, and turning it into an error that\n * names *fields* rather than columns is what makes it useful to a caller that\n * has never seen the database's names.\n */\nasync function execute(\n conn: Pick<SQL, \"unsafe\">,\n dialect: SqlDialect,\n schema: ModelSchema,\n op: Operation,\n text: string,\n values: unknown[],\n): Promise<unknown> {\n // Said once per process, and only for the configuration that silently returns\n // the wrong instant — see `protocol-skew.ts`. Printing is left here because\n // this is the layer allowed to talk to the operator; deciding is not, because\n // nothing that needs a database can be tested in the one configuration CI\n // runs.\n const warning = warnProtocolSkewOnce(dialect.name, schema, text, values);\n if (warning) console.warn(warning);\n\n try {\n return await conn.unsafe(text, values);\n } catch (error) {\n const violation = dialect.constraintViolation(error);\n if (!violation) throw error;\n\n throw new UniqueConstraintError(\n schema.name,\n op,\n fieldsForColumns(schema, violation.columns),\n violation.constraint,\n { cause: error },\n );\n }\n}\n\n/**\n * Driver column names back to Prisma field names, so the error reads in the\n * caller's vocabulary. A column with no matching field is reported as-is rather\n * than dropped: it is still the truest thing we know about the failure.\n */\nfunction fieldsForColumns(\n schema: ModelSchema,\n columns: readonly string[],\n): string[] {\n return columns.map((column) => {\n for (const field of Object.values(schema.fields)) {\n if (field.column === column) return field.name;\n }\n return column;\n });\n}\n\n/**\n * Re-reads the `_count` for rows whose children were written by an `after` step.\n *\n * One read per row rather than one for all of them, and that is not a\n * concession: every write that can carry both a `_count` and an `after` step is\n * a single-row operation — `create`, `update`, `upsert`. `createMany` takes no\n * `include` at all. So the loop runs once, and writing it as a loop keeps a\n * compound primary key expressible without an `in` list over tuples.\n *\n * **Pre-scoped, deliberately.** `effective` has already been through this\n * model's policies and `applyNestedPolicies` has already scoped the `_count`\n * node, so re-applying them would `AND` the same predicate twice — the same\n * rows, a different plan key. This is the same reasoning `delete`'s read-first\n * path uses, a few hundred lines up.\n */\nasync function recountAfterSteps(\n schema: ModelSchema,\n model: typeof Model,\n effective: any,\n rows: Record<string, unknown>[],\n options: unknown,\n): Promise<void> {\n const node = effective?.include?._count ?? effective?.select?._count;\n if (node === undefined || rows.length === 0) return;\n\n for (const row of rows) {\n // **Every component present, or nothing.** What the plan guarantees is on\n // the row is the *link* field — `planForeignSide` pushes `link.parentField`\n // into `keyFields`, which is the column the relation `references`, and that\n // is the primary key only by convention. Declare a relation\n // `references: [publicId]`, ask for `select: { email, _count }`, and `id` is\n // simply not there.\n //\n // The failure that would produce is the bad kind. `compileWhere` drops\n // `undefined` keys, so a `where` built entirely from missing components\n // compiles to **no predicate at all**:\n //\n // findFirst({ where: { id: undefined } }) -> select … from \"User\" limit ?\n //\n // — an arbitrary row, whose count is a plausible number rather than an\n // error. So an incomplete key means the projected value stands, which is\n // the same answer this already gives for a missing row: stale, not\n // invented. Nothing here can be salvaged by guessing.\n const where: Record<string, unknown> = {};\n let identified = schema.primaryKey.length > 0;\n for (const field of schema.primaryKey) {\n const value = row[field];\n if (value === undefined) {\n identified = false;\n break;\n }\n where[field] = value;\n }\n if (!identified) continue;\n\n const fresh = (await (model as any).$exec(\n \"findFirst\",\n { where, select: { _count: node } },\n markPreScoped({ strategy: (options as any)?.strategy }),\n )) as Record<string, unknown> | null;\n\n // `null` only if the row vanished between the write and this read, which\n // inside the write's own transaction it cannot. Leaving the projected value\n // alone is still the right fallback: it is stale, not invented.\n if (fresh && fresh._count !== undefined) row._count = fresh._count;\n }\n}\n\nfunction rowsOf(result: unknown): Record<string, unknown>[] {\n if (Array.isArray(result)) return result as Record<string, unknown>[];\n if (result === null || result === undefined) return [];\n if (typeof result !== \"object\") return [];\n return [result as Record<string, unknown>];\n}\n\n/**\n * Splits a `createMany` that would exceed the driver's parameter ceiling, or\n * returns `null` when it fits.\n *\n * The ceiling is enforced in `render`, so the only way to learn that a call is\n * too large is to try compiling it. That is deliberate rather than lazy: a size\n * check ahead of every write would cost every write, and the plan cache means\n * the compile is paid once per shape anyway.\n *\n * The chunk size comes from **binding one row**, not from dividing the reported\n * total. Division looks equivalent and is not: `required` includes whatever the\n * statement binds besides the rows, so on a shape with any fixed overhead it\n * understates the per-row cost and produces a chunk that is still too large.\n * Binding a single row asks the compiler the question directly.\n */\nfunction chunkedCreateMany(\n schema: ModelSchema,\n args: any,\n dialect: SqlDialect,\n strategy: RelationStrategy,\n op: Operation,\n): unknown[][] | null {\n const rows = args.data as unknown[];\n if (rows.length < 2) return null;\n\n try {\n getOrCompile(schema, op, args, dialect, strategy);\n return null;\n } catch (error) {\n if (!(error instanceof ParameterLimitError)) throw error;\n\n const single = { ...args, data: [rows[0]] };\n const perRow = getOrCompile(schema, op, single, dialect, strategy).bind(\n single,\n createBindContext(),\n ).length;\n\n // One row on its own over the ceiling is not a chunking problem — no split\n // can help, and the original error says the useful thing.\n if (perRow === 0 || perRow > error.limit) throw error;\n\n const size = Math.floor(error.limit / perRow);\n const chunks: unknown[][] = [];\n for (let at = 0; at < rows.length; at += size) {\n chunks.push(rows.slice(at, at + size));\n }\n return chunks;\n }\n}\n\n/**\n * Whether an `upsert` has to become a read and a write.\n *\n * True exactly when `create` leaves part of the conflict key unset, which is the\n * case `on conflict` cannot express — the insert could never collide on the\n * target, so the update branch would be unreachable.\n *\n * A `where` that names no unique key, or names several, is not this function's\n * to report: it returns false and lets the ordinary path raise the error it\n * already has for that, with the message it already has.\n */\nfunction findThenWrite(schema: ModelSchema, args: any, op: Operation): boolean {\n try {\n const key = matchUniqueKey(schema, args?.where, {\n model: schema.name,\n operation: op,\n argument: \"where\",\n });\n return upsertAbsentConflictKey(schema, args, key).length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Runs a folded relation's own `redact` over the rows the strategy inlined, and\n * then its descendants' over theirs.\n *\n * Only for a plan carrying `root` — a batched child came back through its own\n * `$exec` and has already redacted itself, and doing it twice is harmless but\n * pointless. Only outside `asSystem`, like every other policy.\n *\n * **Recursive, because the fold is.** A lateral node folds its whole subtree into\n * one statement, so a grandchild's rows never enter its model's `$exec` either —\n * and stopping at depth 1 would leave exactly the rows nobody thinks to check\n * unredacted. `RootContribution.folded` is the shape of what was folded, which is\n * the only thing that makes the walk possible.\n *\n * The child's policies are resolved through the registry by name, so this obeys\n * the same rule every nested read does: whatever is registered under that name\n * is the class whose policies apply.\n */\nfunction redactFolded(\n relation: { as: string; model: string; folded?: readonly FoldedRelation[] },\n result: unknown,\n op: Operation,\n system: boolean,\n): void {\n const target = registry.has(relation.model)\n ? registry.get<unknown>(relation.model)\n : undefined;\n const policies = target ? policiesFor(target) : [];\n const nested = relation.folded ?? [];\n\n if (policies.length === 0 && nested.length === 0) return;\n\n const context =\n policies.length > 0\n ? policyContext(\n (target as { $schema?: { name?: string } }).$schema?.name ??\n relation.model,\n op,\n currentUser(),\n system,\n )\n : undefined;\n\n // Collected whether or not *this* level redacts anything: an unpolicied model\n // in the middle of the tree must not hide a policied one below it.\n const children: Record<string, unknown>[] = [];\n\n for (const parent of rowsOf(result)) {\n const rows = parent?.[relation.as];\n if (rows === undefined || rows === null) continue;\n if (context) applyRedaction(policies, context, rows);\n if (nested.length > 0) children.push(...rowsOf(rows));\n }\n\n for (const child of nested) redactFolded(child, children, op, system);\n}\n",
|
|
30
30
|
"import { Model } from \"./Model\";\nimport type { QueryPlan } from \"./plan\";\n\n/**\n * Every query returns instances, achieved **purely** by overriding `$shape`.\n *\n * This is iteration 8's deliverable 4, and its job is to prove invariant 3 was\n * worth holding: `$shape` is a static on the model base rather than a\n * module-level function, so a subclass can change what a query *returns* without\n * any operation knowing. If that had required touching an\n * operation, it would have been a design defect to fix while the cost was still\n * small.\n *\n * It did not. The whole tier is the method below.\n *\n * class Post extends ActiveRecordModel {\n * static $schema = schema.Post\n * get excerpt() { return this.body.slice(0, 100) }\n * }\n *\n * const posts = await Post.findMany({}) // Post instances\n * posts[0].excerpt\n * await posts[0].save()\n *\n * **Shipped as a documented example, not a supported tier.** Two reasons, and\n * neither is effort:\n *\n * 1. It reintroduces the conflict `wrap` exists to avoid. Queries hydrate\n * unconditionally here, so `select: { id: true }` produces an instance whose\n * methods can read fields the query never fetched — a runtime crash the type\n * system cannot see, because the operations' return types still describe\n * plain narrowed payloads. `wrap` requires a complete row precisely so that\n * cannot happen; this trades that guarantee for ergonomics.\n * 2. The return *types* do not change. `findMany` is still typed as returning\n * `Prisma.PostGetPayload<T>[]`, so the instance methods are invisible to\n * TypeScript at the call site even though they are there at runtime. Fixing\n * that means conditional return types across every operation, which is\n * exactly the complexity the POJO baseline was chosen to avoid.\n *\n * So this file is evidence that the seam works, and a warning about what using\n * it costs. If the tier is ever pursued properly it needs its own plan — see the\n * out-of-scope section of `plans/orm/08-eloquent-doorway.md`, which is explicit\n * that half an identity map is worse than none.\n */\nexport abstract class ActiveRecordModel extends Model {\n /**\n * The one override. `plan.shape` still does all the work — decoding, key\n * mapping, relation placeholders — and this only decides what the resulting\n * data is *carried in*.\n *\n * Note what is not here: no per-operation branching, no knowledge of which of\n * the operations is running, and no second code path for writes. A\n * `count` returns a number and an `updateMany` returns `{ count }`; both fall\n * through untouched because they are not rows.\n */\n static override $shape(plan: QueryPlan, rows: unknown[]): unknown {\n const shaped = plan.shape(rows);\n\n if (Array.isArray(shaped)) {\n return shaped.map((row) => this.hydrate(row));\n }\n\n // A single-row operation shapes to `null` when nothing matched, and a\n // counting one to `{ count }`. Neither is a row, and hydrating either would\n // be the kind of special case this override exists to show is unnecessary.\n if (shaped === null || typeof shaped !== \"object\") return shaped;\n if (\"count\" in (shaped as object)) return shaped;\n\n return this.hydrate(shaped);\n }\n\n /**\n * Builds one instance. Separate so a subclass can decide what hydration means\n * — a value object per column, a lazily-decoded field — without reimplementing\n * the shape dispatch above.\n *\n * Goes through `Model.wrap`, so an instance from a query is tracked exactly as\n * one from `wrap` is and `save()` works on it. That reuse is the point: there\n * is one definition of \"a row became an instance\".\n */\n protected static hydrate(row: unknown): unknown {\n if (row === null || typeof row !== \"object\") return row;\n return (this as unknown as typeof Model).wrap(row as object);\n }\n}\n",
|
|
31
31
|
"import { UnsupportedQueryError } from \"./errors\";\nimport type { ModelPolicy } from \"./policy\";\n\n/**\n * Soft deletes, as a policy.\n *\n * This ships as a small built-in because it is the proof that the policy hook is\n * expressive enough to be worth having: hiding deleted rows from *every* read\n * including nested ones, and turning a `delete` into an `update`, is the thing\n * ORMs traditionally implement as a special case threaded through the query\n * builder. Here it is thirty lines against the same `ModelPolicy` interface an\n * application writes, with no privileged access to anything.\n *\n * Usage — `deletedAt` must be a nullable `DateTime` on the model:\n *\n * export class User extends UserModel {\n * static $policies = [softDeletes<typeof User>()]\n * }\n *\n * `typeof User` rather than `User`: the class carries `$schema`, which is what\n * constrains `field` to real columns (#262). The instance spelling still\n * compiles and simply checks nothing.\n *\n * await User.findMany({}) // deleted rows are not there\n * await User.expire({ where }) // sets deletedAt, does not remove the row\n *\n * **`User.delete()` is still a hard delete**, and cannot be made otherwise —\n * see the note on #263 above `softDelete` below. The policy scopes reads; it is\n * the wrapper that rewrites a write, and the wrapper cannot be named `delete`.\n *\n * Composing it with a policy of your own is now just a longer list, in the order\n * they should apply:\n *\n * static $policies = [softDeletes<typeof User>(), new TenantPolicy()]\n *\n * That ordering is the author's, and within a class it is the array's. Across\n * classes `policiesFor` still walks base to derived, so a `$policies` on a\n * shared base is applied before a subclass's and can only be narrowed further.\n *\n * It stays a **factory** rather than a class because it takes configuration and\n * a model type parameter, and a bare constructor in a `$policies` array has\n * nowhere to put either. `PolicyEntry` accepts both forms for exactly this\n * reason.\n */\n\n/**\n * The column names a model *class* declares, read off its generated `$schema`.\n *\n * This is the part of #262 that made it worth doing. The old constraint was\n * `keyof M & string` against an **instance** type, which is not a column check:\n * `softDeletes<User>({ field: \"save\" })` compiled clean and then raised\n * `UnknownFieldError` at runtime, because `save` is a method. Reading\n * `$schema.fields` instead asks the schema what the columns are, so the check\n * and the runtime error now disagree about nothing.\n *\n * It works because the generator emits `satisfies ModelSchema` rather than a\n * `: ModelSchema` annotation — see `bin/orm/emit.ts`. An annotation would widen\n * `fields` to `Record<string, FieldSchema>` and `keyof` it back to `string`.\n *\n * **Falls back to `string` rather than to `never`.** A caller can pass anything\n * that behaves like a model — the structural fakes in `soft-deletes.test.ts` do\n * — and those carry no literal schema. Degrading to unchecked keeps them\n * working; degrading to `never` would reject every `field` they pass.\n */\nexport type SchemaFields<M> = M extends { $schema: { fields: infer F } }\n ? Extract<keyof F, string> extends never\n ? string\n : Extract<keyof F, string>\n : string;\n\n/**\n * The row a model class describes, so one type parameter can carry both.\n *\n * `softDeletes` hands its parameter to `ModelPolicy`, which uses it as the\n * **row** type — `redact` is called with a `Partial` of it. The schema, though,\n * hangs off the *class*. Taking the class and recovering the row through\n * `prototype` is what lets one spelling supply both, and it is the mechanism\n * #243 found and recorded rather than a new invention.\n *\n * An instance type has no `prototype`, so `softDeletes<User>()` still resolves\n * to `User` and keeps compiling — it simply gets no field checking, because an\n * instance type is not where the column names live.\n */\ntype RowOf<M> = M extends { prototype: infer Row } ? Row : M;\n\n/**\n * **The parameter is still the model type, not the field union.**\n *\n * `SoftDeleteOptions` is exported, so an application can annotate with it —\n * `const opts: SoftDeleteOptions<User> = …`. Constraining the parameter to\n * `extends string` and taking the union directly read more honestly from inside\n * this file and broke every such annotation from outside it, with *\"Type 'User'\n * does not satisfy the constraint 'string'\"*. Keeping the model type and\n * resolving the union here costs nothing and keeps those compiling: a row type\n * has no `$schema`, so it degrades to `string` exactly as it did before, and\n * `SoftDeleteOptions<typeof User>` is the spelling that gains the check.\n */\nexport interface SoftDeleteOptions<M = any> {\n /**\n * The timestamp column. Defaults to `deletedAt`, which the template uses.\n *\n * Constrained to the model's **schema fields** when the model is reachable —\n * `softDeletes<typeof User>()`, `softDelete(User)`, `softDeleteMany(User)` —\n * so a typo, or a column the model does not have, is a compile error instead\n * of an `UnknownFieldError` on the first read.\n *\n * Passing no model leaves it `string`, and therefore unchecked. That is the\n * one spelling that cannot be constrained: there is nothing to constrain it\n * against.\n */\n field?: SchemaFields<M>;\n}\n\n/**\n * The read half: every query is scoped to rows whose delete timestamp is null.\n *\n * It applies to nested relation reads for the same reason every policy does —\n * a relation read is `$exec` on the related model — which is the half that\n * ORM-level soft deletes usually get wrong. A deleted `Account` does not appear\n * under `User.findMany({ include: { accounts: true } })` without anything being\n * written at the include site.\n */\nexport function softDeletes<M = any>(\n options: SoftDeleteOptions<M> = {},\n): ModelPolicy<any, any, RowOf<M>> {\n const field = options.field ?? \"deletedAt\";\n\n return {\n scope: () => ({ [field]: null }),\n\n // A soft-deleted model still creates ordinary rows; the column is left to\n // its own default (null). Present because a policy carrying `scope` with no\n // `onCreate` is refused — deliberately, since for a tenant scope that\n // combination is a half-written policy. Here the pass-through *is* the\n // correct behaviour, so it is stated rather than implied.\n onCreate: (_context, data) => data,\n\n // The same statement for updates, and here it is doing real work rather than\n // satisfying a formality. This policy scopes on `deletedAt`, and\n // `softDelete()` below turns a delete into an update that *writes*\n // `deletedAt` — which is precisely the \"an update moves a row out of the\n // scope that selected it\" shape `ScopeEscapeError` refuses. It is also\n // exactly what soft deleting means, so this policy is the one that gets to\n // say the write is intended.\n //\n // Note it does not authorise anything else: the guard is per policy, so a\n // tenant policy sitting beside this one in `$policies` still has to answer\n // for its own column. That separation is the point of the per-policy check.\n onUpdate: (_context, data) => data,\n };\n}\n\n/**\n * What `softDelete` needs from the model it wraps: the write to delegate to,\n * and the schema to name in a refusal.\n *\n * Structural rather than `typeof Model`, so a caller can pass anything that\n * behaves like one — which is why `$schema` is optional here even though every\n * generated model has it.\n */\ntype SoftDeletable<T, Op extends string> = {\n [K in Op]: (args: any) => Promise<T>;\n} & { $schema?: { name: string } };\n\n/**\n * The write half: rewrites a `delete` into an `update` that sets the timestamp.\n *\n * Kept separate from `softDeletes()` and applied at the call site rather than\n * folded into the policy, because a policy rewrites *arguments* and this\n * changes the *operation* — and `$exec` dispatches on the operation before a\n * policy is consulted. Widening `ModelPolicy` to let a policy swap the\n * operation would make every `$exec` call's meaning depend on a hook, which is\n * a much larger claim than scoping a `where`.\n *\n * export class User extends UserModel {\n * static $policies = [softDeletes<typeof User>()]\n * static expire = softDelete(User)\n * static expireMany = softDeleteMany(User)\n * }\n *\n * **The name is not `delete`, and cannot be** — the reason is below.\n * `User.delete()` stays a hard delete.\n *\n * Both return the row(s) the way the real operations do, and both are still\n * subject to the model's policies, because they go through `update` /\n * `updateMany` — which means the soft-delete scope applies and a\n * `expire({ where })` naming an already-deleted row finds nothing, exactly as\n * a hard delete of a missing row would.\n *\n * Why this does not return the generated `delete`'s own signature — #263.\n *\n * `static delete = softDelete(User)` is the recipe the docs used to teach, and\n * it does not type-check. The obvious repair is to have this return the model's\n * own `delete` type so the override is assignable to what it overrides. That\n * cannot work, and the reason is the language rather than the typing:\n *\n * static delete = softDelete(User)\n * // ^ the type of this member would be read off `User`...\n * // ^ ...whose `delete` is the member being defined\n *\n * TypeScript answers `TS7022: 'delete' implicitly has type 'any' because it\n * does not have a type annotation and is referenced directly or indirectly in\n * its own initializer.` Annotating it does not help either: the annotation has\n * to name `typeof UserModel.delete`, and `softDelete(User)` is then checked\n * against a generic signature it still cannot satisfy.\n *\n * Passing the *base* instead of the subclass would break the cycle and break\n * the feature: `softDelete` delegates to `model.update`, policies are resolved\n * per registered class, and `UserModel` carries none — so the soft-delete scope\n * would not apply and `delete` would hide rows it never filtered.\n *\n * So the recipe changed instead of the types, and `delete` stays a hard delete.\n * `docs/orm.md` says so in the words a reader needs, and\n * `soft-delete.test-d.ts` holds the documented snippet verbatim so it cannot\n * drift back.\n \n */\nexport function softDelete<T, M = any>(\n model: SoftDeletable<T, \"update\"> & M,\n options: SoftDeleteOptions<M> = {},\n): (args: any) => Promise<T> {\n const field = options.field ?? \"deletedAt\";\n\n return (args: any) => {\n assertNoData(model, args, \"delete\");\n return model.update({\n ...args,\n data: { [field]: new Date() },\n });\n };\n}\n\nexport function softDeleteMany<T, M = any>(\n model: SoftDeletable<T, \"updateMany\"> & M,\n options: SoftDeleteOptions<M> = {},\n): (args: any) => Promise<T> {\n const field = options.field ?? \"deletedAt\";\n\n return (args: any = {}) => {\n assertNoData(model, args, \"deleteMany\");\n return model.updateMany({\n ...args,\n data: { [field]: new Date() },\n });\n };\n}\n\n/**\n * A `delete` takes no `data`, so one being present means the caller thinks they\n * are calling something else — most likely they wrote `update` and meant it.\n * Refused rather than silently overwritten by the timestamp.\n */\nfunction assertNoData(\n model: { $schema?: { name: string } },\n args: any,\n operation: string,\n): void {\n if (args?.data === undefined) return;\n\n throw new UnsupportedQueryError(\n \"data\",\n // The real model, not the literal `\"soft delete\"` this used to pass.\n // `UnsupportedQueryError` documents `model` as inspectable, and a string\n // that is not a model name can never be what an application matches on\n // (#112). `$schema` is optional only because the parameter is structural —\n // every generated model carries it.\n model.$schema?.name ?? \"unknown\",\n operation,\n `${operation} takes no 'data' — the soft-delete rewrite supplies it. ` +\n `Call update directly if you meant to change other fields at the same ` +\n `time.`,\n );\n}\n",
|
|
32
32
|
"/**\n * `take` / `skip` built from a request, so that a query string cannot produce a\n * value the compiler refuses.\n *\n * **This file is not `compile/paginate.ts`, and the two do opposite jobs.** That\n * one is the compiler's *validator*: `assertPageArgument` refuses a `take` or a\n * `skip` that is not an integer, and its note explains at length why refusing is\n * the only honest answer — a fraction is an opaque `SQLITE_MISMATCH` on one\n * dialect and a silent disagreement with both Prisma and the other dialect on\n * the second. Read that note (`compile/paginate.ts:9-63`) for the reasoning; it\n * is not restated here.\n *\n * This file is the other half, and the half that was missing. A refusal is only\n * useful if the correct spelling is available and short — otherwise the fix a\n * caller reaches for is `Math.floor` sprinkled at whichever call site happened\n * to throw, which fixes one of them. `paginate` is the shorter spelling:\n *\n * const { take, skip } = paginate({\n * page: req.search.get(\"page\"),\n * perPage: req.search.get(\"perPage\"),\n * })\n * await Post.findMany({ take, skip, orderBy: { createdAt: \"desc\" } })\n *\n * against the shape gemi's own documentation used to teach, which breaks:\n *\n * const limit = Number(req.search.get(\"limit\")) || 25 // ?limit=1.5\n *\n * **Why the arguments are `unknown` and not `number`.** A query string is where\n * these values come from — that is the entire point of the helper, and typing\n * them as `number` would mean every caller writes the `Number(...)` that is the\n * bug. `req.search.get` hands back `string | string[]` (`http/HttpRequest.ts:211-223`\n * collects repeated keys into an array), a JSON body hands back whatever was\n * sent, and both arrive here unconverted.\n *\n * **The coercions, measured rather than assumed.** Each of these is a shape a\n * real query string produces, and each one is why the rules below are not simply\n * `Number(...)`:\n *\n * Number(\"\") 0 `?perPage=` — a form's blank field\n * Number(\" \") 0 the same, url-encoded\n * Number(null) 0 an absent key read off a plain object\n * Number([\"2\"]) 2 a single repeated key\n * Number([\"1\",\"2\"]) NaN two of them — so `Number` honours a\n * repeated param sometimes and not others\n * Number(\"1e400\") Infinity not a number `Math.trunc` can fix\n * Number(true) 1\n *\n * The `0`s are the dangerous ones. `page: 0` computes `skip: -25`, and\n * `assertPageArgument` refuses a negative `skip` outright — so a blank field in\n * a form is a 500. `perPage: 0` is worse, because it is *not* refused: `take: 0`\n * is a perfectly good integer and returns an empty page for ever.\n *\n * So an empty or blank string means **absent**, not zero, and anything that is\n * not a number or a string is absent too. Coercing a boolean or a one-element\n * array would be honouring input no HTTP surface can actually send, at the cost\n * of the rule being explainable.\n *\n * **Why `skip` is capped.** `?page=1e300` is finite, so it survives every check\n * above and multiplies out to a `skip` of `2.5e301`. Measured through Bun\n * against SQLite, binding an offset past int64:\n *\n * offset 1e18 -> ok\n * offset 9223372036854775807 -> SQLiteError: datatype mismatch\n * offset 1e20 -> SQLiteError: datatype mismatch\n *\n * — the same `SQLITE_MISMATCH` the fractional-`take` note records, reached from\n * the other end. The cap is `Number.MAX_SAFE_INTEGER` rather than int64's\n * ceiling: it is well inside what both drivers bind, it needs no per-dialect\n * measurement, and above it JavaScript's own arithmetic stops being exact, so a\n * number past it was never a page anybody could count to.\n *\n * **The guarantee, which is the whole contract:** every return value is a pair\n * of integers with `take >= 1` and `skip >= 0`, for every input. It is therefore\n * impossible for `paginate`'s output to be something `assertPageArgument`\n * refuses, and `page-args.test.ts` asserts exactly that by running the validator\n * over the output of a table of hostile query-string values rather than by\n * re-checking the arithmetic.\n */\n\n/**\n * The default page size, and it is not an invented number: `docs/controllers.md`\n * and `docs/routing.md` both taught `Number(req.search.get(\"limit\")) || 25`. The\n * helper replaces those examples, and picking a different default would silently\n * change the page size of every call site rewritten onto it.\n */\nconst DEFAULT_PER_PAGE = 25;\n\n/**\n * The ceiling on a *request-supplied* page size. Its job is that `?perPage=100000`\n * cannot ask for the whole table — one request that reads a million rows into\n * memory is a denial of service the caller did not have to authenticate for.\n *\n * A hundred rather than \"no ceiling at all\", because a helper whose ceiling is\n * opt-in has no ceiling in the code that most needs one. An endpoint that\n * genuinely serves larger pages says so at the call site — `paginate(args,\n * { maxPerPage: 500 })` — which is one visible decision instead of an invisible\n * default.\n */\nconst DEFAULT_MAX_PER_PAGE = 100;\n\n/**\n * See the cap discussion above. Exported so the test can assert the boundary\n * against the same constant the implementation clamps to, rather than repeating\n * the literal and agreeing with itself.\n */\nexport const MAX_SKIP = Number.MAX_SAFE_INTEGER;\n\n/**\n * A query-string value as a whole number, or `null` for \"absent\".\n *\n * `null` rather than a default, so the two callers below can apply *their* own\n * default — the page defaults to 1 and the size defaults to `perPage`, and\n * folding that in here would mean one of them lying about which.\n */\nfunction toWholeNumber(value: unknown): number | null {\n if (typeof value === \"string\") {\n // Measured above: `Number(\"\")` is 0. `?perPage=` is what a browser sends\n // for a blank field, and reading it as zero rather than as absent is how a\n // cleared filter box becomes an empty page.\n if (value.trim() === \"\") return null;\n } else if (typeof value !== \"number\") {\n // Arrays, objects, booleans, `null`, `undefined`. Every one of them has a\n // `Number()` answer and not one of them has a *meaning* — see the table.\n return null;\n }\n\n const parsed = Number(value);\n // Catches `NaN` and both infinities in one test, which is what `Math.trunc`\n // cannot do: `Math.trunc(Infinity)` is `Infinity`, and `Number.isInteger`\n // then says false, so an untruncatable value would reach the compiler and be\n // refused there — by this helper, which exists so that cannot happen.\n if (!Number.isFinite(parsed)) return null;\n\n // Toward zero, which is what Prisma does with a fractional `take` (measured\n // in `compile/paginate.ts`). Matching it means a caller who moves off Prisma\n // keeps the same page, rather than trading a crash for a different answer.\n return Math.trunc(parsed);\n}\n\nconst clamp = (value: number, low: number, high: number) =>\n Math.min(Math.max(value, low), high);\n\n/**\n * Turn `{ page, perPage }` — as read off a query string, in whatever state the\n * client left them — into a `take` / `skip` pair the ORM accepts.\n *\n * paginate({ page: \"2\" }) { take: 25, skip: 25 }\n * paginate({ page: \"2.5\" }) { take: 25, skip: 25 }\n * paginate({ page: \"0\" }) { take: 25, skip: 0 }\n * paginate({ page: \"abc\" }) { take: 25, skip: 0 }\n * paginate({ perPage: \"1000\" }) { take: 100, skip: 0 }\n * paginate({ perPage: \"10\" }, { maxPerPage: 5 }) { take: 5, skip: 0 }\n */\nexport function paginate(\n args: { page?: unknown; perPage?: unknown },\n options: {\n /** The page size when the request does not name one. Default 25. */\n perPage?: number;\n /** The largest page size a *request* may ask for. Default 100. */\n maxPerPage?: number;\n } = {},\n): { take: number; skip: number } {\n // The options are code rather than user input, so it is tempting to trust\n // them. They are clamped anyway, because the guarantee this function makes is\n // unconditional — `paginate(args, { perPage: 0 })` returning `take: 0` would\n // be an empty page for ever, with the helper's own name on it.\n //\n // `Infinity` is honoured rather than rejected, and it is the one place the\n // options are read differently from the arguments. `toWholeNumber` refuses a\n // non-finite value because that rule is about hostile input — `?perPage=1e400`\n // is `Infinity`, and binding it as a `take` is not a page size. Reusing the\n // same rule here made `{ maxPerPage: Infinity }`, the natural spelling of \"no\n // ceiling\", fall back to the default 100 instead: an internal export written\n // to opt out of the cap silently got it back, returned a plausible first page,\n // and was found when somebody noticed 900 rows missing. The caller who writes\n // `Infinity` here is the application, saying so deliberately.\n const maxPerPage =\n options.maxPerPage === Infinity\n ? Infinity\n : Math.max(1, toWholeNumber(options.maxPerPage) ?? DEFAULT_MAX_PER_PAGE);\n const fallback = clamp(\n toWholeNumber(options.perPage) ?? DEFAULT_PER_PAGE,\n 1,\n maxPerPage,\n );\n\n const perPage = clamp(toWholeNumber(args?.perPage) ?? fallback, 1, maxPerPage);\n\n // Page 1 is the first page, and there is no page 0 — a `page` below 1 is\n // clamped up rather than refused, because the values that land there are\n // `\"\"`, `\"0\"` and `\"-1\"`, and none of them is a request for a page that does\n // not exist. Refusing would put a 500 on a link somebody edited by hand.\n const page = Math.max(toWholeNumber(args?.page) ?? 1, 1);\n\n // Clamped after multiplying rather than by bounding `page` first: the product\n // is the thing that has to stay exact, and `page` alone cannot be bounded\n // without knowing `perPage` anyway.\n const skip = Math.min((page - 1) * perPage, MAX_SKIP);\n\n return { take: perPage, skip };\n}\n"
|
|
33
33
|
],
|
|
34
|
-
"mappings": "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",
|
|
35
|
-
"debugId": "
|
|
34
|
+
"mappings": "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",
|
|
35
|
+
"debugId": "139511E06900414B64756E2164756E21",
|
|
36
36
|
"names": []
|
|
37
37
|
}
|