From af44b9c7a0d44cb005799348bdf05fcd2b9fc754 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Wed, 26 May 2021 12:20:49 -0400 Subject: [PATCH] Ks 20210526 accurate total (#2677) * begin with failing test * fixed * changelog --- .../5_5_0/2677-fix-accurate-count-zero.yaml | 5 +++++ .../jpa/search/SearchCoordinatorSvcImpl.java | 2 +- .../jpa/search/builder/SearchBuilder.java | 3 +++ .../r4/ResourceProviderSummaryModeR4Test.java | 21 +++++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2677-fix-accurate-count-zero.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2677-fix-accurate-count-zero.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2677-fix-accurate-count-zero.yaml new file mode 100644 index 00000000000..3edadab3ea3 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_5_0/2677-fix-accurate-count-zero.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 2674 +title: "When myDaoConfig.setDefaultTotalMode(SearchTotalModeEnum.ACCURATE) and there are zero search results on an _id search, +An Index Out of Bounds error was thrown. This has been corrected." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index 8c1df629040..5902a1de196 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -1072,7 +1072,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { ourLog.trace("Performing count"); ISearchBuilder sb = newSearchBuilder(); Iterator countIterator = sb.createCountQuery(myParams, mySearch.getUuid(), myRequest, myRequestPartitionId); - Long count = countIterator.next(); + Long count = countIterator.hasNext() ? countIterator.next() : 0; ourLog.trace("Got count {}", count); TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java index 39af962b897..cf9922478ef 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java @@ -253,6 +253,9 @@ public class SearchBuilder implements ISearchBuilder { init(theParams, theSearchUuid, theRequestPartitionId); ArrayList queries = createQuery(myParams, null, null, null, true, theRequest, null); + if (queries.isEmpty()) { + return Collections.emptyIterator(); + } try (SearchQueryExecutor queryExecutor = queries.get(0)) { return Lists.newArrayList(queryExecutor.next()).iterator(); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderSummaryModeR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderSummaryModeR4Test.java index 09725f30a6f..8f0c4ac3487 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderSummaryModeR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderSummaryModeR4Test.java @@ -4,6 +4,9 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; import ca.uhn.fhir.rest.api.SearchTotalModeEnum; import ca.uhn.fhir.rest.api.SummaryEnum; +import ca.uhn.fhir.rest.gclient.ICriterion; +import ca.uhn.fhir.rest.gclient.StringClientParam; +import ca.uhn.fhir.rest.param.StringParam; import com.google.common.collect.Lists; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Narrative; @@ -109,6 +112,24 @@ public class ResourceProviderSummaryModeR4Test extends BaseResourceProviderR4Tes assertEquals(10, outcome.getEntry().size()); } + /** + * Test zero counts + */ + @Test + public void testSearchNoHitsWithTotalAccurateSpecifiedAsDefault() { + myDaoConfig.setDefaultTotalMode(SearchTotalModeEnum.ACCURATE); + + Bundle outcome = myClient + .search() + .forResource(Patient.class) + .where(new StringClientParam(Patient.SP_RES_ID).matches().value("non-existent-id")) + .returnBundle(Bundle.class) + .execute(); + + assertEquals(new Integer(0), outcome.getTotalElement().getValue()); + assertEquals(0, outcome.getEntry().size()); + } + /** * No summary mode - Should return the first page of results but not * have the total available yet