Skip to content

Conversation

@samwillis
Copy link
Collaborator

@samwillis samwillis commented Nov 26, 2025

Failed test run before the fix: https://github.com/TanStack/db/actions/runs/19701959124/job/56440153416?pr=913

Summary

This PR fixes a bug where cursor-based pagination could stall or skip rows when ordering by Date columns, due to precision differences between JavaScript (milliseconds) and backends like PostgreSQL (microseconds).

The Problem

JavaScript Date objects have millisecond precision, but databases like PostgreSQL store timestamps with microsecond precision. This creates a mismatch:

PostgreSQL stores:
- 2024-01-15T10:30:45.123000Z (row 1)
- 2024-01-15T10:30:45.123100Z (row 2)  
- 2024-01-15T10:30:45.123200Z (row 3)

JavaScript sees all as:
- 2024-01-15T10:30:45.123Z

When paginating, TanStack DB loads "all rows with the same cursor value" to avoid skipping duplicates. The previous code used exact equality (eq), which only matched rows with exactly 123.000000μs, missing rows at other microsecond offsets.

The Fix

For Date values, we now query for the 1ms range that the Date represents:

and(
  gte(expression, new Value(minValue)),           // >= 123.000000μs
  lt(expression, new Value(minValuePlus1ms))      // <  124.000000μs
)

Changes

  • packages/db/src/collection/subscription.ts: Added special handling for Date values to use range queries instead of exact equality
  • packages/db/tests/query/order-by.test.ts: Added test that verifies the correct query structure is generated

@changeset-bot
Copy link

changeset-bot bot commented Nov 26, 2025

🦋 Changeset detected

Latest commit: b2766e1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@tanstack/db Patch
@tanstack/angular-db Patch
@tanstack/db-collection-e2e Patch
@tanstack/electric-db-collection Patch
@tanstack/powersync-db-collection Patch
@tanstack/react-db Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch

Not sure what this means? Click here to learn what changesets are.

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 26, 2025

More templates

@tanstack/angular-db

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

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/electric-db-collection

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

@tanstack/offline-transactions

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

@tanstack/powersync-db-collection

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

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/rxdb-db-collection

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: b2766e1

@github-actions
Copy link
Contributor

github-actions bot commented Nov 26, 2025

Size Change: +65 B (+0.08%)

Total Size: 86.5 kB

Filename Size Change
./packages/db/dist/esm/collection/subscription.js 2.55 kB +65 B (+2.62%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 1.38 kB
./packages/db/dist/esm/collection/changes.js 977 B
./packages/db/dist/esm/collection/events.js 388 B
./packages/db/dist/esm/collection/index.js 3.24 kB
./packages/db/dist/esm/collection/indexes.js 1.1 kB
./packages/db/dist/esm/collection/lifecycle.js 1.67 kB
./packages/db/dist/esm/collection/mutations.js 2.26 kB
./packages/db/dist/esm/collection/state.js 3.43 kB
./packages/db/dist/esm/collection/sync.js 2.37 kB
./packages/db/dist/esm/deferred.js 207 B
./packages/db/dist/esm/errors.js 4.19 kB
./packages/db/dist/esm/event-emitter.js 748 B
./packages/db/dist/esm/index.js 2.64 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/btree-index.js 1.87 kB
./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.22 kB
./packages/db/dist/esm/query/builder/functions.js 733 B
./packages/db/dist/esm/query/builder/index.js 3.96 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 917 B
./packages/db/dist/esm/query/compiler/evaluators.js 1.35 kB
./packages/db/dist/esm/query/compiler/expressions.js 430 B
./packages/db/dist/esm/query/compiler/group-by.js 1.8 kB
./packages/db/dist/esm/query/compiler/index.js 1.96 kB
./packages/db/dist/esm/query/compiler/joins.js 2 kB
./packages/db/dist/esm/query/compiler/order-by.js 1.25 kB
./packages/db/dist/esm/query/compiler/select.js 1.07 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.33 kB
./packages/db/dist/esm/query/live/collection-registry.js 264 B
./packages/db/dist/esm/query/live/collection-subscriber.js 1.74 kB
./packages/db/dist/esm/query/live/internal.js 130 B
./packages/db/dist/esm/query/optimizer.js 2.56 kB
./packages/db/dist/esm/query/predicate-utils.js 2.88 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.18 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 881 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/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

github-actions bot commented Nov 26, 2025

Size Change: 0 B

Total Size: 3.34 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.11 kB
./packages/react-db/dist/esm/useLiveSuspenseQuery.js 431 B
./packages/react-db/dist/esm/usePacedMutations.js 401 B

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

@samwillis samwillis changed the title WIP fix pagination with order by date with precision truncation Fix Date Precision Mismatch in Cursor-Based Pagination Nov 26, 2025
createOrderByBugTests(`eager`)
})

describe(`OrderBy with Date values and precision differences`, () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test checks that we push down the range predicates rather than the eq - I considered making it test the effect, but that ends up testing the mock backend not the implementation.

Arguably we could add a e2e for electric on this.

@samwillis samwillis marked this pull request as ready for review November 26, 2025 11:27
Copy link
Collaborator

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice! Makes me wonder how many other apps out there have this bug and would never figure out a nice clever optimization like this. Big pro of using DB vs. naive filters.

@samwillis samwillis merged commit 954c8fe into main Nov 26, 2025
8 checks passed
@samwillis samwillis deleted the samwillis/fix-pagination-date-precision branch November 26, 2025 16:51
@github-actions github-actions bot mentioned this pull request Nov 26, 2025
@github-actions
Copy link
Contributor

🎉 This PR has been released!

Thank you for your contribution!

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.

3 participants