Skip to content

Conversation

@claude
Copy link
Contributor

@claude claude bot commented Jan 27, 2026

Summary

Fixes the infinite loop in BTreeIndex.takeInternal when indexed values are undefined.

Root cause

The BTree's nextHigherPair(undefined) is designed to return the minimum pair when undefined is passed (to start iteration from the beginning). However, when the minimum key in the tree IS undefined (because an item's indexed field is undefined), calling nextHigherPair(undefined) after processing returns the same pair again, creating an infinite loop.

Fix

The fix introduces a START_ITERATION sentinel symbol to distinguish between:

  • "Start from the beginning" (when from is undefined)
  • "Continue from the actual undefined key" (when the indexed value is undefined)

The loop also detects when nextPair returns the same key as was passed in, which indicates we've completed a cycle and should break out.

Changes

  • Added START_ITERATION symbol as a sentinel to represent "start from beginning"
  • Modified takeInternal to use the sentinel and detect cycles when the key doesn't advance

Test plan

  • New tests pass: should handle undefined indexed values with take and limit
  • New tests pass: should handle undefined indexed values with takeReversed and limit
  • All existing tests pass (1934 tests)

Repro PR

Reproduction test: #1187

Fixes #1186

🤖 Generated with Claude Code

github-actions bot and others added 2 commits January 27, 2026 16:05
…ly (issue #1186)

Co-Authored-By: Claude (claude-opus-4-5) <noreply@anthropic.com>
…lue is undefined (issue #1186)

Co-Authored-By: Claude (claude-opus-4-5) <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Jan 27, 2026

⚠️ No Changeset found

Latest commit: fa8457c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 27, 2026

More templates

@tanstack/angular-db

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

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/electric-db-collection

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

@tanstack/offline-transactions

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

@tanstack/powersync-db-collection

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

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/rxdb-db-collection

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: fa8457c

@github-actions
Copy link
Contributor

Size Change: +63 B (+0.07%)

Total Size: 91 kB

Filename Size Change
./packages/db/dist/esm/indexes/btree-index.js 1.99 kB +63 B (+3.27%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 1.39 kB
./packages/db/dist/esm/collection/changes.js 1.19 kB
./packages/db/dist/esm/collection/events.js 388 B
./packages/db/dist/esm/collection/index.js 3.32 kB
./packages/db/dist/esm/collection/indexes.js 1.1 kB
./packages/db/dist/esm/collection/lifecycle.js 1.68 kB
./packages/db/dist/esm/collection/mutations.js 2.34 kB
./packages/db/dist/esm/collection/state.js 3.49 kB
./packages/db/dist/esm/collection/subscription.js 3.62 kB
./packages/db/dist/esm/collection/sync.js 2.41 kB
./packages/db/dist/esm/deferred.js 207 B
./packages/db/dist/esm/errors.js 4.7 kB
./packages/db/dist/esm/event-emitter.js 748 B
./packages/db/dist/esm/index.js 2.69 kB
./packages/db/dist/esm/indexes/auto-index.js 742 B
./packages/db/dist/esm/indexes/base-index.js 766 B
./packages/db/dist/esm/indexes/lazy-index.js 1.1 kB
./packages/db/dist/esm/indexes/reverse-index.js 513 B
./packages/db/dist/esm/local-only.js 837 B
./packages/db/dist/esm/local-storage.js 2.1 kB
./packages/db/dist/esm/optimistic-action.js 359 B
./packages/db/dist/esm/paced-mutations.js 496 B
./packages/db/dist/esm/proxy.js 3.75 kB
./packages/db/dist/esm/query/builder/functions.js 733 B
./packages/db/dist/esm/query/builder/index.js 4.08 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 1.05 kB
./packages/db/dist/esm/query/compiler/evaluators.js 1.42 kB
./packages/db/dist/esm/query/compiler/expressions.js 430 B
./packages/db/dist/esm/query/compiler/group-by.js 1.81 kB
./packages/db/dist/esm/query/compiler/index.js 2.02 kB
./packages/db/dist/esm/query/compiler/joins.js 2.07 kB
./packages/db/dist/esm/query/compiler/order-by.js 1.45 kB
./packages/db/dist/esm/query/compiler/select.js 1.06 kB
./packages/db/dist/esm/query/expression-helpers.js 1.43 kB
./packages/db/dist/esm/query/ir.js 673 B
./packages/db/dist/esm/query/live-query-collection.js 360 B
./packages/db/dist/esm/query/live/collection-config-builder.js 5.42 kB
./packages/db/dist/esm/query/live/collection-registry.js 264 B
./packages/db/dist/esm/query/live/collection-subscriber.js 1.93 kB
./packages/db/dist/esm/query/live/internal.js 145 B
./packages/db/dist/esm/query/optimizer.js 2.56 kB
./packages/db/dist/esm/query/predicate-utils.js 2.97 kB
./packages/db/dist/esm/query/subset-dedupe.js 921 B
./packages/db/dist/esm/scheduler.js 1.3 kB
./packages/db/dist/esm/SortedMap.js 1.3 kB
./packages/db/dist/esm/strategies/debounceStrategy.js 247 B
./packages/db/dist/esm/strategies/queueStrategy.js 428 B
./packages/db/dist/esm/strategies/throttleStrategy.js 246 B
./packages/db/dist/esm/transactions.js 2.9 kB
./packages/db/dist/esm/utils.js 924 B
./packages/db/dist/esm/utils/browser-polyfills.js 304 B
./packages/db/dist/esm/utils/btree.js 5.61 kB
./packages/db/dist/esm/utils/comparison.js 852 B
./packages/db/dist/esm/utils/cursor.js 457 B
./packages/db/dist/esm/utils/index-optimization.js 1.51 kB
./packages/db/dist/esm/utils/type-guards.js 157 B

compressed-size-action::db-package-size

@github-actions
Copy link
Contributor

Size Change: 0 B

Total Size: 3.7 kB

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 225 B
./packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.17 kB
./packages/react-db/dist/esm/useLiveQuery.js 1.34 kB
./packages/react-db/dist/esm/useLiveSuspenseQuery.js 559 B
./packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

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.

Infinite loop in BTreeIndex.takeInternal when using orderBy and limit with undefined indexed values

0 participants