Conversation
The optimizer copied CollectionRefs with a fresh sourceId. Since TanStack#1877 the compiler compiles the optimized subquery IR, so those copies no longer match any input and fall back to an alias lookup. When an included subquery reuses the alias, the join reads the included subquery's input and the live query returns no rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe query optimizer now preserves collection source IDs when it replaces or copies collection references. Regression tests cover includes over parent subqueries with left joins and reused or distinct aliases. ChangesCollection source identity
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change preserves collection identity during optimization and adds regression coverage for materialized includes with reused aliases. No actionable merge-blocking risk is established; merge after normal checks pass. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change restores correct source binding without showing new access to protected data. Normal query construction keeps independent sources separate. Low residual risk remains because callers can now supply identities explicitly, and externally constructed queries must preserve their uniqueness. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
🎯 Changes
Fixes a regression in 0.11.0: a live query returns no rows when a
from()subquery joins a collection under an alias that an included (materialize()/ includes) subquery reuses.Cause
git bisectbetween@tanstack/db@0.9.2and@tanstack/db@0.11.0points to #1877 (40a5aea5, "preserve pushed subquery predicates"). That change is correct, but it exposed an older problem in the optimizer:CollectionRefs withnew CollectionRefClass(collection, alias). Every copy gets a newsourceId(deepCopyFrom, both branches ofoptimizeFromWithTracking,removeRedundantFromClause).processFromandprocessJoinSourcecompiled the user's original subquery IR, so these copies were never compiled. Since fix(db): preserve pushed subquery predicates #1877 they compile the optimized IR whenever it differs from the original.sourceId, so a copy's ID matches no input. It falls back toallInputs[alias].bindSourceInputsregisters every raw source under its alias too, and the last one wins.collectCollectionSourcesvisits the included subquery after the join, soallInputs["ref"]is the included subquery's input.resolveLazySourceprefers the lexical source), and nothing reads that source anymore. The join never matches, so no parent rows are produced.The optimized IR differs only when a predicate is pushed down. With a single predicate on the nullable side of a left join, nothing is pushed, so the query only fails with two or more predicates.
Fix
CollectionRefaccepts an optionalsourceId. The optimizer's copies, which are the same lexical source, keep the original identity, so the compiled subquery reads its own input and never falls back to alias resolution.cloneQueryForPlacementstill mints fresh IDs on purpose (#1878).Tests
New cases in
tests/query/includes.test.tsundermaterialize:mainwith[], passes with this change.A related optimizer issue showed up while debugging. It's fixed separately in #1977.
✅ Checklist
pnpm test. I ran the fullpackages/dbvitest suite. Two property-test files hit the 5 s timeout on my machine, onmaintoo. With--testTimeout=120000they pass.🚀 Release Impact
🤖 Generated with Claude Code
Summary by CodeRabbit