Motivation
The FHIR search specification defines two ways of combining search parameter values (https://www.hl7.org/fhir/search.html#combining):
- AND — repeating a parameter (
?identifier=a&identifier=b)
- OR — comma separated values within a single parameter (
?identifier=a,b)
The DSF FHIR server currently only supports the AND combination. Comma separated values are passed to the parameter as a single, literal value, so a request like GET [base]/Endpoint?identifier=http://dsf.dev/sid/endpoint-identifier|a,http://dsf.dev/sid/endpoint-identifier|b does not return the union of the matching resources. Clients therefore cannot express a simple "one of these values" query and have to fall back to multiple requests.
Proposed solution
Implement the FHIR search OR join: comma separated values within a single search parameter are combined with a logical OR, while separately repeated parameters keep the existing logical AND semantics.
The combination is applied uniformly in SearchQuery for:
- the generated SQL filter (
( <value1> OR <value2> ... ) per parameter, AND-ed with the other parameters and the read-access filter),
- the in-memory matcher used for Subscriptions (a resource matches a group if it matches any of the OR values),
- the search bundle
self link (OR values are kept comma separated within a single parameter).
A comma escaped as \, is treated as a literal character (per the FHIR escaping rules) and is not used as a value separator.
Scope
In scope
- OR (comma) combination for all search parameter types (token, string, reference, date, number, quantity, uri,
_id, _lastUpdated, _profile, _tag, ...), implemented centrally without touching the individual parameter type implementations.
- Escaping of
\, as a literal comma.
- Correct
self link reconstruction (OR values comma separated, AND values as repeated parameters).
- Unit and integration tests.
Out of scope (for now)
- Full unescaping of the other FHIR escape sequences (
\|, \$, \\) inside a value; only \, is handled, the remaining sequences are left to the parameter type specific parsing (unchanged behavior).
- Collapsing an OR list into a single
IN / = ANY(...) SQL expression per parameter type. The values are OR-ed as individual conditions; PostgreSQL already combines the index scans (GIN BitmapOr) into a single query, so a
per-type collapse is a possible later micro-optimization, not part of this change.
Acceptance criteria
Motivation
The FHIR search specification defines two ways of combining search parameter values (https://www.hl7.org/fhir/search.html#combining):
?identifier=a&identifier=b)?identifier=a,b)The DSF FHIR server currently only supports the AND combination. Comma separated values are passed to the parameter as a single, literal value, so a request like
GET [base]/Endpoint?identifier=http://dsf.dev/sid/endpoint-identifier|a,http://dsf.dev/sid/endpoint-identifier|bdoes not return the union of the matching resources. Clients therefore cannot express a simple "one of these values" query and have to fall back to multiple requests.Proposed solution
Implement the FHIR search OR join: comma separated values within a single search parameter are combined with a logical OR, while separately repeated parameters keep the existing logical AND semantics.
The combination is applied uniformly in
SearchQueryfor:( <value1> OR <value2> ... )per parameter, AND-ed with the other parameters and the read-access filter),selflink (OR values are kept comma separated within a single parameter).A comma escaped as
\,is treated as a literal character (per the FHIR escaping rules) and is not used as a value separator.Scope
In scope
_id,_lastUpdated,_profile,_tag, ...), implemented centrally without touching the individual parameter type implementations.\,as a literal comma.selflink reconstruction (OR values comma separated, AND values as repeated parameters).Out of scope (for now)
\|,\$,\\) inside a value; only\,is handled, the remaining sequences are left to the parameter type specific parsing (unchanged behavior).IN/= ANY(...)SQL expression per parameter type. The values are OR-ed as individual conditions; PostgreSQL already combines the index scans (GINBitmapOr) into a single query, so aper-type collapse is a possible later micro-optimization, not part of this change.
Acceptance criteria
GET [base]/[type]?param=a,breturns the union of the resources matchingparam=aorparam=b(OR).GET [base]/[type]?param=a¶m=bkeeps returning only resources matching both (AND) — unchanged behavior.\,is treated as a literal comma, not as a value separator.selflink represents OR values comma separated within one parameter and AND values as repeated parameters.