fix(sqlite-persistence): preserve expression index use - #1867
KyleAMathews wants to merge 11 commits into
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
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 (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthrough
ChangesSQLite expression-index planning
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The adapter emits canonical SQL literals for persisted JSON reference paths while comparison values remain bound, and the reported validation passes with no actionable merge-blocking risk evidenced. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
🛠️ Fix failing CI checks 💡
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 |
…ion-index-oracle # Conflicts: # docs/contributing/oracle-coverage.md
More templates
@tanstack/angular-db
@tanstack/browser-db-sqlite-persistence
@tanstack/capacitor-db-sqlite-persistence
@tanstack/cloudflare-durable-objects-db-sqlite-persistence
@tanstack/db
@tanstack/db-ivm
@tanstack/db-sqlite-persistence-core
@tanstack/electric-db-collection
@tanstack/electron-db-sqlite-persistence
@tanstack/expo-db-sqlite-persistence
@tanstack/node-db-sqlite-persistence
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/react-native-db-sqlite-persistence
@tanstack/react-router-with-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/tauri-db-sqlite-persistence
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +507 B (+0.3%) Total Size: 170 kB 📦 View Changed
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 7.34 kB ℹ️ View Unchanged
|
…ion-index-oracle # Conflicts: # docs/contributing/oracle-coverage.md # packages/db-sqlite-persistence-core/src/index.ts # packages/db-sqlite-persistence-core/src/persisted.ts # packages/db-sqlite-persistence-core/src/sqlite-core-adapter.ts
Persisted SQLite queries can now use the expression indexes that their collection configuration creates. Previously, queries returned expected rows while SQLite scanned the collection table.
Index DDL stored JSON paths as SQL literals. Runtime predicates bound the same paths as parameters. SQLite did not treat these forms as one expression.
This change gives index DDL and runtime predicates one canonical expression shape. It also rebuilds stale physical indexes after compiler output changes.
Why SQLite missed the index
The index and the old predicate could use the same path and return the same rows:
SQLite matches expression indexes by SQL structure. A parameter that contains
$.profile.scoredoes not match the literal path in the index definition.The compiler now emits the validated path as a canonical SQL literal:
json_extract(value, '$.profile.score')Ordinary comparison values remain parameters. Scalar BigInt targets become validated SQL integers when SQLite needs that numeric expression shape.
How the change works
CASEandjson_extractexpressions.sourceAliasmetadata distinguishes qualified references from legacy nested property paths.PropRef.pathvalues keep their prior meaning. The compiler does not guess that a nested path contains an alias.This keeps strings, dates, booleans, numbers, and
INlist values bound. Compiler-owned paths and index constants use validated literals.Oracle coverage
The Node oracle uses the public SQLite-core adapter with the real BetterSQLite3 driver. It makes these observations independently:
EXPLAIN QUERY PLAN.The same property, generators, observations, and eight-run budget run in fixed-seed and seedless-random campaigns. A seed and shrink path select one exact replay.
The generated grammar covers equality, normal
IN, 901-value batchedIN, ranges, conjunctions, ordering, andlower(ref). Each axis has an ablation and a plausible wrong-answer control.Deterministic cases cover index upgrades, constant-bearing expressions, aliases, legacy nested paths, dates, and signed 64-bit BigInts. Separate controls expose row-only false greens and the former bound-path behavior.
Exact replay:
Scope boundaries
Implementation trailhead
Verification
@tanstack/db: 6,385 tests passed.✅ Checklist
🚀 Release Impact
Part of #1659