SQL on FHIR WG Meetings



SQL on FHIR WG Meeting — May 27, 2025
AD
Adam Culbertson
John Grimes
Principal Research Consultant CSIRO
Arjun Sanyal
Principal Antidote Solutions
Nikolai Ryzhikov
CTO at Health Samurai
Steve Munini
CEO and CTO, Helios Software
May 27, 2025
Topics discussed:
- The shareable profile says the FHIRPath subset covers string, integer and decimal literals — but the tests don't stick to it, and some use date literals. Nobody noticed because implementations lean on engines like fhirpath.js that handle dates anyway. The subset also says you must implement literals and then goes quiet on whether the Boolean, maths and comparison operators have to work over those types, or over anything that isn't a literal, and some tests wander into exactly that territory.
- Nikolai Ryzhikov wanted the subset written down formally. Functions are the easy half — you either support one or you don't. Operators need types, so his suggestion was to name them in the spec as typed operators: string plus, decimal plus, dateTime plus, with the first two mandatory and the awkward ones optional. Left open: macros like where, and how deeply you can nest them, since recursive grammars are hard for some implementers.
- A cut-down ANTLR grammar was floated, since the FHIRPath spec ships one and declares it the source of truth when the prose disagrees. It was talked down fairly quickly: the functions aren't in the grammar, behaviour isn't either, and it becomes one more thing to maintain. The better idea was to reference spec features from the tests, so you can see which feature each test actually depends on, and so the set can grow without becoming vague.
- Column types have a semantic hole. The shareable profile makes you declare a column type as a FHIR type, but a FHIRPath expression doesn't always have one — a FHIRPath string is just a string, not a FHIR string or uri or oid — and the spec has no mapping between the two. The related question is defaults: with no hint at all, should a dateTime come out as a native type from one runner and a string from another?
- The evidence for caring came from the paper. Running the same ViewDefinition on Aidbox and Pathling, the SQL wouldn't run over both results without casting — the only interoperability gap left. The leaning was towards ANSI SQL types, because databases already document how they map to ANSI, and Parquet already carries them. On whether to add a new element for it, John's line was to articulate the problem first: tags already exist, are barely implemented, and the spec says almost nothing about what they mean.
- Nikolai proposed merging $run and $evaluate into one operation, on the grounds that the response is identical and the only difference is whether you send the view definition or point at one. John Grimes offered the closest precedent — ValueSet/$expand, which takes either a url or a valueSet — so the parameter was renamed url. $run stays single-view because it streams synchronously; $export takes a collection. A live check confirmed Parameters can't hold contained resources, which killed the other option.