Skip to content

fix(api): show all episodes when sorting and filtering (builds on #972) - #1010

Open
ashtonian wants to merge 4 commits into
madeofpendletonwool:mainfrom
ashtonian:test/pagination-backends-upstream
Open

ashtonian wants to merge 4 commits into
madeofpendletonwool:mainfrom
ashtonian:test/pagination-backends-upstream

Conversation

@ashtonian

@ashtonian ashtonian commented Oct 18, 2026 •

Copy link
Copy Markdown

Builds on @xoiram's #972 to fix missing or repeated episodes when sorting and filtering large podcast lists (#954). #972 supplies the pagination query fix, stable ordering for tied values, and the original PostgreSQL regression tests. Its original commit is preserved.

Adds on top of #972:

  • Broader database regression coverage using mixed podcast/YouTube lists and merged podcasts, including overlapping episode/video IDs and tied dates, titles, and durations.
  • Checks every supported sort direction and completion filter across page boundaries, plus search results, totals, and separation between users. Runs the added coverage on both PostgreSQL and MySQL-compatible databases.
  • Extends the Rust CI job with disposable PostgreSQL and MariaDB services and runs all API tests, including database tests normally skipped without explicit test databases. The MySQL fixture uses the simple query protocol for database selection so it also works on MySQL 8.4.
  • Resolves the original PR's merge conflict with current main while retaining its fix and tests.

Validation: all 21 Rust API tests pass when combined with #1009, against PostgreSQL 18 with MariaDB 11.4 and again with MySQL 8.4. GitHub Actions await maintainer approval. No schema migration or runtime dependency is added.

This PR contains #972 plus these additions and targets main. If #972 lands separately first, sync this branch before merging.

Related: #954. Replaces the closed fork follow-up.

xoiram and others added 3 commits August 23, 2026 10:49
return_podcast_episodes_capitalized capped each UNION branch (Episodes,
YouTubeVideos) with `ORDER BY pubdate DESC LIMIT (limit+offset)` regardless
of the requested sort, then re-sorted the truncated set in the outer query.
That's only valid when sorting newest-first: for any other sort (oldest
first, title, duration) on a podcast with more episodes than the current
page window, the per-branch cap discarded rows the outer sort actually
needed. In practice this made "oldest first" pagination loop over the same
newest-N episodes forever instead of ever reaching older ones, and made
completed/incomplete/in-progress filters silently drop matches that weren't
among the newest N raw rows (even though the separate, unrestricted count
query correctly reported them).

Fixes, for both the Postgres and MySQL code paths:
- Each per-branch subquery now orders by the actually-requested sort
  column/direction instead of a hardcoded recency order, restoring the
  top-K-merge correctness of the per-branch LIMIT for every sort.
- The completed/incomplete/in-progress filter is now pushed into each
  branch's WHERE before its LIMIT, instead of only being applied after
  truncation.
- Added an explicit tiebreaker (episodeid/videoid per branch, is_youtube +
  Episodeid at the outer level) so ties in the sort column can't produce a
  different row order across separate page requests as per_branch_limit
  grows, which could otherwise reintroduce the same duplicate/skip
  behavior via a different path.
- Consolidated the sort-column and filter-clause mappings, which had
  drifted into 4 and 6 duplicated match blocks respectively across the two
  DB backends — the kind of divergence that caused the original bug.

Adds in-binary regression tests (rust-api has no lib target, so these
can't live under tests/) covering: oldest-first pagination visiting every
episode without duplicates, a completed-filter match outside the newest
page, and pagination stability when the sort column is fully tied. Verified
against a real Postgres, including confirming each test fails against the
pre-fix query and passes after.

Wires a new rust-backend-tests CI job (its own ephemeral Postgres service)
to run these, since the existing backend-tests job's Python suite is
already broken (imports a FastAPI app module that no longer exists) and
untested. Also gitignores rust-api/target/, which wasn't previously excluded.
@ashtonian
ashtonian marked this pull request as ready for review October 18, 2026 02:10
@ashtonian ashtonian changed the title fix(api): correct pagination with PostgreSQL and MariaDB coverage (builds on #972) fix(api): show all episodes when sorting and filtering (builds on #972) Oct 18, 2026

This branch has not been deployed

No deployments
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.

2 participants