Skip to content

Commit 11111d5

Browse files
committed
Tweaks related to quantity instance for min/max values
- Add Jira link to comment about keeping quantity unit for min/max values - Use quantityInstance more consistently for min/max values - Remove unused maxValueForInstance and minValueForInstance functions
1 parent d8d8cdc commit 11111d5

4 files changed

Lines changed: 87 additions & 176 deletions

File tree

examples/browser/cql4browsers.js

Lines changed: 43 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,7 @@ class Interval {
22132213
// "If the low boundary of the interval is closed and null, this operator returns the minimum
22142214
// value for the point type of the interval."
22152215
if (this.low == null) {
2216-
const quantityInstance = this.high && this.pointType == elmTypes_1.ELM_QUANTITY_TYPE ? this.high : undefined;
2216+
const quantityInstance = getQuantityInstanceForMinMax(this);
22172217
const minValue = (0, math_1.minValueForType)(this.pointType, quantityInstance);
22182218
if (this.lowClosed || minValue == null) {
22192219
return minValue;
@@ -2222,7 +2222,7 @@ class Interval {
22222222
// "If the low boundary of the interval is open and null, this operator returns an
22232223
// uncertainty from the minimum value for the point type of the interval to the high
22242224
// boundary of the interval (using End operator semantics to determine the high boundary)."
2225-
const end = ((end) => (end.isUncertainty ? end.high : end))(this.high == null ? (0, math_1.maxValueForType)(this.pointType) : this.end());
2225+
const end = ((end) => (end.isUncertainty ? end.high : end))(this.high == null ? (0, math_1.maxValueForType)(this.pointType, quantityInstance) : this.end());
22262226
return new uncertainty_1.Uncertainty(minValue, end);
22272227
}
22282228
}
@@ -2236,7 +2236,7 @@ class Interval {
22362236
// "If the high boundary of the interval is closed and null, this operator returns the maximum
22372237
// value for the point type of the interval."
22382238
if (this.high == null) {
2239-
const quantityInstance = this.low && this.pointType == elmTypes_1.ELM_QUANTITY_TYPE ? this.low : undefined;
2239+
const quantityInstance = getQuantityInstanceForMinMax(this);
22402240
const maxValue = (0, math_1.maxValueForType)(this.pointType, quantityInstance);
22412241
if (this.highClosed || maxValue == null) {
22422242
return maxValue;
@@ -2245,7 +2245,7 @@ class Interval {
22452245
// "If the high boundary of the interval is open and null, this operator returns an
22462246
// uncertainty from the low boundary of the interval (using Start operator semantics to
22472247
// determine the low boundary) to the maximum value for the point type of the interval."
2248-
const start = ((start) => (start.isUncertainty ? start.low : start))(this.low == null ? (0, math_1.minValueForType)(this.pointType) : this.start());
2248+
const start = ((start) => (start.isUncertainty ? start.low : start))(this.low == null ? (0, math_1.minValueForType)(this.pointType, quantityInstance) : this.start());
22492249
return new uncertainty_1.Uncertainty(start, maxValue);
22502250
}
22512251
}
@@ -2323,13 +2323,7 @@ class Interval {
23232323
// https://build.fhir.org/ig/HL7/cql/09-b-cqlreference.html#size
23242324
getPointSize() {
23252325
// "... point-size is determined by successor of minimum T - minimum T"
2326-
let minValue;
2327-
if (this.pointType != null && this.pointType !== elmTypes_1.ELM_ANY_TYPE) {
2328-
minValue = (0, math_1.minValueForType)(this.pointType, this.pointType === elmTypes_1.ELM_QUANTITY_TYPE ? (this.low ?? this.high) : undefined);
2329-
}
2330-
else {
2331-
minValue = (0, math_1.minValueForInstance)(this.low ?? this.high);
2332-
}
2326+
let minValue = (0, math_1.minValueForType)(this.pointType, getQuantityInstanceForMinMax(this));
23332327
// due to floating point issues in JS, we must use 0.0 for Decimal/Quantity instead of min
23342328
if (minValue === limits_1.MIN_FLOAT_VALUE) {
23352329
minValue = 0.0;
@@ -2365,9 +2359,10 @@ class Interval {
23652359
const lowClosed = this.lowClosed || this.low != null;
23662360
const highClosed = this.highClosed || this.high != null;
23672361
if (this.pointType != null && this.pointType !== elmTypes_1.ELM_ANY_TYPE) {
2362+
const quantityInstance = getQuantityInstanceForMinMax(this);
23682363
let low;
23692364
if (this.lowClosed && this.low == null) {
2370-
low = (0, math_1.minValueForType)(this.pointType);
2365+
low = (0, math_1.minValueForType)(this.pointType, quantityInstance);
23712366
}
23722367
else if (!this.lowClosed && this.low != null) {
23732368
low = (0, math_1.successor)(this.low, this.pointType);
@@ -2377,7 +2372,7 @@ class Interval {
23772372
}
23782373
let high;
23792374
if (this.highClosed && this.high == null) {
2380-
high = (0, math_1.maxValueForType)(this.pointType);
2375+
high = (0, math_1.maxValueForType)(this.pointType, quantityInstance);
23812376
}
23822377
else if (!this.highClosed && this.high != null) {
23832378
high = (0, math_1.predecessor)(this.high, this.pointType);
@@ -2386,10 +2381,10 @@ class Interval {
23862381
high = this.high;
23872382
}
23882383
if (low == null) {
2389-
low = new uncertainty_1.Uncertainty((0, math_1.minValueForType)(this.pointType), high);
2384+
low = new uncertainty_1.Uncertainty((0, math_1.minValueForType)(this.pointType, quantityInstance), high);
23902385
}
23912386
if (high == null) {
2392-
high = new uncertainty_1.Uncertainty(low, (0, math_1.maxValueForType)(this.pointType));
2387+
high = new uncertainty_1.Uncertainty(low, (0, math_1.maxValueForType)(this.pointType, quantityInstance));
23932388
}
23942389
return new Interval(low, high, lowClosed, highClosed);
23952390
}
@@ -2416,36 +2411,61 @@ exports.Interval = Interval;
24162411
// meaning? This does affect test expectations and representation of returned results for callers.
24172412
function normalizeInterval(interval) {
24182413
const ivl = interval.copy();
2414+
const minValue = (0, math_1.minValueForType)(ivl.pointType, getQuantityInstanceForMinMax(ivl));
2415+
const maxValue = (0, math_1.maxValueForType)(ivl.pointType, getQuantityInstanceForMinMax(ivl));
24192416
if (ivl.low != null && ivl.lowClosed !== false) {
24202417
if (ivl.low.isUncertainty) {
2421-
const minValue = (0, math_1.minValueForInstance)(ivl.low.low);
2422-
const maxValue = (0, math_1.maxValueForInstance)(ivl.low.low);
24232418
if (cmp.equals(ivl.low.low, minValue) &&
24242419
(cmp.equals(ivl.low.high, maxValue) || cmp.equals(ivl.low.high, ivl.high))) {
24252420
ivl.low = null;
24262421
ivl.lowClosed = false;
24272422
}
24282423
}
2429-
else if (cmp.equals(ivl.low, (0, math_1.minValueForInstance)(ivl.low))) {
2424+
else if (cmp.equals(ivl.low, minValue)) {
24302425
ivl.low = null;
24312426
}
24322427
}
24332428
if (ivl.high != null && ivl.highClosed !== false) {
24342429
if (ivl.high.isUncertainty) {
2435-
const minValue = (0, math_1.minValueForInstance)(ivl.high.low);
2436-
const maxValue = (0, math_1.maxValueForInstance)(ivl.high.low);
24372430
if (cmp.equals(ivl.high.high, maxValue) &&
24382431
(cmp.equals(ivl.high.low, minValue) || cmp.equals(ivl.high.low, ivl.low))) {
24392432
ivl.high = null;
24402433
ivl.highClosed = false;
24412434
}
24422435
}
2443-
else if (cmp.equals(ivl.high, (0, math_1.maxValueForInstance)(ivl.high))) {
2436+
else if (cmp.equals(ivl.high, maxValue)) {
24442437
ivl.high = null;
24452438
}
24462439
}
24472440
return ivl;
24482441
}
2442+
function getQuantityInstanceForMinMax(ivl) {
2443+
if (ivl?.pointType !== elmTypes_1.ELM_QUANTITY_TYPE) {
2444+
return;
2445+
}
2446+
if (ivl.low?.isQuantity) {
2447+
return ivl.low;
2448+
}
2449+
if (ivl.high?.isQuantity) {
2450+
return ivl.high;
2451+
}
2452+
if (ivl.low?.isUncertainty) {
2453+
if (ivl.low.low?.isQuantity) {
2454+
return ivl.low.low;
2455+
}
2456+
if (ivl.low.high?.isQuantity) {
2457+
return ivl.low.high;
2458+
}
2459+
}
2460+
if (ivl.high?.isUncertainty) {
2461+
if (ivl.high.low?.isQuantity) {
2462+
return ivl.high.low;
2463+
}
2464+
if (ivl.high.high?.isQuantity) {
2465+
return ivl.high.high;
2466+
}
2467+
}
2468+
}
24492469
function performConversionIfNecessary(left, right) {
24502470
if (left.pointType === elmTypes_1.ELM_DATE_TYPE && right.pointType === elmTypes_1.ELM_DATETIME_TYPE) {
24512471
left = new Interval(left.low?.getDateTime(), left.high?.getDateTime(), left.lowClosed, left.highClosed, elmTypes_1.ELM_DATETIME_TYPE);
@@ -9811,9 +9831,7 @@ exports.subtract = subtract;
98119831
exports.limitDecimalPrecision = limitDecimalPrecision;
98129832
exports.successor = successor;
98139833
exports.predecessor = predecessor;
9814-
exports.maxValueForInstance = maxValueForInstance;
98159834
exports.maxValueForType = maxValueForType;
9816-
exports.minValueForInstance = minValueForInstance;
98179835
exports.minValueForType = minValueForType;
98189836
exports.decimalAdjust = decimalAdjust;
98199837
exports.decimalOrNull = decimalOrNull;
@@ -10147,37 +10165,6 @@ function predecessor(val, type, precision) {
1014710165
return null;
1014810166
}
1014910167
}
10150-
function maxValueForInstance(val) {
10151-
if (typeof val === 'number') {
10152-
if (Number.isInteger(val)) {
10153-
return limits_1.MAX_INT_VALUE;
10154-
}
10155-
else {
10156-
return limits_1.MAX_FLOAT_VALUE;
10157-
}
10158-
}
10159-
else if (typeof val === 'bigint') {
10160-
return limits_1.MAX_LONG_VALUE;
10161-
}
10162-
else if (val && val.isTime && val.isTime()) {
10163-
return datetime_1.MAX_TIME_VALUE?.copy();
10164-
}
10165-
else if (val && val.isDateTime) {
10166-
return datetime_1.MAX_DATETIME_VALUE?.copy();
10167-
}
10168-
else if (val && val.isDate) {
10169-
return datetime_1.MAX_DATE_VALUE?.copy();
10170-
}
10171-
else if (val && val.isQuantity) {
10172-
// Although the spec says max Quantity has unit '1', it doesn't make sense to change the unit,
10173-
// especially if this is being used in the context of an interval or uncertainty since the
10174-
// left and right sides need to be comparable in those cases.
10175-
return new quantity_1.Quantity(limits_1.MAX_FLOAT_VALUE, val.unit || '1');
10176-
}
10177-
else {
10178-
return null;
10179-
}
10180-
}
1018110168
function maxValueForType(type, quantityInstance) {
1018210169
switch (type) {
1018310170
case elmTypes_1.ELM_INTEGER_TYPE:
@@ -10196,42 +10183,12 @@ function maxValueForType(type, quantityInstance) {
1019610183
// Although the spec says max Quantity has unit '1', it doesn't make sense to change the unit,
1019710184
// especially if this is being used in the context of an interval or uncertainty since the
1019810185
// left and right sides need to be comparable in those cases.
10186+
// See: https://jira.hl7.org/browse/FHIR-57935
1019910187
return new quantity_1.Quantity(limits_1.MAX_FLOAT_VALUE, quantityInstance?.unit || '1');
1020010188
}
1020110189
}
1020210190
return null;
1020310191
}
10204-
function minValueForInstance(val) {
10205-
if (typeof val === 'number') {
10206-
if (Number.isInteger(val)) {
10207-
return limits_1.MIN_INT_VALUE;
10208-
}
10209-
else {
10210-
return limits_1.MIN_FLOAT_VALUE;
10211-
}
10212-
}
10213-
else if (typeof val === 'bigint') {
10214-
return limits_1.MIN_LONG_VALUE;
10215-
}
10216-
else if (val && val.isTime && val.isTime()) {
10217-
return datetime_1.MIN_TIME_VALUE?.copy();
10218-
}
10219-
else if (val && val.isDateTime) {
10220-
return datetime_1.MIN_DATETIME_VALUE?.copy();
10221-
}
10222-
else if (val && val.isDate) {
10223-
return datetime_1.MIN_DATE_VALUE?.copy();
10224-
}
10225-
else if (val && val.isQuantity) {
10226-
// Although the spec says max Quantity has unit '1', it doesn't make sense to change the unit,
10227-
// especially if this is being used in the context of an interval or uncertainty since the
10228-
// left and right sides need to be comparable in those cases.
10229-
return new quantity_1.Quantity(limits_1.MIN_FLOAT_VALUE, val.unit || '1');
10230-
}
10231-
else {
10232-
return null;
10233-
}
10234-
}
1023510192
function minValueForType(type, quantityInstance) {
1023610193
switch (type) {
1023710194
case elmTypes_1.ELM_INTEGER_TYPE:
@@ -10250,6 +10207,7 @@ function minValueForType(type, quantityInstance) {
1025010207
// Although the spec says max Quantity has unit '1', it doesn't make sense to change the unit,
1025110208
// especially if this is being used in the context of an interval or uncertainty since the
1025210209
// left and right sides need to be comparable in those cases.
10210+
// See: https://jira.hl7.org/browse/FHIR-57935
1025310211
return new quantity_1.Quantity(limits_1.MIN_FLOAT_VALUE, quantityInstance?.unit || '1');
1025410212
}
1025510213
}

0 commit comments

Comments
 (0)