diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/LibraryBuilder.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/LibraryBuilder.java index 4ece6bfc9..9e66f360d 100644 --- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/LibraryBuilder.java +++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/LibraryBuilder.java @@ -1098,12 +1098,48 @@ public Invocation resolveProperContainsInvocation( return resolveBinaryInvocation("System", "ProperContains", properContains); } + private int getTypeScore(OperatorResolution resolution) { + int typeScore = ConversionMap.ConversionScore.ExactMatch.score(); + for (DataType operand : + resolution.getOperator().getSignature().getOperandTypes()) { + typeScore += ConversionMap.getTypePrecedenceScore(operand); + } + + return typeScore; + } + private Expression lowestScoringInvocation(Invocation primary, Invocation secondary) { if (primary != null) { if (secondary != null) { if (secondary.getResolution().getScore() < primary.getResolution().getScore()) { return secondary.getExpression(); + } else if (primary.getResolution().getScore() < secondary.getResolution().getScore()) { + return primary.getExpression(); + } + if (primary.getResolution().getScore() == secondary.getResolution().getScore()) { + int primaryTypeScore = getTypeScore(primary.getResolution()); + int secondaryTypeScore = getTypeScore(secondary.getResolution()); + + if (secondaryTypeScore < primaryTypeScore) { + return secondary.getExpression(); + } else if (primaryTypeScore < secondaryTypeScore) { + return primary.getExpression(); + } else { + // ERROR: + StringBuilder message = new StringBuilder("Call to operator ") + .append(primary.getResolution().getOperator().getName()) + .append("/") + .append(secondary.getResolution().getOperator().getName()) + .append(" is ambiguous with: ") + .append("\n - ") + .append(primary.getResolution().getOperator().getName()) + .append(primary.getResolution().getOperator().getSignature()) + .append("\n - ") + .append(secondary.getResolution().getOperator().getName()) + .append(secondary.getResolution().getOperator().getSignature()); + throw new IllegalArgumentException(message.toString()); + } } } diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorEntry.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorEntry.java index e0a3bb186..9c8f87d04 100644 --- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorEntry.java +++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorEntry.java @@ -68,6 +68,24 @@ private Signature getInvocationSignature(Signature callSignature, Signature oper return callSignature; } + private OperatorResolution getOperatorResolution( + Operator operator, + Signature callSignature, + Signature invocationSignature, + ConversionMap conversionMap, + OperatorMap operatorMap, + boolean allowPromotionAndDemotion, + boolean requireConversions) { + Conversion[] conversions = getConversions( + callSignature, operator.getSignature(), conversionMap, operatorMap, allowPromotionAndDemotion); + OperatorResolution result = new OperatorResolution( + operator, conversions); + if (requireConversions && conversions == null) { + return null; + } + return result; + } + public List resolve( CallContext callContext, ConversionMap conversionMap, OperatorMap operatorMap) { List results = null; @@ -75,9 +93,19 @@ public List resolve( // Attempt exact match against this signature if (operator.getSignature().equals(invocationSignature)) { - results = new ArrayList<>(); - results.add(new OperatorResolution(operator)); - return results; + OperatorResolution result = getOperatorResolution( + operator, + callContext.getSignature(), + invocationSignature, + conversionMap, + operatorMap, + callContext.getAllowPromotionAndDemotion(), + false); + if (result != null) { + results = new ArrayList<>(); + results.add(result); + return results; + } } // Attempt to resolve against sub signatures @@ -85,33 +113,65 @@ public List resolve( // If no subsignatures match, attempt subType match against this signature if (results == null && operator.getSignature().isSuperTypeOf(invocationSignature)) { - results = new ArrayList<>(); - results.add(new OperatorResolution(operator)); + OperatorResolution result = getOperatorResolution( + operator, + callContext.getSignature(), + invocationSignature, + conversionMap, + operatorMap, + callContext.getAllowPromotionAndDemotion(), + false); + if (result != null) { + results = new ArrayList<>(); + results.add(result); + return results; + } } if (results == null && conversionMap != null) { // Attempt to find a conversion path from the call signature to the target signature - Conversion[] conversions = - new Conversion[operator.getSignature().getSize()]; - boolean isConvertible = callContext - .getSignature() - .isConvertibleTo( - operator.getSignature(), - conversionMap, - operatorMap, - callContext.getAllowPromotionAndDemotion(), - conversions); - if (isConvertible) { - OperatorResolution resolution = new OperatorResolution(operator); - resolution.setConversions(conversions); - results = new ArrayList<>(); - results.add(resolution); + OperatorResolution result = getOperatorResolution( + operator, + callContext.getSignature(), + invocationSignature, + conversionMap, + operatorMap, + callContext.getAllowPromotionAndDemotion(), + true); + if (result != null) { + if (results == null) { + results = new ArrayList<>(); + } + results.add(result); } } return results; } + private Conversion[] getConversions( + Signature callSignature, + Signature operatorSignature, + ConversionMap conversionMap, + OperatorMap operatorMap, + boolean allowPromotionAndDemotion) { + if (callSignature == null + || operatorSignature == null + || callSignature.getSize() != operatorSignature.getSize()) { + return null; + } + + Conversion[] conversions = new Conversion[callSignature.getSize()]; + boolean isConvertible = callSignature.isConvertibleTo( + operatorSignature, conversionMap, operatorMap, allowPromotionAndDemotion, conversions); + + if (isConvertible) { + return conversions; + } + + return null; + } + private SignatureNodes subSignatures = new SignatureNodes(); public boolean hasSubSignatures() { diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorResolution.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorResolution.java index 7ca38d7d6..507429091 100644 --- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorResolution.java +++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/model/OperatorResolution.java @@ -7,8 +7,11 @@ public class OperatorResolution { public OperatorResolution() {} - public OperatorResolution(Operator operator) { + public OperatorResolution(Operator operator, Conversion[] conversions) { this.operator = operator; + if (conversions != null) { + setConversions(conversions); + } } private Operator operator; diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/TranslationTests.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/TranslationTests.java index 85cb2a424..808511f6d 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/TranslationTests.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/TranslationTests.java @@ -17,6 +17,8 @@ import java.util.stream.Collectors; import org.cqframework.cql.elm.tracking.TrackBack; import org.hamcrest.Matchers; +import org.hl7.cql.model.IntervalType; +import org.hl7.cql.model.SimpleType; import org.hl7.cql_annotations.r1.CqlToElmInfo; import org.hl7.elm.r1.*; import org.junit.jupiter.api.Disabled; @@ -329,6 +331,81 @@ void multiThreadedTranslation() throws IOException { CompletableFuture.allOf(cfs).join(); } + @Test + void resolutionProperlyIncludesTests() throws IOException { + final CqlTranslator translator = TestUtils.runSemanticTest("ResolutionTests/ProperlyIncludesTests.cql", 0); + Library compiledLibrary = translator.getTranslatedLibrary().getLibrary(); + List statements = compiledLibrary.getStatements().getDef(); + + assertThat(statements.size(), equalTo(5)); + + ExpressionDef test = statements.get(0); + assertThat(test.getExpression(), instanceOf(ProperContains.class)); + ProperContains properContains = (ProperContains)test.getExpression(); + assertThat(properContains.getOperand().get(0), instanceOf(Interval.class)); + Interval interval = (Interval)properContains.getOperand().get(0); + assertThat(interval.getResultType(), instanceOf(IntervalType.class)); + IntervalType intervalType = (IntervalType)interval.getResultType(); + assertThat(intervalType.getPointType(), instanceOf(SimpleType.class)); + SimpleType pointType = (SimpleType)intervalType.getPointType(); + assertThat(pointType.getName(), equalTo("System.Integer")); + assertThat(properContains.getOperand().get(1), instanceOf(As.class)); + As _as = (As)properContains.getOperand().get(1); + assertThat(_as.getAsType().toString(), equalTo("{urn:hl7-org:elm-types:r1}Integer")); + assertThat(_as.getOperand(), instanceOf(Null.class)); + + test = statements.get(1); + assertThat(test.getExpression(), instanceOf(ProperContains.class)); + properContains = (ProperContains)test.getExpression(); + assertThat(properContains.getOperand().get(0), instanceOf(Interval.class)); + interval = (Interval)properContains.getOperand().get(0); + assertThat(interval.getResultType(), instanceOf(IntervalType.class)); + intervalType = (IntervalType)interval.getResultType(); + assertThat(intervalType.getPointType(), instanceOf(SimpleType.class)); + pointType = (SimpleType)intervalType.getPointType(); + assertThat(pointType.getName(), equalTo("System.Integer")); + assertThat(properContains.getOperand().get(1), instanceOf(As.class)); + _as = (As)properContains.getOperand().get(1); + assertThat(_as.getAsType().toString(), equalTo("{urn:hl7-org:elm-types:r1}Integer")); + assertThat(_as.getOperand(), instanceOf(Null.class)); + + test = statements.get(2); + assertThat(test.getExpression(), instanceOf(ProperContains.class)); + properContains = (ProperContains)test.getExpression(); + assertThat(properContains.getOperand().get(0), instanceOf(Interval.class)); + interval = (Interval)properContains.getOperand().get(0); + assertThat(interval.getResultType(), instanceOf(IntervalType.class)); + intervalType = (IntervalType)interval.getResultType(); + assertThat(intervalType.getPointType(), instanceOf(SimpleType.class)); + pointType = (SimpleType)intervalType.getPointType(); + assertThat(pointType.getName(), equalTo("System.Any")); + assertThat(properContains.getOperand().get(1), instanceOf(Null.class)); + + test = statements.get(3); + assertThat(test.getExpression(), instanceOf(ProperContains.class)); + properContains = (ProperContains)test.getExpression(); + assertThat(properContains.getOperand().get(0), instanceOf(Interval.class)); + interval = (Interval)properContains.getOperand().get(0); + assertThat(interval.getResultType(), instanceOf(IntervalType.class)); + intervalType = (IntervalType)interval.getResultType(); + assertThat(intervalType.getPointType(), instanceOf(SimpleType.class)); + pointType = (SimpleType)intervalType.getPointType(); + assertThat(pointType.getName(), equalTo("System.Any")); + assertThat(properContains.getOperand().get(1), instanceOf(Null.class)); + + test = statements.get(4); + assertThat(test.getExpression(), instanceOf(ProperContains.class)); + properContains = (ProperContains)test.getExpression(); + assertThat(properContains.getOperand().get(0), instanceOf(Interval.class)); + interval = (Interval)properContains.getOperand().get(0); + assertThat(interval.getResultType(), instanceOf(IntervalType.class)); + intervalType = (IntervalType)interval.getResultType(); + assertThat(intervalType.getPointType(), instanceOf(SimpleType.class)); + pointType = (SimpleType)intervalType.getPointType(); + assertThat(pointType.getName(), equalTo("System.Integer")); + assertThat(properContains.getOperand().get(1), instanceOf(As.class)); + } + @Test void hidingVariousUseCases() throws IOException { final CqlTranslator translator = TestUtils.runSemanticTest("HidingTests/TestHidingVariousUseCases.cql", 0); diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r4/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r4/BaseTest.java index 27abd12d5..c6227e015 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r4/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r4/BaseTest.java @@ -55,10 +55,10 @@ void fhirTiming() throws IOException { ExpressionDef def = (ExpressionDef) visitFile("fhir/r4/TestFHIRTiming.cql"); // Query-> // where-> - // IncludedIn-> + // In-> // left-> - // ToInterval() - // As(fhir:Period) -> + // ToDateTime() + // As(fhir:dateTime) -> // Property(P.performed) // right-> MeasurementPeriod Query query = (Query) def.getExpression(); @@ -69,16 +69,16 @@ void fhirTiming() throws IOException { Retrieve request = (Retrieve) source.getExpression(); assertThat(request.getDataType(), quickDataType("Procedure")); - // Then check that the where an IncludedIn with a ToInterval as the left operand + // Then check that the where is an In with a ToDateTime as the left operand Expression where = query.getWhere(); - assertThat(where, instanceOf(IncludedIn.class)); - IncludedIn includedIn = (IncludedIn) where; - assertThat(includedIn.getOperand().get(0), instanceOf(FunctionRef.class)); - FunctionRef functionRef = (FunctionRef) includedIn.getOperand().get(0); - assertThat(functionRef.getName(), is("ToInterval")); + assertThat(where, instanceOf(In.class)); + In in = (In) where; + assertThat(in.getOperand().get(0), instanceOf(FunctionRef.class)); + FunctionRef functionRef = (FunctionRef) in.getOperand().get(0); + assertThat(functionRef.getName(), is("ToDateTime")); assertThat(functionRef.getOperand().get(0), instanceOf(As.class)); As asExpression = (As) functionRef.getOperand().get(0); - assertThat(asExpression.getAsType().getLocalPart(), is("Period")); + assertThat(asExpression.getAsType().getLocalPart(), is("dateTime")); assertThat(asExpression.getOperand(), instanceOf(Property.class)); Property property = (Property) asExpression.getOperand(); assertThat(property.getScope(), is("P")); diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r401/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r401/BaseTest.java index 37aea3a22..84b66898d 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r401/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/r401/BaseTest.java @@ -59,10 +59,10 @@ void fhirTiming() throws IOException { ExpressionDef def = (ExpressionDef) visitFile("fhir/r401/TestFHIRTiming.cql"); // Query-> // where-> - // IncludedIn-> + // In-> // left-> - // ToInterval() - // As(fhir:Period) -> + // ToDateTime() + // As(fhir:dateTime) -> // Property(P.performed) // right-> MeasurementPeriod Query query = (Query) def.getExpression(); @@ -73,16 +73,16 @@ void fhirTiming() throws IOException { Retrieve request = (Retrieve) source.getExpression(); assertThat(request.getDataType(), quickDataType("Procedure")); - // Then check that the where an IncludedIn with a ToInterval as the left operand + // Then check that the where is an In with a ToDateTime as the left operand Expression where = query.getWhere(); - assertThat(where, instanceOf(IncludedIn.class)); - IncludedIn includedIn = (IncludedIn) where; - assertThat(includedIn.getOperand().get(0), instanceOf(FunctionRef.class)); - FunctionRef functionRef = (FunctionRef) includedIn.getOperand().get(0); - assertThat(functionRef.getName(), is("ToInterval")); + assertThat(where, instanceOf(In.class)); + In in = (In) where; + assertThat(in.getOperand().get(0), instanceOf(FunctionRef.class)); + FunctionRef functionRef = (FunctionRef) in.getOperand().get(0); + assertThat(functionRef.getName(), is("ToDateTime")); assertThat(functionRef.getOperand().get(0), instanceOf(As.class)); As asExpression = (As) functionRef.getOperand().get(0); - assertThat(asExpression.getAsType().getLocalPart(), is("Period")); + assertThat(asExpression.getAsType().getLocalPart(), is("dateTime")); assertThat(asExpression.getOperand(), instanceOf(Property.class)); Property property = (Property) asExpression.getOperand(); assertThat(property.getScope(), is("P")); diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu3/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu3/BaseTest.java index bfdaf1916..8ea70b1b0 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu3/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu3/BaseTest.java @@ -51,10 +51,10 @@ void fhirTiming() throws IOException { ExpressionDef def = (ExpressionDef) visitFile("fhir/stu3/TestFHIRTiming.cql"); // Query-> // where-> - // IncludedIn-> + // In-> // left-> - // ToInterval() - // As(fhir:Period) -> + // ToDateTime() + // As(fhir:dateTime) -> // Property(P.performed) // right-> MeasurementPeriod Query query = (Query) def.getExpression(); @@ -67,14 +67,14 @@ void fhirTiming() throws IOException { // Then check that the where an IncludedIn with a Case as the left operand Expression where = query.getWhere(); - assertThat(where, instanceOf(IncludedIn.class)); - IncludedIn includedIn = (IncludedIn) where; - assertThat(includedIn.getOperand().get(0), instanceOf(FunctionRef.class)); - FunctionRef functionRef = (FunctionRef) includedIn.getOperand().get(0); - assertThat(functionRef.getName(), is("ToInterval")); + assertThat(where, instanceOf(In.class)); + In in = (In) where; + assertThat(in.getOperand().get(0), instanceOf(FunctionRef.class)); + FunctionRef functionRef = (FunctionRef) in.getOperand().get(0); + assertThat(functionRef.getName(), is("ToDateTime")); assertThat(functionRef.getOperand().get(0), instanceOf(As.class)); As asExpression = (As) functionRef.getOperand().get(0); - assertThat(asExpression.getAsType().getLocalPart(), is("Period")); + assertThat(asExpression.getAsType().getLocalPart(), is("dateTime")); assertThat(asExpression.getOperand(), instanceOf(Property.class)); Property property = (Property) asExpression.getOperand(); assertThat(property.getScope(), is("P")); diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu301/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu301/BaseTest.java index ee06cb82f..a9cf737d1 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu301/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/fhir/stu301/BaseTest.java @@ -69,14 +69,14 @@ void fhirTiming() throws IOException { // Then check that the where an IncludedIn with a ToInterval as the left operand Expression where = query.getWhere(); - assertThat(where, instanceOf(IncludedIn.class)); - IncludedIn includedIn = (IncludedIn) where; - assertThat(includedIn.getOperand().get(0), instanceOf(FunctionRef.class)); - FunctionRef functionRef = (FunctionRef) includedIn.getOperand().get(0); - assertThat(functionRef.getName(), is("ToInterval")); + assertThat(where, instanceOf(In.class)); + In in = (In) where; + assertThat(in.getOperand().get(0), instanceOf(FunctionRef.class)); + FunctionRef functionRef = (FunctionRef) in.getOperand().get(0); + assertThat(functionRef.getName(), is("ToDateTime")); assertThat(functionRef.getOperand().get(0), instanceOf(As.class)); As asExpression = (As) functionRef.getOperand().get(0); - assertThat(asExpression.getAsType().getLocalPart(), is("Period")); + assertThat(asExpression.getAsType().getLocalPart(), is("dateTime")); assertThat(asExpression.getOperand(), instanceOf(Property.class)); Property property = (Property) asExpression.getOperand(); assertThat(property.getScope(), is("P")); diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/quick/v330/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/quick/v330/BaseTest.java index 67133edf9..0fddd1fd8 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/quick/v330/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/quick/v330/BaseTest.java @@ -55,9 +55,9 @@ void fhirTiming() throws IOException { ExpressionDef def = (ExpressionDef) visitFile("quick/v330/TestFHIRTiming.cql"); // Query-> // where-> - // IncludedIn-> + // In-> // left-> - // As(Interval) -> + // As(DateTime) -> // Property(P.performed) // right-> MeasurementPeriod Query query = (Query) def.getExpression(); @@ -70,15 +70,11 @@ void fhirTiming() throws IOException { // Then check that the where an IncludedIn with a Case as the left operand Expression where = query.getWhere(); - assertThat(where, instanceOf(IncludedIn.class)); - IncludedIn includedIn = (IncludedIn) where; - assertThat(includedIn.getOperand().get(0), instanceOf(As.class)); - As asExpression = (As) includedIn.getOperand().get(0); - assertThat(asExpression.getAsTypeSpecifier(), instanceOf(IntervalTypeSpecifier.class)); - IntervalTypeSpecifier intervalTypeSpecifier = (IntervalTypeSpecifier) asExpression.getAsTypeSpecifier(); - assertThat(intervalTypeSpecifier.getPointType(), instanceOf(NamedTypeSpecifier.class)); - NamedTypeSpecifier namedTypeSpecifier = (NamedTypeSpecifier) intervalTypeSpecifier.getPointType(); - assertThat(namedTypeSpecifier.getName().getLocalPart(), is("DateTime")); + assertThat(where, instanceOf(In.class)); + In in = (In) where; + assertThat(in.getOperand().get(0), instanceOf(As.class)); + As asExpression = (As) in.getOperand().get(0); + assertThat(asExpression.getAsType().getLocalPart(), equalTo("DateTime")); assertThat(asExpression.getOperand(), instanceOf(Property.class)); Property property = (Property) asExpression.getOperand(); assertThat(property.getScope(), is("P")); diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/ResolutionTests/ProperlyIncludesTests.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/ResolutionTests/ProperlyIncludesTests.cql new file mode 100644 index 000000000..57b834ec7 --- /dev/null +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/ResolutionTests/ProperlyIncludesTests.cql @@ -0,0 +1,9 @@ +library ProperlyIncludesTests + +// These should all resolve to ProperContains(Interval, Integer) +// ProperContains(Interval, Integer) +define TestA: Interval[1, null] properly includes null +define TestB: Interval[1, null) properly includes null +define TestC: Interval[null, null] properly includes null +define TestD: Interval(null, null) properly includes null +define TestE: Interval[1, null] properly includes null as Choice> diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/fhir/r4/TestFHIRTiming.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/fhir/r4/TestFHIRTiming.cql index 2428f8486..c2e262560 100644 --- a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/fhir/r4/TestFHIRTiming.cql +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/fhir/r4/TestFHIRTiming.cql @@ -15,4 +15,5 @@ define Procedures: // Because performed is a "choice", it could be interval-valued, or it could be datetime-valued // In that case, it should continue to treat it as an interval timing phrase, not a left-point-valued timing phrase // Fixed much more generally with a combination of interval promotion/demotion and better instantiation in the presence of choice types + // NOTE: As of 1.5.3 with the clarification of type precedence (Simple, Class, Tuple, Interval, List) this resolves as an In, not an IncludedIn where P.performed included in "Measurement Period"