Translating CQL measures into SQL on FHIR, and an API for keeping a view materialised — Aug 19, 2025
Gene — one CQL measure, two paths, two MeasureReports
Takes one CQL measure down two paths and produces a MeasureReport from each — one via CQL evaluation, one via a SQL query generated from that CQL — then puts the two reports and their timings side by side.
A quality measure isn't nuclear engineering. It's a collection of lookups and evaluations asking whether the values in a resource meet a requirement.
The prototype does the translation with an LLM; the real version would compile ELM to SQL piece by piece.
Arjun — schema stability
Nothing guarantees that
birthDatein CQL isDOBin the system you're running against. A translation that works on paper meets a mapping problem in the real world.
Gene conceded the point and turned it into a precondition: you'd have to pin the CQL to a known set of resources and to the ViewDefinitions aligned with them — his prototype quietly assumes that's already true.
Steve — which corners of CQL survive?
Gene's answer: it scales with complexity. A one-liner that identifies the diabetic patients is trivial, a thousand-line medication adherence HEDIS measure with hundreds of logical statements is another animal entirely — but if you treat CQL as a collection of operations and lookups, the same machinery should extend.
Nikolai — reframing so translation isn't the point
CQL isn't always the source of truth — sometimes the source of truth is just a report someone wants — so the value is giving people the same logic expressible as ViewDefinitions plus SQL and letting them pick per use case, since some measures are painful to run performantly over a whole population in CQL.
If CQL is the official statement of the logic, run both over the same data sets with the corner cases in — if the results match you can trust your SQL version. CQL becomes the reference implementation you test against.
Materialisation — closer to REFRESH than to re-export
Here's a ViewDefinition, here's a destination, keep it up to date, I don't care how.
Doesn't fit the export API: no output files, no formats, and you need to see the view's status or refresh it by hand. That points at a separate operational resource rather than a definitional one.
Steve was interested and asked whether this meant Postgres views or ANSI views; Nikolai said neither necessarily — sometimes it's an unlogged table, and the destination might be Postgres or ClickHouse.
Steve noted that change-data-capture adapters pushing every table change onto a Kafka topic are the same shape of problem, and worth characterising at spec level.