Repository navigation
Conversation
Correlated EXISTS / NOT EXISTS conditions and a correlated count(*) over a declared relation, on the builder (Db.related) and in findMany's where. findMany's _count counts a many relation with one grouped statement per level. A subquery that correlates on the outer tenant column takes that column's tenant binding.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 15 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
findManyand the builder cannot filter rows by their related rows or count related rows. Prisma code uses_countandsome/every/nonea lot, and Drizzle needs raw SQL for most of them.Closes #80.
Part of #52.
Depends on #110; review only the commits after it.
Changes
Db.related(schema.table, $)gives the relations of a table on the$of a builder query. Each relation hassome(where?),none(where?),every(where)andcount(where?).someisEXISTS (…),noneisNOT EXISTS (…),everyisNOT EXISTS (… AND NOT (where)). The subquery reads the target under the alias<outer alias>__<relation>, so a self-relation works. Filters nest: thewhereof a filter gets its ownr.count(where?)is anExpr<number>:coalesce((SELECT count(*) …), 0). It works in aselectand in awhere.findMany'swhere(at every level) gets the same object as its second argument:where: ($, r) => [r.posts.some()]._count: { posts: true | { where } }infindManyadds_count: { posts: number }to the rows of that level. It keeps feat(database): relational reads with defineRelations and findMany #110's loading model: one grouped statement per counted relation,SELECT <to>, count(*) … WHERE <to> IN (<keys>) GROUP BY <to>, with the same tenant pin as a loaded level. Onlymanyrelations can be counted (type error otherwise).<inner tenant> = <outer tenant>. A small change incompile.tsgives such a subquery the binding of the outer tenant column, so a filter under$.orgId.eq("a")stays"single-tenant". Only the relation filters set this internal mark, and they always write the equality. A filter does not scope an unscoped outer query. A filter from an untenanted table into a tenanted one is"cross-tenant"unless its ownwherepins the tenant.QueryBuilderDefect, so it never correlates a column to itself.docs/relations.md, section 6 indesign/relations.md,docs/reference.md, one changeset.ClickHouse (tested live on 26.8.2.7)
some,none,every, and nested filters work (correlated subqueries are on by default in 26.8).count()in awhereworks.count()in aselectnext to awhereworks only when the outer columns it correlates on are selected too. Otherwise ClickHouse fails withNOT_IMPLEMENTED("can't find correlated column … in current header"). The docs say this, and the test selects the key and tenant columns.count()over no rows returns NULL on ClickHouse, not 0. Thecoalescehandles it._countinfindManyneeds no correlation, so it works on every version.Left out
_countof aonerelation:r.author.some()says the same.update/delete: their accessor is not qualified, so there is no alias to correlate on. Refused with a defect.orderBy: { posts: { _count: "desc" } }). On a builder query, selectcount()and order by its alias.EXISTSandcount(*), so no dialect work is expected.Validation
Run on the head commit against a live ClickHouse 26.8.2.7 (the CI matrix version), with
EFFECT_ORM_CLICKHOUSE_URLset, so no suite is skipped:bun run build: pass.bun run typecheck: pass.bunx vitest run --testTimeout=60000 --hookTimeout=60000: pass. Test files: 64 passed (64). Tests: 1065 passed (1065).node scripts/check-doc-citations.mjs,check-exports-documented.mjs,check-doc-examples.mjs: pass.bun scripts/check-package.ts(tarball, types, CommonJS consumer): pass.Need help on this PR? Tag
@codesmith-botwith what you need.