Skip to content

Commit

Permalink
Fix tuple equality with null values
Browse files Browse the repository at this point in the history
Previously, if tuples had the same fields, and at least one field had a null value on one tuple and a non-null value on the other, then:
* if the null/non-null field came after a field with different values, it returned false (which is correct)
* if the null/non-null field came before a field with different values, it returned null (which is incorrect)

Now it will return the correct answer regardless of where the null/non-null field is.
  • Loading branch information
cmoesel committed Nov 13, 2024
1 parent 12a8ce0 commit 2f61fef
Show file tree
Hide file tree
Showing 6 changed files with 841 additions and 479 deletions.
3 changes: 2 additions & 1 deletion examples/browser/cql4browsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8697,14 +8697,15 @@ function deepCompareKeysAndValues(a, b, comparisonFunction) {
const comparisonResult = comparisonFunction(a[key], b[key]);
if (comparisonResult === null) {
shouldReturnNull = true;
return true;
}
return comparisonResult;
});
}
else {
finalComparisonResult = false;
}
if (shouldReturnNull) {
if (finalComparisonResult && shouldReturnNull) {
return null;
}
return finalComparisonResult;
Expand Down
3 changes: 2 additions & 1 deletion src/util/comparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,15 @@ function deepCompareKeysAndValues(a: any, b: any, comparisonFunction: any) {
const comparisonResult = comparisonFunction(a[key], b[key]);
if (comparisonResult === null) {
shouldReturnNull = true;
return true;
}
return comparisonResult;
});
} else {
finalComparisonResult = false;
}

if (shouldReturnNull) {
if (finalComparisonResult && shouldReturnNull) {
return null;
}
return finalComparisonResult;
Expand Down
6 changes: 6 additions & 0 deletions test/elm/comparison/comparison-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ describe('Equal', () => {

it('should identify uncertian tuples with same fields but one has a null field', async function () {
should(await this.uncertTuplesWithNullFieldOnOne.exec(this.ctx)).be.null();
should(await this.uncertTuplesWithNullFieldOnFirstOne.exec(this.ctx)).be.null();
});

it('should identify unequal tuples with different values but one has a null field', async function () {
should(await this.uneqTuplesWithNullFieldOnOne.exec(this.ctx)).be.false();
should(await this.uneqTuplesWithNullFieldOnFirstOne.exec(this.ctx)).be.false();
});

it('should identify equal/unequal DateTimes in same timezone', async function () {
Expand Down
3 changes: 3 additions & 0 deletions test/elm/comparison/data.cql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ define UneqTuples: Tuple{a: 1, b: Tuple{c: 1}} = Tuple{a: 1, b: Tuple{c: -1}}
define EqTuplesWithNullFields: Tuple{a: 'Hello', b: null} = Tuple{a: 'Hello', b: null}
define UneqTuplesWithNullFields: Tuple{a: 'Hello', b: null} = Tuple{a: 'Goodbye', b: null}
define UncertTuplesWithNullFieldOnOne: Tuple{a: 'Hello', b: null} = Tuple{a: 'Hello', b: 'null'}
define UncertTuplesWithNullFieldOnFirstOne: Tuple{a: null, b: 'Goodbye'} = Tuple{a: 'Hello', b: 'Goodbye'}
define UneqTuplesWithNullFieldOnOne: Tuple{a: 'Hello', b: null} = Tuple{a: 'Goodbye', b: 'null'}
define UneqTuplesWithNullFieldOnFirstOne: Tuple{a: null, b: 'Hello'} = Tuple{a: 'null', b: 'Goodbye'}
define EqDateTimes: DateTime(2000, 3, 15, 13, 30, 25, 200, +1.0) = DateTime(2000, 3, 15, 13, 30, 25, 200, +1.0)
define UneqDateTimes: DateTime(2000, 3, 15, 13, 30, 25, 200, +1.0) = DateTime(2000, 3, 15, 13, 30, 25, 201, +1.0)
define EqDateTimesTZ: DateTime(2000, 3, 15, 23, 30, 25, 200, +1.0) = DateTime(2000, 3, 16, 2, 30, 25, 200, +4.0)
Expand Down
Loading

0 comments on commit 2f61fef

Please sign in to comment.