From 4490c9ca098e28c8220c77538b5b9bf1cc5d74cb Mon Sep 17 00:00:00 2001
From: James Agnew
Date: Wed, 14 Aug 2019 14:39:40 -0400
Subject: [PATCH] Correct the eq operator on the _filter parameter
---
.../ca/uhn/fhir/jpa/dao/SearchBuilder.java | 9 +++--
.../dao/r4/FhirResourceDaoR4FilterTest.java | 35 ++++++++++++++++++-
pom.xml | 2 +-
src/changes/changes.xml | 5 +++
src/site/xdoc/index.xml | 2 +-
5 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index 124e3668ee1..4e30159e585 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -1676,8 +1676,6 @@ public class SearchBuilder implements ISearchBuilder {
Predicate predicate;
if ((operation == null) ||
- (operation == SearchFilterParser.CompareOperation.eq) ||
- (operation == SearchFilterParser.CompareOperation.co) ||
(operation == SearchFilterParser.CompareOperation.sw) ||
(operation == SearchFilterParser.CompareOperation.ew)) {
@@ -1685,6 +1683,11 @@ public class SearchBuilder implements ISearchBuilder {
Predicate hashCode = theBuilder.equal(theFrom.get("myHashNormalizedPrefix").as(Long.class), hash);
Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), likeExpression);
predicate = theBuilder.and(hashCode, singleCode);
+ } else if (operation == SearchFilterParser.CompareOperation.eq) {
+ Long hash = ResourceIndexedSearchParamString.calculateHashNormalized(myDaoConfig.getModelConfig(), theResourceName, theParamName, normalizedString);
+ Predicate hashCode = theBuilder.equal(theFrom.get("myHashNormalizedPrefix").as(Long.class), hash);
+ Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), normalizedString);
+ predicate = theBuilder.and(hashCode, singleCode);
} else if (operation == SearchFilterParser.CompareOperation.ne) {
Predicate singleCode = theBuilder.notEqual(theFrom.get("myValueNormalized").as(String.class), likeExpression);
predicate = combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
@@ -1701,7 +1704,7 @@ public class SearchBuilder implements ISearchBuilder {
Predicate singleCode = theBuilder.lessThanOrEqualTo(theFrom.get("myValueNormalized").as(String.class), likeExpression);
predicate = combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);
} else {
- throw new IllegalArgumentException("Unknown operation type: " + operation);
+ throw new IllegalArgumentException("Don't yet know how to handle operation " + operation + " on a string");
}
return predicate;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4FilterTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4FilterTest.java
index cfecc19072f..9088233c5f3 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4FilterTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4FilterTest.java
@@ -6,15 +6,18 @@ import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hamcrest.Matchers;
import org.hl7.fhir.r4.model.Patient;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentMatchers;
import java.util.List;
import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.emptyString;
import static org.junit.Assert.*;
@SuppressWarnings({"Duplicates"})
@@ -44,7 +47,7 @@ public class FhirResourceDaoR4FilterTest extends BaseJpaR4Test {
}
@Test
- public void testChainWithMultipleTypePossibilities() {
+ public void testBrackets() {
Patient p= new Patient();
p.addName().setFamily("Smith").addGiven("John");
@@ -73,6 +76,36 @@ public class FhirResourceDaoR4FilterTest extends BaseJpaR4Test {
}
+ @Test
+ public void testStringComparatorEq() {
+
+ Patient p= new Patient();
+ p.addName().setFamily("Smith").addGiven("John");
+ p.setActive(true);
+ String id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
+
+ p = new Patient();
+ p.addName().setFamily("Jones").addGiven("Frank");
+ p.setActive(false);
+ String id2 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
+
+ SearchParameterMap map;
+ List found;
+
+ map = new SearchParameterMap();
+ map.setLoadSynchronous(true);
+ map.add(Constants.PARAM_FILTER, new StringParam("name eq smi"));
+ found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
+ assertThat(found, Matchers.empty());
+
+ map = new SearchParameterMap();
+ map.setLoadSynchronous(true);
+ map.add(Constants.PARAM_FILTER, new StringParam("name eq smith"));
+ found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
+ assertThat(found, containsInAnyOrder(id1));
+
+ }
+
@Test
public void testFilterDisabled() {
myDaoConfig.setFilterParameterEnabled(false);
diff --git a/pom.xml b/pom.xml
index 84b1e35d3ea..51ded534115 100755
--- a/pom.xml
+++ b/pom.xml
@@ -558,7 +558,7 @@
- 4.0.0
+ 4.0.1-SNAPSHOT
1.0.2
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d3bdf8ceecc..261ca2b399d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -19,6 +19,11 @@
when deciding how to encode the resource being sent. Thanks to Sean McIlvenna for the
pull request!
+
+ When using the _filter search parameter, string comparisons using the "eq" operator
+ were incorrectly performing a partial match. This has been corrected. Thanks to
+ Marc Sandberg for pointing this out!
+
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
index 1a21f643deb..6359a63a6f5 100644
--- a/src/site/xdoc/index.xml
+++ b/src/site/xdoc/index.xml
@@ -102,7 +102,7 @@
- James Agnew
-
+
May 30, 2019 - HAPI FHIR 3.8.0 (Hippo) Released -
The next release of HAPI has now been uploaded to the Maven repos and