Skip to content

Optimize library keyword search with materialized matching IDs - #168

Draft
filiksyos wants to merge 1 commit into
mainfrom
fix/library-search-query-plan-20261006
Draft

filiksyos wants to merge 1 commit into
mainfrom
fix/library-search-query-plan-20261006

Conversation

@filiksyos

@filiksyos filiksyos commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add a SECURITY INVOKER, STABLE keyword-search RPC that materializes lightweight matching IDs before sorting/pagination, reuses the same candidates for exact totals, and fetches only selected 180-character previews.
  • Keep the existing full-text and metadata strategy order, sort semantics, source RLS, public card fields, and 96-row fetch cap. All user input remains bound data in SQL.
  • Route application keyword searches through the RPC. Missing-function errors alone fall back to the existing query implementation so an application/database rollout mismatch does not break current search.
  • Add 11 RPC-path regressions on top of the existing 21, and include migration files in CI path coverage.

Diagnosis

Read-only EXPLAIN showed the existing search-vector GIN index used by counts, while sorted LIMIT 24 rows chose the cached-at index and filtered vectors row by row. The materialized-ID query plans GIN bitmap scan → lightweight candidate sort → bounded primary-key hydration. This is a plan-level diagnosis, not a measured latency claim.

Verification

  • 32 credential-free regression tests passed
  • TypeScript and focused ESLint passed
  • Production Next build passed without external credentials
  • Independent security/behavior review found no blockers
  • Existing repository-wide lint issues remain outside this change, as documented in Fix library search parsing and source fallback failures #167

Migration status: approval required, not applied

Production apply_migration was denied because creating a persistent RPC and granting EXECUTE to anon/authenticated needs explicit approval for this production rollout. No database changes occurred. Do not merge until approved, applied and anonymous runtime checks pass.

The only database change is this new read-only function. It uses the existing security-invoker library view/RLS, returns no new fields, sets an empty search_path, limits output to 96 rows, revokes PUBLIC execution and grants execution only to the existing anon/authenticated library audience. No table data, extensions, indexes, credentials, RLS policies or timeout settings are changed.

After approval: apply the included migration; test FTS, metadata, punctuation, no-match and trending queries as anon under the existing 3-second statement limit; verify security advisors have no new findings; then verify preview CI, merge and verify production.

Metadata searches still lack trigram indexes; one materialized scan may be sufficient, but actual runtime checks determine whether further work is needed. No index build is included.

Exact-head CI result

Head 9134af84c72f2b6458cf9ef01839f807711610b7 passed the library-search workflow: frozen install, all 32 tests, TypeScript and focused ESLint. Vercel preview dpl_A1rcx6ypiBNHBcdEzemRDt6jXwTa is READY. As of 2026-10-06 13:55 UTC, the production function does not exist and no migration is recorded. Waiting for explicit production migration approval; this PR remains draft and unmerged.

@vercel

vercel Bot commented Oct 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
gitreverse Ready Ready Preview Oct 6, 2026 1:53pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — 9134af84 Deployed Oct 6, 2026 by vercel[bot]
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.

1 participant