Skip to content

Commit

Permalink
WIP: Fixing resolve() type resolution for combine and iif.
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrszul committed Dec 23, 2024
1 parent 5f2710a commit ca13590
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ public void collectDataRoots(@Nonnull final DataRoot currentRoot,
collectDataRoots(typedRoot, fhirPath.suffix(), traversalPath, dataRoots);
} else {
// TODO: check if we are in a mixed collection
collectDataRoots(currentRoot, fhirPath.suffix(), traversalPath.andThen(headPath), dataRoots);
collectDataRoots(currentRoot, fhirPath.suffix(), traversalPath.andThen(headPath),
dataRoots);
}
} else if (headPath instanceof Paths.ExternalConstantPath ecp) {
// we do not need to do anything here
Expand All @@ -99,6 +100,13 @@ public void collectDataRoots(@Nonnull final DataRoot currentRoot,
dataRoots);
}
// NOTE: other paths should be literals so we should not need to resolve them
} else if (PathsUtils.isMulitPath(headPath)) {
// combine needs to be processed differentnly
// each of the children needs to be processed with the entire suffic
headPath.children()
.forEach(child -> collectDataRoots(currentRoot, child.andThen(fhirPath.suffix()),
traversalPath, dataRoots));

} else if (!headPath.isNull()) {
// and also collect the for the children
headPath.children()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package au.csiro.pathling.fhirpath.execution;

import au.csiro.pathling.fhirpath.FhirPath;
import au.csiro.pathling.fhirpath.operator.CombineOperator;
import au.csiro.pathling.fhirpath.path.Paths;
import au.csiro.pathling.fhirpath.path.Paths.EvalFunction;
import au.csiro.pathling.fhirpath.path.Paths.EvalOperator;
import jakarta.annotation.Nonnull;
import java.util.Optional;
import lombok.experimental.UtilityClass;
Expand Down Expand Up @@ -60,11 +62,27 @@ public static boolean isTypeOf(@Nonnull final FhirPath path) {
return asTypeOf(path).isPresent();
}

public static boolean isCombineOperation(@Nonnull final FhirPath path) {
return path instanceof EvalOperator evalOperator
&& evalOperator.getOperator() instanceof CombineOperator;
}

public static boolean isIif(@Nonnull final FhirPath path) {
return path instanceof EvalFunction evalFunction && evalFunction.getFunctionIdentifier()
.equals("iif");
}

public static boolean isMulitPath(@Nonnull final FhirPath path) {
return isCombineOperation(path) || isIif(path);
}

@Nonnull
public static Optional<EvalFunction> asTypeOf(@Nonnull final FhirPath path) {
return path instanceof EvalFunction evalFunction && evalFunction.getFunctionIdentifier()
.equals("ofType")
? Optional.of(evalFunction)
: Optional.empty();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import au.csiro.pathling.fhirpath.execution.MultiFhirPathEvaluator;
import au.csiro.pathling.fhirpath.function.registry.StaticFunctionRegistry;
import au.csiro.pathling.io.source.DataSource;
import au.csiro.pathling.terminology.TerminologyService;
import au.csiro.pathling.test.SpringBootUnitTest;
import au.csiro.pathling.test.assertions.DatasetAssert;
import au.csiro.pathling.test.datasource.ObjectDataSource;
import au.csiro.pathling.test.helpers.TerminologyServiceHelpers;
import jakarta.annotation.Nonnull;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -21,6 +23,7 @@
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Encounter.EncounterStatus;
import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
Expand Down Expand Up @@ -54,6 +57,9 @@ class FhirpathTest {
@Autowired
FhirEncoders encoders;

@Autowired
TerminologyService terminologyService;


@Nonnull
Dataset<Row> evalExpression(@Nonnull final ObjectDataSource dataSource,
Expand All @@ -74,22 +80,20 @@ FhirPathEvaluator createEvaluator(@Nonnull final ResourceType subjectResource,

@Test
void accessParentResourceInJoinedExpression() {
// ????
TerminologyServiceHelpers.setupSubsumes(terminologyService);
final ObjectDataSource dataSource = getPatientsWithConditions();
final Dataset<Row> resultDataset = evalExpression(dataSource, ResourceType.PATIENT,
"reverseResolve(Condition.subject).code.coding.subsumes(%resource.reverseResolve(Condition.subject).code)");
System.out.println(resultDataset.queryExecution().executedPlan().toString());
resultDataset.show();
// TODO: update expectations
new DatasetAssert(resultDataset)
.hasRowsUnordered(
RowFactory.create("1", true),
RowFactory.create("2", false),
RowFactory.create("2", true),
RowFactory.create("3", null)
);
}


@Test
void simpleReverseResolveToSingularValue() {
final ObjectDataSource dataSource = getPatientsWithConditions();
Expand Down Expand Up @@ -685,5 +689,63 @@ void extensionReference() {
);
}

@Test
void testCombineOperatorWithTwoUntypedResourcePaths() {
final ObjectDataSource dataSource =
new ObjectDataSource(spark, encoders,
List.of(
new Patient().setId("Patient/1"),
new Condition()
.setSubject(new Reference("Patient/1"))
.setId("Condition/1"),
new DiagnosticReport()
.setSubject(new Reference("Patient/1"))
.setId("DiagnosticReport/1")
));

final Dataset<Row> resultDataset = evalExpression(dataSource,
ResourceType.PATIENT,
"(reverseResolve(Condition.subject).subject.resolve() combine "
+ "reverseResolve(DiagnosticReport.subject).subject.resolve()).ofType(Patient).id"
);
resultDataset.show();
new DatasetAssert(resultDataset)
.hasRowsUnordered(
RowFactory.create("1", sql_array("1", "1"))
);
}


@Test
void testIfFunctionWithUntypedResourceResult() {

final ObjectDataSource dataSource =
new ObjectDataSource(spark, encoders,
List.of(
new Patient()
.setGender(AdministrativeGender.MALE)
.addLink(new Patient.PatientLinkComponent()
.setType(Patient.LinkType.REPLACEDBY)
.setOther(new Reference("Patient/2")))
.setId("Patient/1"),
new Patient()
.setGender(AdministrativeGender.UNKNOWN)
.setId("Patient/2"),
new Patient().setId("Patient/3")
));

final Dataset<Row> resultDataset = evalExpression(dataSource,
ResourceType.PATIENT,
"iif(gender = 'male', link.where(type = 'replaced-by').other.resolve(), "
+ "link.where(type = 'replaces').other.resolve()).ofType(Patient).gender"
);
resultDataset.show();
new DatasetAssert(resultDataset)
.hasRowsUnordered(
RowFactory.create("1", "unknown"),
RowFactory.create("2", null),
RowFactory.create("3", null)
);
}

}

0 comments on commit ca13590

Please sign in to comment.