Topics discussed:
- The
$runoperation was refactored to follow the same pattern as CQL's evaluate. The confusion that had held it up was a small one: a Parameters parameter can carry a whole resource, not just a data type — which is the unique thing Parameters can do. There's also an open ticket to let$runwrap query results in a Parameters resource as an additional output format, so the response is valid FHIR rather than something that isn't FHIR at all. Not the default, just another format. - The bigger argument was whether SQL on FHIR should bridge to the clinical quality world's evaluate operations. The CQL library evaluate is a poor fit — its name is canonical and far too far down the road to change, and its parameters are described as "defined in the CQL library". Measure evaluate is more generic, and SQL isn't hard-coded in it. The argument for reusing it: wrapping logic in a Library is precisely what lets you swap CQL for SQL — run the library, get the MeasureReport back, and it shouldn't matter whether SQL or JavaScript executed underneath. The argument against: Measure drags in numerators, denominators, stratifiers, populations, scoring types — a whole DSL — and adopting it means a runner has to understand all of it. Left open, with research homework on both sides.
- The counterweight to all of it was the temptation to do nothing clever: SQL on FHIR could just ship
$runand$exportand let people do whatever they want. Someone with a quality-measures background agreed, and pointed out that not everything is a measure — sometimes you just want every patient who had an MI in a date range, broken out by facility and physician group, and you don't want the burden of a quality measure's structure to ask that. The practical asymmetry was put bluntly: an organisation might have hundreds of people who could write that in SQL, and five who could write it in CQL. - The two-layer approach that makes the SQL simple: use ViewDefinitions to pull out all the data requirements into flat rectangular tables, then compute the actual answer in plain SQL over those tables. Because the SQL never reaches into FHIR to do the FHIR-specific work, it stays simple. Cited as what NCQA were experimenting with — breaking the CQL-to-SQL problem into those two halves. It also came with a caution from experience: hand-translating measures to efficient SQL a dozen times showed the two share maybe eighty per cent of their declarative parts, but the other twenty per cent needs different decisions, because efficient SQL requires thinking the SQL way rather than the eager, one-patient-at-a-time way.
- A concrete design problem with no clean answer:
$runis one generic operation over any library, and the library declares its own parameters, so there's no machine-readable way to say "validate these parameters against this library's parameter definitions". Profiles bind at OperationDefinition time, so the only conformant route is a derived OperationDefinition per library — exactly what named queries do, since a named query is just an OperationDefinition of type query. That may be too much ceremony, in which case it stays as prose in the spec. The same nesting is why GET is awkward: you could invent alib.param=valuesyntax, but it gets verbose fast and can't group repeats, so POST-only is the likely landing.