SQL on FHIR WG Meetings

The feature-query IG, and partial-failure semantics for export — May 6, 2025

Nikolai Ryzhikov
Nikolai Ryzhikov
CTO at Health Samurai
Gino Canessa
Gino Canessa
Principal Software Engineer at Microsoft
John Grimes
John Grimes
Principal Research Consultant CSIRO
Steve Munini
Steve Munini
CEO and CTO, Helios Software
Arjun Sanyal
Arjun Sanyal
Principal Antidote Solutions
May 6, 2025

Partial failure — if one view dies, does the export?

Implementing export walked Nikolai straight into partial failure. His proposal: borrow FHIR's transaction/batch split — a transaction fails if anything fails, a batch tolerates partial failure — with per-view statuses and a partially-finished state.

Nikolai Ryzhikov
Nikolai Ryzhikov
CTO at Health Samurai

The default should be to carry on. After two hours of waiting, nine views out of ten may be worth having.

Steve — from experience: plenty can fail in the back end at any point, so you need somewhere to mark an individual failure and let the client decide.

Gino — torn: if the views are interdependent you can't run your analytics without all seven, so failing fast frees the resources for everybody else.

They landed on an input parameter to choose — as much as I hate just adding parameters.

John drew out a case that isn't a crash at all: a server that manages five of your views and refuses two because it hasn't got terminology functionality is telling you something permanent, not transient.

The feature-query IG — how a server says what it does

Gino Canessa
Gino Canessa
Principal Software Engineer at Microsoft

We'd been trying to rebuild the capability statement since before R5 and never found enough appetite for anyone to do the work, so we gave up and built this instead.

It's triplets — feature, context, value — and you either ask the server through an operation, or assert through an HTTP header that says only honour this request if you support this feature, getting a 501 back so you can fall back to another format.

Both modes are needed, he argued: discover once and cache the behaviour, but keep asserting per request, because in six months somebody updates that server and forgets to enable Parquet and you're left on a strange diagnostic hunt.

Why the capability statement can't stretch

Its structure is fixed: there's nowhere to say which CQL version you support, or which include and rev-include and iterate behaviours, or which sort orders — and search parameter combinations would explode combinatorially into a document that's already megabytes and already too big for people to use.

Graham's terminology case is the shape of the fix: asking what properties a code system has is a nonsense question server-wide, so the feature is the property, the context is one specific code system, and the values are its properties — and he flatly won't enumerate every code system on the server.

John's alternative — a "pre-flight" operation

John Grimes
John Grimes
Principal Research Consultant CSIRO

Instead of enumerating features, add a parameter meaning don't run this, just tell me whether you could. That reaches things far too fine-grained to be features, like individual FHIRPath functions.

He conceded the feature-query work is better thought through and the next step is mapping it onto SQL on FHIR to see if it fits.

Nikolai's angle: a view runs through FHIRPath and every engine supports some subset, and the spec can't even describe which subset it requires — so asking an engine to enumerate its functions may be the only honest option.

Gino's take: it's the same as an unsupported search parameter — you can always do the broad thing and filter on your side, as long as both parties know that's what's happening.

$materialise — a black box that keeps a view up to date

Nikolai wants an operation that works as a black box: here's a view, keep it up to date, and I'll read your documentation to find out how to reach it — with export as a special case of materialising.

John made him be precise, naming three axes:

  • Synchronous or async
  • Predefined or ephemeral views
  • Snapshot or continuously updating

...and asking what pointer you actually get back. He tested the abstraction with three cases: a database materialised view, a Parquet file on S3 you keep streaming into, and a Kafka topic.

Gino Canessa
Gino Canessa
Principal Software Engineer at Microsoft

I don't want to say our only tool is a hammer. You need to know the auth and what kind of endpoint it is, and we're already trying to share that between bulk exchange and subscriptions rather than describe auth a third time.

John's objection to using subscriptions at all: they're built around resources, while SQL on FHIR's unit is a row.

Gino's answer: the payload is abstracted and the trigger can be any event, so view updated, or even every hour, is a perfectly good topic.