clinical_quality_language icon indicating copy to clipboard operation
clinical_quality_language copied to clipboard

cql-to-elm creates ProperIn expression when ProperIncludedIn is expected

Open hossenlopp opened this issue 10 months ago • 3 comments

When updating cql-execution test data to be generated with 3.22.0 we noticed a test broke due to the ELM output changing for the following test CQL.

define NullIncludes: {1, 2, 3, 4, 5} properly included in null

In 3.12.0 this was creating a ProperIncludedIn expression for this define statement. 3.22.0 is creating a ProperIn expression instead. It seems this should still be ProperIncludedIn as it is specifically called out to be in the CQL.

hossenlopp avatar Mar 11 '25 22:03 hossenlopp

When the types are parsed as List<T> properly included in List<T> or Interval<T> properly included in Interval<T>, the generated ELM is ProperIncludedIn(List<T>, List<T>) / ProperIncludedIn(Interval<T>, Interval<T>). When the types are T properly included in List<T> or T properly included in Interval<T>, the ELM is ProperIn(T, List<T>) / ProperIn(T, Interval<T>). In the latest version of the compiler,

{1, 2, 3, 4, 5} properly included in null

is parsed as List<Integer> properly included in Interval<List<Integer>>, so the ELM is ProperIn({1, 2, 3, 4, 5}, null as Interval<List<Integer>>). One possible way to enforce ProperIncludedIn is to use

{1, 2, 3, 4, 5} properly included in null as List<Integer>

which compiles to ProperIncludedIn({1, 2, 3, 4, 5}, null as List<Integer>)

antvaset avatar Mar 20 '25 00:03 antvaset

Interesting... I'm pretty sure that Interval<List<Integer>> is not even a valid CQL type -- as the Interval type (T) is supposed to be a point (not a list). The ELM type XSD only specifies intervals of integers, decimals, quantities, dates, datetimes, and times. So it's interesting that the translator would choose to make null an invalid Integer<List<Integer>> type rather than the simpler (and valid) List<Integer>.

Thanks for the tip regarding casting null. We use that trick in other parts of our test suite. I guess we'll use it here too.

cmoesel avatar Mar 20 '25 11:03 cmoesel

The {'s', 'u', 'n'} properly included in null case is especially interesting because it auto-casts null as Interval<List<String>>. I thought maybe the compiler was mistakenly allowing Interval<List<Integer>> because Integer is a valid point type for an interval, but String is not a valid point type -- so it seems it will likely auto-cast to an interval of any type of list.

cmoesel avatar Mar 20 '25 12:03 cmoesel