Unified search: projection-parametrized search() SQL consolidation#5157
Merged
habdelra merged 6 commits intoJun 9, 2026
Merged
Conversation
…ngine
Consolidate the searchCards and searchPrerendered SQL projections into one
search(realmURL, query, opts, projection): the shared query core
(WHERE / GROUP BY url / ORDER / LIMIT) is built once in _search, and only the
SELECT list varies by projection —
- dataOnly: pristine_doc + error_doc (today's searchCards projection);
- render(format, renderType): the format-specific HTML column via
buildHtmlColumnExpression (reused verbatim) + used_render_type + deps +
display_names + icon_html + error_doc, plus pristine_doc carried
conditionally (CASE WHEN <htmlExpr> IS NULL) so the live serialization
rides along only on no-HTML fallback rows; HTML-backed rows ship none.
searchCards and searchPrerendered become thin wrappers over search(); their
output is unchanged, so the existing wrapper tests are the parity goldens.
New tests cover projection equivalence (same row set + page.total across
projections) and the conditional pristine_doc. No response-shape or endpoint
change — emission/shape work lands in CS-11433.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
…ault-filteron' into cs-11431-unified-search-projection-parametrized-search-sql
Code comments describe the enduring contract, not the rollout sequence.
habdelra
commented
Jun 8, 2026
Comments (test files included) state the enduring contract, not the ticket.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR consolidates the SQL projection logic used by instance search into a single IndexQueryEngine.search() entrypoint that varies only the SELECT list via a SearchProjection, while keeping the existing searchCards and searchPrerendered wrappers intact.
Changes:
- Introduces
SearchProjectionand a newIndexQueryEngine.search()method to centralize the shared query core and parameterize the projection. - Refactors
searchCardsandsearchPrerenderedto delegate tosearch()while preserving their return shapes. - Adds unit tests that directly exercise projection equivalence and the conditional
pristine_docbehavior for render results.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/runtime-common/index-query-engine.ts | Adds SearchProjection and consolidates instance search into a projection-parametrized search() used by the existing wrappers. |
| packages/host/tests/unit/index-query-engine-test.ts | Adds direct tests for search() projection parity and conditional pristine_doc behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
habdelra
changed the base branch from
cs-11430-unified-search-render-type-resolution-rule-default-filteron
to
main
June 8, 2026 21:30
State the contract in timeless terms — drop temporal/delivery framing
("today's", "later separate step", "existing/new") and the identity-only
delivery phrasing from comments and an assertion message.
…_doc The render projection carries the live serialization only on rows with no HTML for the format. Build that by wrapping the grouped query: the inner query computes `html` once (aliased) and a raw `pristine_doc_fallback`; the outer query applies `CASE WHEN html IS NULL THEN pristine_doc_fallback` — so the COALESCE/JSONB HTML expression is evaluated a single time per row instead of twice. Sort values are exposed as inner columns and the outer ORDER BY applies them (plus the `url` tiebreaker), so ordering and paging are unchanged. Adds a sort-order test alongside the projection-equivalence and conditional-pristine_doc tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
backspace
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 / Stream A step 1 of Unify prerendered-card-search and card-search: collapse the two SQL projections in
index-query-engine.tsinto one parametrized query. Pure refactor — output is unchanged (the existing wrapper tests are the parity goldens).The change
search(realmURL, query, opts, projection)builds the shared query core once (_searchstill ownsWHERE/GROUP BY url/ORDER/LIMIT) and varies only the SELECT list byprojection:dataOnly→pristine_doc+error_doc(today'ssearchCardsprojection).render(format, renderType)→ the format-specific HTML column viabuildHtmlColumnExpression(reused verbatim) +used_render_type+deps/display_names/icon_html/error_doc, pluspristine_doccarried conditionally —CASE WHEN <htmlExpr> IS NULL THEN ANY_VALUE(pristine_doc) END— so the live serialization rides along only on no-HTML fallback rows; HTML-backed rows carry none (they'll ship identity-only in CS-11433).searchCardsandsearchPrerenderedare now thin wrappers oversearch(); their returned shape is unchanged. No response-shape or endpoint change — emission lands in CS-11433.Tests
Unit | querysuite (allsearchCards/searchPrerenderedcases) passes unchanged — 74/74 locally.search()returns the same row set +page.totalacross thedataOnlyandrenderprojections for the same query.pristine_doc: present only on rows whose HTML expression isNULL(verified: HTML-backed row → nopristine_doc; no-HTML row → livepristine_doc).The pg path is exercised by the realm-server search/prerendered/indexing shards in CI (the SQL reuses the existing pg/sqlite
dbExpressionvariants).🤖 Generated with Claude Code