fix(db): total ordering for series OFFSET pagination

GetDistinctSeries ordered by MAX(created_at) DESC alone. Bulk imports
inserted in a single transaction share one NOW() timestamp, leaving
large numbers of (library_id, series) groups tied on MAX(created_at);
Postgres does not guarantee tie order between executions, so
LIMIT/OFFSET pages could repeat or drop series across page loads.

Add the GROUP BY keys (library_id, series) as tiebreakers so the sort
is total and deterministic. Comment documents why the tiebreaker is
required so it is not dropped as noise. sqlc regenerated (interface
unchanged; the comment flows into querier.go docs).
This commit is contained in:
John O'Keefe committed 2026-10-19 12:39:32 -04:00
1 parent f4414aa5b6
commit 38efbff7e1
3 files changed
+17 -2

No files matched your search

+6 -1
View File
@@ -2880,7 +2880,12 @@ WHERE (sqlc.narg('library_id')::uuid IS NULL OR library_id = sqlc.narg('library_
AND missing_scan_count = 0
AND series IS NOT NULL AND series != ''
GROUP BY library_id, series
ORDER BY MAX(created_at) DESC
-- Tiebreaker REQUIRED for LIMIT/OFFSET pagination: bulk imports in one
-- transaction share a single NOW() timestamp, leaving many groups tied on
-- MAX(created_at). Postgres does not guarantee tie order between
-- executions, so page boundaries could repeat or drop series. The GROUP BY
-- keys make the sort total and deterministic.
ORDER BY MAX(created_at) DESC, library_id, series
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
-- name: GetDistinctSeriesCount :one