Skip to content

fix(sqlite): apply _tag/_profile/_security/_source search filters - #482

Open
angela-helios wants to merge 1 commit into
mainfrom
fix/474-meta-search-params
Open

fix(sqlite): apply _tag/_profile/_security/_source search filters#482
angela-helios wants to merge 1 commit into
mainfrom
fix/474-meta-search-params

Conversation

@angela-helios

Copy link
Copy Markdown
Contributor

Closes #474

The bug

Patient?_tag=…, _profile=…, _security=… (and _source=…) returned the unfiltered result set on sqlite, with the self link echoing the parameter as if it had been applied. The sqlite query builder diverts every _-prefixed parameter into its special-parameter handler, which only implements _id/_lastUpdated/_text/_content/_filter and returns None for everything else — the condition was silently dropped. Prefer: handling=strict couldn't catch it: the spec registers these parameters on Resource (with Resource.meta.tag etc. expressions), so they are not "unknown".

The fix

The extraction side was already correct — the writer indexes meta.tag/profile/security/source under their own param_name rows, and postgres (which special-cases only _id/_lastUpdated and routes the rest by type) already filtered correctly. Sqlite now exempts these four from the special-handler diversion so they take the regular token/uri path against search_index. One condition change; no schema or extraction changes.

Tests

  • Persistence (search_suite): _tag filters to the tagged resource, no-match returns empty, _security by label, _profile by canonical.
  • REST (search_integration): GET /Patient?_tag=system|code and ?_profile=… over HTTP return only the tagged patient.
  • Full runs green: persistence lib 758, search_suite 85, search_integration 103; clippy clean.

Note: _tag:not semantics ride on #480 (resource-level :not negation) — once both merge, :not composes with these params through the same path.

The sqlite query builder diverted every underscore-prefixed parameter
into the special-parameter handler, which only implements _id,
_lastUpdated, _text, _content, and _filter and returns None for the
rest -- so _tag, _profile, _security, and _source were silently dropped
and the search returned the unfiltered result set, while the self link
echoed the parameter as if it had been applied. Strict handling did not
catch it either: the registry knows these parameters (the spec defines
them on Resource with meta.* expressions), so they are not 'unknown'.

The extraction side was already correct -- the writer indexes meta.tag,
meta.profile, meta.security, and meta.source under their own
param_name rows. Only the query side dropped them, and only on sqlite:
the postgres builder special-cases just _id/_lastUpdated and routes
everything else by type. Sqlite now does the same for these four,
letting them take the regular token/uri path against search_index.

Closes #474
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

search: _tag, _profile and _security filters are silently dropped — even under Prefer: handling=strict — and the self link claims they were applied

2 participants