Source collection emptied when an ordered window that fell back to a full-source read is replaced by one reading the same subset
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- database
Direzione di ricerca
Start with repro.test.ts in the linked reproduction to see the failing subscribe and release sequence, then trace ordered-window fallback and source collection cleanup in the TanStack DB code. Reproduce with npm test; done means switching between overlapping full-source fallback windows keeps the 50-row window populated and the shared source rows intact, regardless of subscribe and release order.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
- I've validated the bug against the latest version of DB packages
Describe the bug
One syncMode: "on-demand" query collection, one ordered, limited live query:
q.from({ r: source })
.where(({ r }) => not(eq(r.status, 4)))
.orderBy(({ r }) => r.date, { direction, nulls, stringSort: "lexical" })
.orderBy(({ r }) => r.id, direction)
.limit(50)
When the sort direction changes, the new live query is subscribed, then the old one is released (what a UI binding does when a reactive sort changes). If both windows fell back to a full-source read of the same filter, releasing the old window removes every row from the source collection. The new window stays at 0 rows and never recovers, nor does any other view on that collection.
Two triggers of the documented full-source fallback reproduce it:
- the first page ends on a NULL sort value (
DESC NULLS FIRSTon a nullable column); stringSort: "locale", without any NULL.
Indexes matching the query's compareOptions (no dev warning) don't change the result.
Requests seen by queryFn in the failing case:
DESC limit=50 -> 50 rows
DESC limit=none -> 240 rows (full-source fallback, where: status != 4)
ASC limit=50 -> 50 rows
ASC limit=none -> 240 rows (same subset as above)
-- old DESC window released --
source.size === 0, asc.size === 0
Controls that work:
- No NULL dates: the DESC window only requests its boundary tie (
date = …), so the ASC full read is a different subset. The source keeps 240 rows. - Same NULL data, but the old window is released before the new one subscribes: the source keeps its rows and the ASC window shows 50.
- Two unordered live queries with the same
where, overlapping the same way, keep their rows. So it seems specific to subsets acquired by the ordered loader's full-source fallback.
To Reproduce
Repo: https://github.com/1bod/tanstack-db-ordered-window-empties-source
StackBlitz: https://stackblitz.com/github/1bod/tanstack-db-ordered-window-empties-source
npm installnpm test- See the 2 control tests pass and the 3
BUGtests fail withexpected +0 to be 50(window) andexpected 0 to be greater than 0(source collection size).
repro.test.ts only uses @tanstack/db, @tanstack/query-db-collection and @tanstack/query-core, with a fake backend that honours where (including cursor predicates), orderBy with NULLS FIRST/LAST, offset and limit.
Expected behavior
After the switch, the ASC window shows its 50 rows and the source collection keeps the rows the new window holds, whatever the order of subscribe and release.
Screenshots
N/A
Desktop (please complete the following information):
- OS: Linux
- Browser: N/A (Node 26.13, vitest 4.1.12). First seen in a browser with
@tanstack/vue-db(useLiveQuery/useLiveInfiniteQuery) when toggling the sort of a list sorted by a nullable date. - Version:
@tanstack/db1.0.0-rc.1.3,@tanstack/query-db-collection1.5.1,@tanstack/query-core5.105.3
Smartphone (please complete the following information):
N/A
Additional context
Workaround: split the query into an isNull(date) window and a not(isNull(date)) window with stringSort: "lexical", so no page ends on NULL and the fallback never runs.
Possibly related: #2160 (rows lost across reentrant final-owner cleanup), #2352 (identical subset reuse), #2268 (full-source fallback on NULL page ends).
- Lingua principale
- TypeScript
- Stelle
- 4k
- Fork
- 277
- Merge medio
- 1g 11h
- PR unite (30g)
- 148
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/db
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
OfflineExecutor.dispose() never settles pendingTransactionPromisesForse di nuovo libera @Claire-ovo l’ha presa 10 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
TanStack/db#2254 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Two @tanstack/db tests time out under CPU load because a cold module import counts against the 5 s default timeoutForse già presa @jp-knj l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
Issue simili
-
test-reliability
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Azure/azure-sdk-for-js#40672 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
HarperFast/studio#2067 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
liberation-data/drivine#639 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno