Limit type on _has query (#1743)

* Limit type on _has query

* Add changelog
This commit is contained in:
James Agnew 2020-03-03 08:28:38 -05:00 committed by GitHub
parent 3c2c1dab2e
commit 58b5bd9664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 4 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 1742
title: "When performing a search in the JPA server where the only parameter was a `_has` parameter,
the server did not respect the resource typename being searched for, causing false positive
search results. This has been corrected."

View File

@ -430,7 +430,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
break;
case Constants.PARAM_HAS:
addPredicateHas(theAndOrParams, theRequest);
addPredicateHas(theResourceName, theAndOrParams, theRequest);
break;
case Constants.PARAM_TAG:
@ -756,7 +756,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
return retVal;
}
private void addPredicateHas(List<List<IQueryParameterType>> theHasParameters, RequestDetails theRequest) {
private void addPredicateHas(String theResourceType, List<List<IQueryParameterType>> theHasParameters, RequestDetails theRequest) {
for (List<? extends IQueryParameterType> nextOrList : theHasParameters) {
@ -811,8 +811,9 @@ class PredicateBuilderReference extends BasePredicateBuilder {
Join<ResourceTable, ResourceLink> join = myQueryRoot.join("myResourceLinksAsTarget", JoinType.LEFT);
Predicate pathPredicate = myPredicateBuilder.createResourceLinkPathPredicate(targetResourceType, paramReference, join);
Predicate pidPredicate = join.get("mySourceResourcePid").in(subQ);
Predicate andPredicate = myBuilder.and(pathPredicate, pidPredicate);
Predicate sourceTypePredicate = myBuilder.equal(join.get("myTargetResourceType"), theResourceType);
Predicate sourcePidPredicate = join.get("mySourceResourcePid").in(subQ);
Predicate andPredicate = myBuilder.and(pathPredicate, sourcePidPredicate, sourceTypePredicate);
myQueryRoot.addPredicate(andPredicate);
}
}

View File

@ -172,6 +172,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
@Qualifier("myDeviceDaoR4")
protected IFhirResourceDao<Device> myDeviceDao;
@Autowired
@Qualifier("myProvenanceDaoR4")
protected IFhirResourceDao<Provenance> myProvenanceDao;
@Autowired
@Qualifier("myDiagnosticReportDaoR4")
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
@Autowired

View File

@ -620,6 +620,41 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
@Test
public void testHasLimitsByType() {
Patient patient = new Patient();
patient.setActive(true);
IIdType patientId = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
Encounter encounter = new Encounter();
encounter.setStatus(Encounter.EncounterStatus.ARRIVED);
IIdType encounterId = myEncounterDao.create(encounter).getId().toUnqualifiedVersionless();
Device device = new Device();
device.setManufacturer("Acme");
IIdType deviceId = myDeviceDao.create(device).getId().toUnqualifiedVersionless();
Provenance provenance = new Provenance();
provenance.addTarget().setReferenceElement(patientId);
provenance.addTarget().setReferenceElement(encounterId);
provenance.addAgent().setWho(new Reference(deviceId));
myProvenanceDao.create(provenance);
String criteria = "_has:Provenance:target:agent=" + deviceId.getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(criteria, myFhirCtx.getResourceDefinition(Encounter.class));
map.setLoadSynchronous(true);
myCaptureQueriesListener.clear();
IBundleProvider results = myEncounterDao.search(map);
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
List<String> ids = toUnqualifiedVersionlessIdValues(results);
assertThat(ids, containsInAnyOrder(encounterId.getValue()));
}
@Test
public void testHasParameter() {
IIdType pid0;