cqframework / clinical_quality_language

Clinical Quality Language (CQL) is an HL7 specification for the expression of clinical knowledge that can be used within both the Clinical Decision Support (CDS) and Clinical Quality Measurement (CQM) domains. This repository contains complementary tooling in support of that specification.
https://confluence.hl7.org/display/CDS/Clinical+Quality+Language
Apache License 2.0
251 stars 121 forks source link

Incorrect tuple equality behavior #1349

Open brynrhodes opened 3 months ago

brynrhodes commented 3 months ago

This expression currently returns false:

define Test1: Tuple { Id : 1, Name : 'John' } = Tuple { Id : 2, Name : null }

But tuples have no implied ordering, so this should be null

Test cases for this (and other tuple equality testing) are being considered for the cql-tests repository here: https://github.com/cqframework/cql-tests/pull/3

When those tests are agreed and approved, they should be used as the source for the test for this issue

JPercival commented 2 months ago

Are you certain this should be null? My reading of the spec here is that it would return false:

For tuple types, this means that equality returns true if and only if the tuples are of the same type, and the values for all elements that have values, by name, are equal.

No mention of "null". The discussion for Codes and Concepts says it uses "tuple semantics" and the example shown implies it would be false, not null.

The equal (=) operator for Codes and Concepts uses tuple equality semantics. This means that the operator will return true if and only if the values for each element by name are equal.

If either argument is null, or has different components specified, the result is null.

define "Code1": Code { system: 'http://loinc.org', code: '8480-6', version: '1.0', display: 'Systolic blood pressure' }
define "Concept1": Concept { codes: { Code1 }, display: 'Concepts' }
define "Concept2": Concept { codes: { Code1 }, display: 'More Concepts' }
define "EqualIsTrue": Code1 = Code1
define "EqualIsFalse": Concept1 = Concept2

Notice how Concept1 and Concept2 vary only by the value of display. In the example you posted the only difference is value of Name. I suppose Name may also vary by type, since it's System.Any in the latter.