SQL on FHIR WG Meetings
SQL on FHIR WG Meeting — 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

Topics discussed:

  • Implementing export walked Nikolai Ryzhikov straight into partial failure: if one view dies halfway through, does the whole export die with it? He proposed borrowing FHIR's own split, where a transaction fails if anything fails and a batch tolerates partial failure, with per-view statuses and a partially-finished state — and argued the default should be to carry on, because after two hours of waiting, nine views out of ten may be worth having. Steve Munini agreed from experience that 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 was 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 Grimes 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.
  • Gino's history of the feature-query IG is that they'd been trying to rebuild the capability statement since before R5 and never found enough appetite for anyone to do the work, so they 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.
  • The reason the capability statement can't stretch is that 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. Steve asked whether the long-standing confusion over which search parameter combinations a server really supports fits here; Gino said that's one of the tickets driving the whole thing.
  • John offered the alternative he'd been carrying: instead of enumerating features, add a parameter meaning don't run this, just tell me whether you could — the pre-flight — which 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 is that 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.
  • Nikolai wants a $materialise 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 was wary of quietly turning it into a new subscription channel, since you need to know the auth and what kind of endpoint it is, and they're already trying to share that between bulk exchange and subscriptions rather than describe auth a third time: "I don't want to say our only tool is a hammer." John's objection to using subscriptions at all is that they're built around resources, while SQL on FHIR's unit is a row — Gino's answer is that the payload is abstracted and the trigger can be any event, so view updated, or even every hour, is a perfectly good topic.