feat(analytics): multi-hop relationship joins for datasets (ADR-0071)#2296
Merged
Conversation
Datasets can now group/aggregate by a field two or three to-one relationships
away (`account.owner.region`), not just one. Implements ADR-0071's remaining
gap (matrix/across was already shipped).
- spec: `include` accepts dotted relationship PATHS (≤3 hops, refined at parse);
dimension/measure `field` may be a multi-hop path. To-many is out of scope.
- compiler: resolve each path hop-by-hop into one `cube.join` per prefix; the
join alias is the path with dots → `__` (a single valid identifier — quoted
dotted identifiers are rejected by the read-scope SQL guard). `RelationshipResolver`
may now return `{ object, table }` to chain (string return stays back-compat).
Declaring `a.b` auto-adds the intermediate `a`. allowlist = every prefix alias.
- strategy: `qualifyAndRegisterJoin` registers the chain (parent→child) and the
deepest alias qualifies the column; `resolveStorageTarget` resolves the owning
object at the full path. Per-hop RLS comes for free (the scope loop iterates
every join alias).
- to-one only ⇒ no fan-out ⇒ aggregates correct with no symmetric aggregates.
- single-hop unchanged (alias no-op); 27 new/updated tests; 164 analytics tests
green; spec api-surface unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 93 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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.
Summary
Implements the remaining open gap from ADR-0071 — multi-hop joins (matrix/across was already shipped). A dataset can now group or aggregate by a field two or three to-one relationships away:
Design (per the ADR)
includeholds lookup / master_detail (child→parent) relationships, which never fan out. SoSUM/COUNTstay correct with zero symmetric-aggregate machinery. To-many traversal is explicitly out of scope.account.owner.region(dotted, self-disambiguating). The SQL alias isaccount__owner(dots →__, the Cube.js convention) because the read-scope SQL guard fail-closed-rejects dotted identifiers. Single-segment paths are unchanged ⇒ single-hop joins are byte-for-byte identical.a.bauto-includes intermediatea.Touch points
spec/src/ui/dataset.zod.tsincludepaths + ≤3-hop refine + field docsservice-analytics/dataset-compiler.tsRelationshipResolver → {object,table}; chain-resolve into per-prefix joins;joinAlias; allowlist = prefixesservice-analytics/native-sql-strategy.tsqualifyAndRegisterJoinchain;resolveStorageTargetmulti-hopTests
LEFT JOINs + per-hop RLS + prefix-allowlist enforcement).check:api-surfaceunchanged.Review notes
Touches the analytics SQL builder + RLS scoping, so I'm opening this for review rather than auto-merging. The follow-up (ADR P2 — objectui multi-hop field picker / include-path editor) is not in this PR.
🤖 Generated with Claude Code