Skip to content

Conversation

@KyleAMathews
Copy link
Collaborator

When processing incremental updates to groupBy queries, the D2 pipeline might emit an insert for an updated aggregate without a corresponding delete in certain edge cases. This caused "already exists" errors in the live query collection.

Added a defensive check in applyChanges() that treats inserts as updates when the key already exists, but only for queries without custom getKey (like groupBy). Queries with custom getKey + joins still throw errors as expected to alert users of potential data issues.

Added comprehensive test suite for groupBy incremental update scenarios:

  • Basic incremental updates with same groupBy key
  • Multiple groups being updated
  • Sum aggregate with incremental updates
  • Batch vs incremental processing
  • Subquery pattern (groupBy used as source for another query)
  • Rapid sequential inserts
  • Multiple events in single batch

🎯 Changes

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

When processing incremental updates to groupBy queries, the D2 pipeline
might emit an insert for an updated aggregate without a corresponding
delete in certain edge cases. This caused "already exists" errors in the
live query collection.

Added a defensive check in applyChanges() that treats inserts as updates
when the key already exists, but only for queries without custom getKey
(like groupBy). Queries with custom getKey + joins still throw errors
as expected to alert users of potential data issues.

Added comprehensive test suite for groupBy incremental update scenarios:
- Basic incremental updates with same groupBy key
- Multiple groups being updated
- Sum aggregate with incremental updates
- Batch vs incremental processing
- Subquery pattern (groupBy used as source for another query)
- Rapid sequential inserts
- Multiple events in single batch
@changeset-bot
Copy link

changeset-bot bot commented Dec 16, 2025

⚠️ No Changeset found

Latest commit: 4c77498

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 Dec 16, 2025

More templates

@tanstack/angular-db

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

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/electric-db-collection

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

@tanstack/offline-transactions

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

@tanstack/powersync-db-collection

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

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/rxdb-db-collection

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: 4c77498

@github-actions
Copy link
Contributor

github-actions bot commented Dec 16, 2025

Size Change: +35 B (+0.04%)

Total Size: 89.5 kB

Filename Size Change
./packages/db/dist/esm/collection/sync.js 2.39 kB +8 B (+0.34%)
./packages/db/dist/esm/query/live/collection-config-builder.js 5.35 kB +27 B (+0.51%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 1.39 kB
./packages/db/dist/esm/collection/changes.js 999 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.34 kB
./packages/db/dist/esm/collection/state.js 3.46 kB
./packages/db/dist/esm/collection/subscription.js 3.54 kB
./packages/db/dist/esm/deferred.js 207 B
./packages/db/dist/esm/errors.js 4.27 kB
./packages/db/dist/esm/event-emitter.js 748 B
./packages/db/dist/esm/index.js 2.68 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.93 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.75 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.46 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-registry.js 264 B
./packages/db/dist/esm/query/live/collection-subscriber.js 1.9 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.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 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/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

github-actions bot commented Dec 16, 2025

Size Change: 0 B

Total Size: 3.35 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.12 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

claude and others added 5 commits December 16, 2025 23:42
Update @tanstack/query-db-collection from ^1.0.7 to ^1.0.8 in:
- examples/react/todo
- examples/solid/todo

This fixes the sherif check that requires consistent dependency versions
across the workspace.
The previous fix in applyChanges was insufficient because the actual error
was thrown in the sync layer. This adds a fallback that converts inserts
to updates for live queries without custom getKey (like groupBy) when the
key already exists, preventing duplicate key errors during incremental updates.
Added a test that directly exercises the sync layer fix by:
1. Setting up a collection with utils[LIVE_QUERY_INTERNAL].hasCustomGetKey = false
   (simulating a live query without custom getKey, like groupBy)
2. Inserting a document with a specific key
3. Attempting to insert another document with the same key (without delete)

Without the fix, this would throw "Cannot insert document with key ... already exists".
With the fix, the insert is converted to an update.

Also added a test to verify regular collections still throw errors on duplicate inserts.
…plicate-inserts-PvGLM

# Conflicts:
#	examples/react/todo/package.json
#	examples/solid/todo/package.json
#	pnpm-lock.yaml
@KyleAMathews
Copy link
Collaborator Author

#1044 also fixes this! So closing

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