Skip to content

Support the logical OR (comma separated values) for FHIR search parameters #554

Description

@schwzr

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

  • GET [base]/[type]?param=a,b returns the union of the resources matching param=a or param=b (OR).
  • GET [base]/[type]?param=a&param=b keeps returning only resources matching both (AND) — unchanged behavior.
  • \, is treated as a literal comma, not as a value separator.
  • The returned bundle's self link represents OR values comma separated within one parameter and AND values as repeated parameters.
  • Subscription criteria evaluation (in-memory matcher) honors the same OR semantics.
  • Searches without a comma produce byte-identical SQL to before (no regression); existing search behavior is unchanged.
  • Unit and integration tests cover the above.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions