SQL on FHIR WG Meetings





SQL on FHIR WG Meeting — June 17, 2025
Gino Canessa
Principal Software Engineer at Microsoft
Nikolai Ryzhikov
CTO at Health Samurai
Arjun Sanyal
Principal Antidote Solutions
John Grimes
Principal Research Consultant CSIRO
Eugene Vestel
Software Engineer
Steve Munini
CEO and CTO, Helios Software
Jun 17, 2025
Topics discussed:
- Standing in for Brian Kaney, Arjun Sanyal laid out why Library: the clinical reasoning resources already point at Library for their logic, and there are four places they want to reach a SQL query from — a measure, questionnaire pre-population, the inclusion criteria on a plan definition, and dynamic values in an activity definition. The framing is that SQL is just another expression language alongside FHIRPath and CQL.
- Nikolai Ryzhikov's objection was base64: you can't read the query out of the resource. John Grimes liked the idea but wanted an end-to-end example that pulls the resources together, since it's hard to see how it fits in practice.
- The tension the group kept circling: clinical reasoning is a heavily modelled space, built around named library components, manifests and packaging, and all of that is useful there. It sits badly with "I just want to run some SQL". Getting clinical reasoning to drop Library is a non-starter; making everyone who wants SQL adopt the whole library and management framework is a big lift. Nobody resolved it — the leaning was that both can exist. John Grimes argued the interface to clinical reasoning need not also be the way SQL on FHIR represents queries generally, and that the first question is what SQL on FHIR itself needs around a query.
- Eugene Vestel described using Library strictly as a CQL container: one executable block per library, each with its own URI, and you almost never evaluate a library directly — you evaluate a measure that references it. Nikolai pushed on this: does he always have to wrap an expression in a library just to run it? Yes. That produced the sharper diagnosis — CQL welds the parsing, the extraction and the evaluation together, which is why you end up at measure, whereas SQL on FHIR hands all of that to the SQL server and keeps only definitions. A separate warning: CRMI's computable/publishable/executable vocabulary is itself defined around CQL, so "executable" doesn't obviously mean anything for another language.
- Gino Canessa brought a straw man wrapping the SQL in an OperationDefinition instead, mostly because it lands you in the search API for free: make the kind query and it works through the standard _query parameter, and operations don't have to return FHIR, so CSV, NDJSON or Parquet come out the other end. He'd still never execute raw SQL from a REST call, so his preferred version is a stored procedure with the operation's parameters mapped onto the procedure's. He also floated coding SQL dialects as a tuple of dialect plus expression, since no MIME type for dialects exists and inventing a MIME parameter felt uncomfortable.
- Nikolai sketched the third option — a dedicated Query as an R6 additional resource, with the views it depends on, a mapping for view names, parameters and dialects as real fields. His argument was readability and discoverability: OperationDefinition fits the API nicely but pollutes the operation list once you have dozens of queries, and everything lands in extensions. Gino, who by his own account hates the extension mechanism, agreed it looked a lot cleaner. Nobody objected to the three coexisting — a query resource can still be packaged into a library and pointed at from an operation.