From a1fbeeacaa710cc2bf6bbb457425cf7989f0e7ca Mon Sep 17 00:00:00 2001 From: katie_smilecdr Date: Tue, 31 Aug 2021 15:11:06 -0400 Subject: [PATCH] [2935] Escape "%" in like expression --- ...935-Search-with-trailing-percent-sign.yaml | 5 +++ .../predicate/StringPredicateBuilder.java | 6 ++-- .../provider/r4/ResourceProviderR4Test.java | 32 ++++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2935-Search-with-trailing-percent-sign.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2935-Search-with-trailing-percent-sign.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2935-Search-with-trailing-percent-sign.yaml new file mode 100644 index 00000000000..5c99ab10b71 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2935-Search-with-trailing-percent-sign.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 2935 +jira: SMILE-3022 +title: "No resource returned when search with percent sign. Problem is now fixed" diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/StringPredicateBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/StringPredicateBuilder.java index 88fd7cdae18..bc5b9a4c891 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/StringPredicateBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/StringPredicateBuilder.java @@ -225,15 +225,15 @@ public class StringPredicateBuilder extends BaseSearchParamPredicateBuilder { } public static String createLeftAndRightMatchLikeExpression(String likeExpression) { - return "%" + likeExpression.replace("%", "[%]") + "%"; + return "%" + likeExpression.replace("%", "\\%") + "%"; } public static String createLeftMatchLikeExpression(String likeExpression) { - return likeExpression.replace("%", "[%]") + "%"; + return likeExpression.replace("%", "\\%") + "%"; } public static String createRightMatchLikeExpression(String likeExpression) { - return "%" + likeExpression.replace("%", "[%]"); + return "%" + likeExpression.replace("%", "\\%"); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index 73233bd5e84..b939c4b1536 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -295,7 +295,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { myCaptureQueriesListener.logSelectQueries(); } - @Test public void testSearchWithContainsLowerCase() { myDaoConfig.setAllowContainsSearches(true); @@ -333,6 +332,37 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { } + @Test + public void testSearchWithPercentSign() { + myDaoConfig.setAllowContainsSearches(true); + + Patient pt1 = new Patient(); + pt1.addName().setFamily("Smith%"); + String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue(); + + Bundle output = myClient + .search() + .forResource("Patient") + .where(Patient.NAME.contains().value("Smith%")) + .returnBundle(Bundle.class) + .execute(); + List ids = output.getEntry().stream().map(t -> t.getResource().getIdElement().toUnqualifiedVersionless().getValue()).collect(Collectors.toList()); + assertThat(ids, containsInAnyOrder(pt1id)); + + Patient pt2 = new Patient(); + pt2.addName().setFamily("Sm%ith"); + String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue(); + + output = myClient + .search() + .forResource("Patient") + .where(Patient.NAME.contains().value("Sm%ith")) + .returnBundle(Bundle.class) + .execute(); + ids = output.getEntry().stream().map(t -> t.getResource().getIdElement().toUnqualifiedVersionless().getValue()).collect(Collectors.toList()); + assertThat(ids, containsInAnyOrder(pt2id)); + } + @Test public void testSearchWithDateInvalid() throws IOException { HttpGet get = new HttpGet(ourServerBase + "/Condition?onset-date=junk");