Skip to content

test: failing tests for AND/OR queries mixing indexed and non-indexed conditions#1581

Open
kevin-dp wants to merge 4 commits into
TanStack:mainfrom
kevin-dp:test/showcase-index-optimization-or-and-bugs
Open

test: failing tests for AND/OR queries mixing indexed and non-indexed conditions#1581
kevin-dp wants to merge 4 commits into
TanStack:mainfrom
kevin-dp:test/showcase-index-optimization-or-and-bugs

Conversation

@kevin-dp

@kevin-dp kevin-dp commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds seven unit tests to collection-indexes.test.ts that assert the expected results of currentStateAsChanges for where clauses that the index optimizer currently gets wrong. All tests are written purely in terms of expected behaviour.

Mixing indexed and non-indexed conditions (e.g. length(name) > 6):

  1. OR — the result must be the union of rows matching either condition. Currently rows matched only by the non-indexed condition are missing.
  2. AND — every condition must be enforced. Currently rows failing the non-indexed condition are included.
  3. Compound range + condition on another (indexed) field — all conditions must be enforced. Currently only the range is applied.

Range boundary handling:
4. Strictest lower boundgte(age, 25) AND gt(age, 25) must reduce to age > 25 regardless of argument order. Currently the inclusive bound wins.
5. Strictest upper boundlte(age, 30) AND lt(age, 30) must reduce to age < 30. Currently the inclusive bound wins.
6. Date bounds at the same value — distinct Date instances representing the same time must be treated as equal when picking the strictest bound. (Also exercises one-sided compound ranges, which currently return an empty result.)
7. Strict comparisons on date fieldsgt(createdAt, date) must exclude the boundary row. Currently the BTree index includes it because it compares the normalized indexed value against the raw Date.

⚠️ These tests fail on main by design — they pin down the expected behaviour. The follow-up PR #1582 provides the fixes that make them pass.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added coverage to verify strict range-query boundary behavior for createdAt date fields (values equal to the boundary are excluded).
    • Expanded complex query optimization assertions for correct and/or semantics when combining indexed predicates with computed, non-indexed predicates.
    • Added edge-case tests ensuring comparisons involving missing/undefined values never return matches and align with full-scan behavior.

…d non-indexed conditions

These tests assert the expected results of currentStateAsChanges for
AND/OR where clauses that combine conditions on indexed fields with
conditions that cannot be served by an index. They currently fail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6f8b565c-abce-48ba-8548-789a78aef691

📥 Commits

Reviewing files that changed from the base of the PR and between 0dac2f8 and 029e759.

📒 Files selected for processing (1)
  • packages/db/tests/collection-indexes.test.ts

📝 Walkthrough

Walkthrough

Adds tests ensuring date gt is strict and expands Complex Query Optimization coverage with mixed indexed/computed predicate cases, overlapping-range bound tightening, equal-date-instance handling, full conjunction enforcement across fields, and comprehensive undefined value edge cases.

Changes

Complex Query Optimization & Date-bound Tests

Layer / File(s) Summary
Date gt strictness on createdAt
packages/db/tests/collection-indexes.test.ts
Verifies gt on a createdAt date field is strict and excludes rows equal to the boundary.
Mixed indexed vs computed predicate boolean ops
packages/db/tests/collection-indexes.test.ts
or(...) returns the union when one branch is index-backed and the other is a non-indexed computed predicate; and(...) enforces conjunction when mixing indexed and computed predicates.
Overlapping range bound tightening and date equality
packages/db/tests/collection-indexes.test.ts
Confirms overlapping lower (gte + gt) and upper (lte + lt) bounds apply the strictest bound at shared boundaries; distinct Date instances with identical timestamps are treated as equal for bound enforcement.
Compound range with predicate on another field
packages/db/tests/collection-indexes.test.ts
Asserts conjunction semantics when a compound range on one field is combined with a predicate on another field, returning only rows matching the full conjunction.
Undefined value edge cases and bound handling
packages/db/tests/collection-indexes.test.ts
Tests that undefined bounds (gt(score, undefined)), equality checks on undefined, IN matching with undefined members, and range comparisons all correctly exclude rows with missing values and do not leak matches from index-optimized execution.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 I hopped through tests at dawn,
Dates and ranges neatly drawn,
Or and And danced, bounds set tight,
Undefined caught by morning light,
Conjunctions matched — all queries right! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main addition: failing tests for AND/OR queries mixing indexed and non-indexed conditions, which is the primary focus of the changeset.
Description check ✅ Passed The description covers the changes in detail and aligns with the template's requirements, though the Release Impact checklist section is incomplete (both checkboxes unchecked without explicit clarification).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@1581

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@1581

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@1581

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@1581

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@1581

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@1581

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@1581

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@1581

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@1581

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@1581

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@1581

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@1581

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@1581

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@1581

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@1581

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@1581

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@1581

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@1581

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@1581

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@1581

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@1581

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@1581

commit: 029e759

kevin-dp and others added 3 commits June 10, 2026 14:31
Adds expected-behaviour tests for range conditions:
- compound ranges sharing a boundary value must apply the strictest
  bound regardless of argument order, including for date values
- one-sided compound ranges must return the matching rows
- strict comparisons (gt) on date fields must exclude the boundary row

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A compound range condition where one bound is undefined (e.g.
gt(score, undefined) AND lt(score, 90)) must match nothing, since a
comparison against undefined is never true. The index-optimized path
must agree with a full scan. This test currently fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ries

A comparison against null/undefined is never true, but BTree indexes
store and return rows with nullish indexed values (they sort as the
smallest key). These tests assert that the index-optimized snapshot
matches a full predicate scan for:
- eq against undefined
- IN with an undefined member
- a range comparison over a field that has rows with undefined values
- an upper-bounded compound range over such a field

They currently fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant