Commit e7ce035
authored
TML-2785: M:N slice 1 — correlated include read through the junction (#679)
Slice 1 of the **SQL ORM: Many-to-Many End to End** project ([Linear
project](https://linear.app/prisma-company/project/sql-orm-many-to-many-end-to-end-c178df40ca3a)).
Reads an M:N relation through its junction.
> **Stacked PR.** Base is `tml-2784` (#678, slice 0) → `tml-2597` (#673)
→ `tml-2729` (#667) → `main`. Review/merge bottom-up.
## Overview
`db.orm.User.include(tags)` now resolves a many-to-many relation to `{
…user, tags: Tag[] }` in a **single correlated subquery** that walks
parent → junction → target — no `LATERAL`, no second query. Built on
slice 0s `ResolvedRelation.through`.
## Changes (4 commits)
- **`fcecac5b3`** — integration fixture gains a `User ↔ Tag` M:N
relation via a `UserTag` junction (composite PK `user_id`/`tag_id`);
`contract.json`/`.d.ts` re-emitted.
- **`e587b433c`** — read path: `IncludeExpr.through` (surfaced by
`resolveIncludeRelation`), and `buildCorrelatedIncludeProjection` gains
an M:N branch — `buildManyToManyJunctionArtifacts` builds a non-LATERAL
inner join to the junction (`junction.childColumns =
target.targetColumns`) correlated to the parent (`junction.parentColumns
= parent` anchor), composite-key AND-ed; FK decode path reused.
Unit-tested at the AST level.
- **`b9c3e9f7b`** — replace 2 bare `as` casts with `castAs`; add the
missing M:N + distinct + non-leaf unit test.
- **`d3232cbad`** — 7 integration tests (PGlite).
## Integration tests (per the project standard)
Whole-row `toEqual`; 6/7 use explicit `.select(...)` (so adding a model
field wont churn assertions); **test 5 uses implicit/default selection**
(full `User` + `tags: Tag[]` shape); a **single-execution /
no-`LATERAL`** assertion; depth-2 nesting (`invitedUsers → tags`); edges
(user with no tags → `tags: []`; a tag shared by multiple users).
## Why
This is the first of the three relation-shaped M:N consumers (read /
filter / write) over slice 0s shared `through` primitive. The
correlated-only approach matches the post-TML-2729 read path (no LATERAL
to reintroduce).
## Scope / notes
Read only — filter (TML-2786) and write (TML-2787) are later slices. The
fixture is **one-directional** (`User.tags`; reverse `Tag.users`
deferred — adding it trips a latent create-overload type fragility in
unrelated mutation-defaults tests; see the projects unattended-decisions
log). Fixture re-emit used a `tsx` bypass because the CLI `contract
emit` fails on a sandbox config-load env issue — **CI `fixtures:check`
is the real golden-stability gate**; please confirm its green (or re-run
the canonical emit). Broad integration runs show pre-existing
PGlite/WASM JIT flakiness; the M:N tests pass on targeted runs.
Refs: TML-2785.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* include(...) now supports many-to-many (M:N) relationships via
junction tables, returning correct nested arrays and preserving
single-query execution.
* **Tests**
* Added unit and integration tests covering M:N includes, composite
keys, nested includes, distinct+nested scenarios, and end-to-end result
shape correctness.
* **Documentation**
* Added upgrade notes for 0.14 describing the runtime support for M:N
correlated include reads.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>1 parent dc72201 commit e7ce035
19 files changed
Lines changed: 1117 additions & 10 deletions
File tree
- packages/3-extensions/sql-orm-client
- src
- test
- projects/sql-orm-many-to-many
- skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14
- test/integration/test/sql-orm-client
Lines changed: 19 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | | - | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
297 | 298 | | |
298 | 299 | | |
299 | 300 | | |
| 301 | + | |
300 | 302 | | |
301 | 303 | | |
302 | 304 | | |
| |||
327 | 329 | | |
328 | 330 | | |
329 | 331 | | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
330 | 347 | | |
331 | 348 | | |
332 | 349 | | |
333 | 350 | | |
334 | 351 | | |
335 | 352 | | |
336 | 353 | | |
| 354 | + | |
337 | 355 | | |
338 | 356 | | |
339 | 357 | | |
| |||
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
103 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
104 | 106 | | |
105 | 107 | | |
106 | 108 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
513 | 514 | | |
514 | 515 | | |
515 | 516 | | |
| 517 | + | |
516 | 518 | | |
517 | 519 | | |
518 | 520 | | |
| |||
Lines changed: 103 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| |||
341 | 342 | | |
342 | 343 | | |
343 | 344 | | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
344 | 418 | | |
345 | 419 | | |
346 | 420 | | |
| |||
377 | 451 | | |
378 | 452 | | |
379 | 453 | | |
380 | | - | |
381 | | - | |
382 | | - | |
383 | | - | |
384 | | - | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
385 | 473 | | |
386 | 474 | | |
387 | 475 | | |
| |||
409 | 497 | | |
410 | 498 | | |
411 | 499 | | |
| 500 | + | |
412 | 501 | | |
413 | 502 | | |
414 | 503 | | |
| |||
467 | 556 | | |
468 | 557 | | |
469 | 558 | | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
470 | 563 | | |
471 | 564 | | |
472 | 565 | | |
| |||
529 | 622 | | |
530 | 623 | | |
531 | 624 | | |
| 625 | + | |
532 | 626 | | |
533 | 627 | | |
534 | 628 | | |
| |||
545 | 639 | | |
546 | 640 | | |
547 | 641 | | |
| 642 | + | |
548 | 643 | | |
549 | 644 | | |
550 | 645 | | |
| |||
614 | 709 | | |
615 | 710 | | |
616 | 711 | | |
617 | | - | |
618 | | - | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
619 | 715 | | |
620 | 716 | | |
621 | 717 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
53 | 67 | | |
54 | 68 | | |
55 | 69 | | |
| |||
58 | 72 | | |
59 | 73 | | |
60 | 74 | | |
| 75 | + | |
61 | 76 | | |
62 | 77 | | |
63 | 78 | | |
| |||
0 commit comments