diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5307-search-for-medicationrequests-with-medication-contained-does-not-return-correct-results.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5307-search-for-medicationrequests-with-medication-contained-does-not-return-correct-results.yaml new file mode 100644 index 00000000000..61ac6be82ac --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5307-search-for-medicationrequests-with-medication-contained-does-not-return-correct-results.yaml @@ -0,0 +1,6 @@ +--- +type: fix +issue: 5307 +title: "Some search parameters include parenthetical expressions (e.g. `(MedicationRequest.medication as Reference)`). +The leading `(` was causing searches using parenthetical expressions to fail where the reference target was a contained resource. +This has been corrected." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java index 4ac5a609bf8..16ed33dd153 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java @@ -2809,7 +2809,7 @@ public class QueryStack { private List extractPaths(String theResourceType, RuntimeSearchParam theSearchParam) { List pathsForType = theSearchParam.getPathsSplit().stream() .map(String::trim) - .filter(t -> t.startsWith(theResourceType)) + .filter(t -> (t.startsWith(theResourceType) || t.startsWith("(" + theResourceType))) .collect(Collectors.toList()); if (pathsForType.isEmpty()) { ourLog.warn( diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4SearchContainedTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4SearchContainedTest.java index be955c3c401..bc833728d92 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4SearchContainedTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4SearchContainedTest.java @@ -19,13 +19,22 @@ import org.hl7.fhir.r4.model.CarePlan.CarePlanStatus; import org.hl7.fhir.r4.model.ClinicalImpression; import org.hl7.fhir.r4.model.ClinicalImpression.ClinicalImpressionStatus; import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Composition; +import org.hl7.fhir.r4.model.DateTimeType; +import org.hl7.fhir.r4.model.DateType; import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.Encounter.EncounterStatus; import org.hl7.fhir.r4.model.HumanName; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Medication; +import org.hl7.fhir.r4.model.MedicationRequest; import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Quantity; +import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.RiskAssessment; import org.hl7.fhir.r4.model.RiskAssessment.RiskAssessmentStatus; @@ -37,6 +46,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Date; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -988,6 +998,50 @@ public class ResourceProviderR4SearchContainedTest extends BaseResourceProviderR } + /** + * See #5307 + */ + @Test + public void testContainedSearchByTokenWithParentheticalExpression() throws IOException { + + IIdType mid1; + { + Medication m1 = new Medication(); + m1.setId("med0312"); + m1.setCode(new CodeableConcept().addCoding(new Coding() + .setSystem("http://snomed.info/sct") + .setCode("324689003") + .setDisplay("Nystatin 100,000 units/ml oral suspension (product)") + )); + + MedicationRequest medReq = new MedicationRequest(); + medReq.addIdentifier() + .setUse(Identifier.IdentifierUse.OFFICIAL) + .setSystem("http://www.bmc.nl/portal/prescriptions") + .setValue("12345689"); + medReq.setStatus(MedicationRequest.MedicationRequestStatus.COMPLETED); + medReq.setIntent(MedicationRequest.MedicationRequestIntent.ORDER); + medReq.setMedication(new Reference() + .setReference("#med0312") + .setDisplay("Nystatin 100,000 u/ml oral suspension")); + medReq.setAuthoredOnElement(new DateTimeType("2015-01-15")); + medReq.addContained(m1); + + // -- update + mid1 = myMedicationRequestDao.create(medReq, mySrd).getId().toUnqualifiedVersionless(); + + MedicationRequest medReqCreated = myMedicationRequestDao.read(mid1); + + ourLog.debug("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(medReqCreated)); + } + + String uri = myServerBase + "/MedicationRequest?medication.code=http://" + UrlUtil.escapeUrlParam("snomed.info/sct|324689003"); + List mids = searchAndReturnUnqualifiedVersionlessIdValues(uri); + + assertEquals(1L, mids.size()); + assertThat(mids, contains(mid1.getValue())); + } + public List searchAndReturnUnqualifiedVersionlessIdValues(String uri) throws IOException { List ids; HttpGet get = new HttpGet(uri);