SQL on FHIR WG Meetings
SQL on FHIR WG Meeting — March 5, 2024
Mar 5, 2024

Topics discussed:

  • Views turned out to be useful for more than the original idea of a flat table of scalars — some people want nested structure or repeated fields — so the proposal was to label a view with its intended use. Then tooling can check the view actually matches the label, and you can look at one and tell immediately that this can be exported as a CSV while that one is a more complicated structure. Two ways to model it: an enumerated intent field on the resource, or a FHIR profile per intent. Profiles won on extensibility — new intents can be added as they emerge, with their own constraints, by anyone, from their own repository.
  • The objection was that "intent" is being asked to carry two unrelated ideas. One is about the artefact: is this identified by a URI and published in an IG, or am I handing it to a Python library to run right now? The other is about capability: is the output flat like CSV, or a nested Spark schema, or JSON text in a column? The answer was that profiles can carry both — but the mix was acknowledged rather than resolved.
  • The catch with profiles is that for the tabular case the profile would be almost empty. There's no way to express "every column is a non-repeated scalar" as a checkable constraint, so it works as a tag and nothing validates it. There is precedent for profiles that attach semantics the tooling can't enforce, and the argument that carried was one mechanism rather than two: profiles genuinely pay off in the shareable case, where the constraints are real — require the URL, require the name, require experimental to be false.
  • Nobody argued for any of this in the first version — "nothing is v1 scope except what we've got". Two practical snags noted: the ViewDefinition is a logical model rather than a resource, so it has no meta in which to declare which profiles it conforms to, and profiling logical models pokes at the corners of the FHIR tooling that are less well tested.
  • A related thread: a view runner does more than run. There's validating a ViewDefinition, inferring the schema it will produce, and just answering "can you run this at all?" — operations that stop short of executing anything, and that the spec could describe as roles you either implement or don't. It matters because layers get built on top: Pathling is being re-architected to use ViewDefinitions as its primitive, with things like aggregate running FHIRPath over the schema the first layer produced — which only works if you can infer that schema from the view.