Stream: cql
Topic: Single value from function changes to a list
Michael Riley (Jun 03 2021 at 18:15):
I've been writing a script to capture an index date of a covid immunization with the FHIR library on cql. But I'm having an issue with typing of returns from functions. I'm working from this initial script definition
library "TestExampleOfFunction" version '0.0.1'
using FHIR version '4.0.0'
include "FHIRHelpers" version '4.0.0' called FHIRHelpers
codesystem "ICD-10-CM": 'http://hl7.org/fhir/sid/icd-10-cm'
codesystem "CVX": 'http://hl7.org/fhir/sid/cvx'
codesystem "RxNorm": 'http://www.nlm.nih.gov/research/umls/rxnorm'
codesystem "NDC": 'http://hl7.org/fhir/sid/ndc'
codesystem "CPT": 'http://www.ama-assn.org/go/cpt'
*Covid Vaccine Drug Exposure definition ommited for space*
context Patient
define "CovidImmunization": [Immunization: "Covid Vaccine Drug Exposure".codes]
define "MostRecentCovidI": MostRecentImmunizationDT("CovidImmunization")
define function MostRecentImmunizationDT(ImmunizationList List<FHIR.Immunization>):
from ImmunizationList I
let result: Last(ImmunizationList I sort by (occurrence as FHIR.dateTime).value asc)
return (result.occurrence as FHIR.dateTime).value
define "testRange":
Interval[ "MostRecentCovidI" + 1 day, "MostRecentCovidI" + 42 days]
Now when I run this definition, I get a weird typing on "MostRecentCovidI" on the testRange definition
Error [53:13] Could not resolve call to operator Add with signature (list<System.DateTime>,System.Quantity).
So it seems like the 'result' variable comes back as a tuple of a list with a quantity, which seems very odd, I was expecting a FHIR.dateTime.value which would be a system.DateTime in cql.
So I try and reduce the result scope variable in the function definition itself and add another Last clause in the definition like so.
define function MostRecentImmunizationDT(ImmunizationList List<FHIR.Immunization>):
from ImmunizationList I
let result: Last(ImmunizationList I sort by (occurrence as FHIR.dateTime).value asc)
return Last((result.occurrence as FHIR.dateTime).value)
This generates an error saying that the return value is already a System.DateTime, and the Last function cannot work on it.
Error [50:12] Could not resolve call to operator Last with signature (System.DateTime).
So the return is already defined as a System.DateTime, but the only way I'm able to move forward on my script is to change my top level definition to
define "MostRecentCovidI": Last(MostRecentImmunizationDT("CovidImmunization"))
Which makes no sense, the return type should have been a System.DateTime not a list. What's going on here? Is the return clause not firing correctly? Is this a poor way to craft functions? And what's a better way to check runtime types of defines?
JP (Jun 03 2021 at 19:32):
This code is a bit redundant in the sense that you're effectively generating the cross-product of ImmunizationList with itself
define function MostRecentImmunizationDT(ImmunizationList List<FHIR.Immunization>):
from ImmunizationList I
let result: Last(ImmunizationList I sort by (occurrence as FHIR.dateTime).value asc)
return (result.occurrence as FHIR.dateTime).value
I think what you're looking for is:
define function MostRecentImmunizationDT(ImmunizationList List<FHIR.Immunization>):
Last(ImmunizationList I
return (I.occurrence as FHIR.dateTime).value
sort asc)
That creates a List of dateTime ordered earliest to latest, then gets the last one.
JP (Jun 03 2021 at 19:34):
As far as this error is concerned, the latter parameter that's showing as a Quantity is due to first parameter being a List and causing some type inference to blow up. There might be a way to improve the messaging in the future in the translator.
Error [53:13] Could not resolve call to operator Add with signature (list<System.DateTime>,System.Quantity).
Michael Riley (Jun 04 2021 at 14:57):
Thank you for the help here. I will be more careful with the from clause, I thought I still needed the multi-query from clause to define the retrieval, as i wanted my return clause to be very clear in the function. but clearly you can just run the filters, and access down the List via an INTERNAL return clause.
Last updated: Apr 12 2022 at 19:14 UTC