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 dc34125641f..c9832286052 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 @@ -282,6 +282,7 @@ public class SearchBuilder implements ISearchBuilder { continue; } List> andOrParams = myParams.get(nextParamName); + // LUKETODO: setResourceName appears NOT to work here?!?!?!??!??!?! Condition predicate = theQueryStack.searchForIdsWithAndOr(with().setResourceName(myResourceName) .setParamName(nextParamName) .setAndOrParams(andOrParams) @@ -673,6 +674,8 @@ public class SearchBuilder implements ISearchBuilder { // If we haven't added any predicates yet, we're doing a search for all resources. Make sure we add the // partition ID predicate in that case. if (!sqlBuilder.haveAtLeastOnePredicate()) { + // LUKETODO: this is where we add the RES_TYPE clause + // LUKETODO: we skip this in the failing case because there's no predicate?????? Condition partitionIdPredicate = sqlBuilder .getOrCreateResourceTablePredicateBuilder() .createPartitionIdPredicate(myRequestPartitionId); @@ -739,6 +742,7 @@ public class SearchBuilder implements ISearchBuilder { * Now perform the search */ GeneratedSql generatedSql = sqlBuilder.generate(theOffset, myMaxResultsToFetch); + ourLog.info("6086: generatedSql:\n{}\nparams:\n{}", generatedSql.getSql(), generatedSql.getBindVariables()); if (!generatedSql.isMatchNothing()) { SearchQueryExecutor executor = mySqlBuilderFactory.newSearchQueryExecutor(generatedSql, myMaxResultsToFetch); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/sql/SearchQueryBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/sql/SearchQueryBuilder.java index a0f64d8ef72..48a25e916f5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/sql/SearchQueryBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/sql/SearchQueryBuilder.java @@ -646,6 +646,7 @@ public class SearchQueryBuilder { ResourceTablePredicateBuilder resourceTable = mySqlBuilderFactory.resourceTable(this); addTable(resourceTable, null); if (theIncludeResourceTypeAndNonDeletedFlag) { + // LUKETODO: this is where we add the RES_TYPE clause Condition typeAndDeletionPredicate = resourceTable.createResourceTypeAndNonDeletedPredicates(); addPredicate(typeAndDeletionPredicate); } diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QuerySandbox.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QuerySandbox.java index 95ab54ddb19..e2643b26484 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QuerySandbox.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QuerySandbox.java @@ -1,8 +1,11 @@ package ca.uhn.fhir.jpa.dao.r4; +import ca.uhn.fhir.batch2.jobs.step.ResourceIdListStep; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.interceptor.api.Hook; import ca.uhn.fhir.interceptor.api.Pointcut; +import ca.uhn.fhir.interceptor.model.RequestPartitionId; +import ca.uhn.fhir.jpa.api.svc.IBatch2DaoSvc; import ca.uhn.fhir.jpa.dao.TestDaoSearch; import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.config.TestHSearchAddInConfig; @@ -30,7 +33,10 @@ import org.springframework.test.context.support.DependencyInjectionTestExecution import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.transaction.PlatformTransactionManager; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.ArrayList; +import java.util.Date; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -68,6 +74,8 @@ public class FhirResourceDaoR4QuerySandbox extends BaseJpaTest { DaoTestDataBuilder myDataBuilder; @Autowired TestDaoSearch myTestDaoSearch; + @Autowired + IBatch2DaoSvc myBatch2DaoSvc; @Override protected PlatformTransactionManager getTxManager() { @@ -164,6 +172,42 @@ public class FhirResourceDaoR4QuerySandbox extends BaseJpaTest { assertTrue(actualIds.containsAll(List.of(id1, id2, id3))); } + // LUKETODO: consider @Nested class + @Test + void testDeleteExpunge1() { +// SearchParameterMap[params={event=[[TokenParam[system=http://terminology.hl7.org/CodeSystem/v2-0003,value=], TokenParam[system=https://harris-chr.com/fhir/CodeSystem/arc-interface-trigger,value=]]]}] +// MessageHeader?event=http://terminology.hl7.org/CodeSystem/v2-0003|,https://harris-chr.com/fhir/CodeSystem/arc-interface-trigger|&_lastUpdated=ge2023-09-17T00:00:00.000000Z&_lastUpdated=le2025-09-23T23:59:59.999999Z&_expunge=true +// myTestDaoSearch.searchForResources("MessageHeader?event=http://terminology.hl7.org/CodeSystem/v2-0003|,https://harris-chr.com/fhir/CodeSystem/arc-interface-trigger|&_lastUpdated=ge2023-09-17T00:00:00.000000Z&_lastUpdated=le2025-09-23T23:59:59.999999Z&_expunge=true"); + final LocalDateTime startDateTime = LocalDateTime.now().minusDays(2); + final Date startDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()); + final LocalDateTime endDateTime = LocalDateTime.now().minusDays(1); + final Date endDate = Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()); + + myBatch2DaoSvc.fetchResourceIdStream(startDate, endDate, RequestPartitionId.allPartitions(), "MessageHeader?event=http://terminology.hl7.org/CodeSystem/v2-0003|,https://harris-chr.com/fhir/CodeSystem/arc-interface-trigger|&_lastUpdated=ge2023-09-17T00:00:00.000000Z&_lastUpdated=le2025-09-23T23:59:59.999999Z&_expunge=true") + .visitStreamNoResult(x -> { + var z = x.toList(); + }); + final List queries = myCapturedQueries.stream().toList(); + + ourLog.info("queries: {}", queries); + } + + @Test + void testDeleteExpunge2() { + final LocalDateTime startDateTime = LocalDateTime.now().minusDays(2); + final Date startDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()); + final LocalDateTime endDateTime = LocalDateTime.now().minusDays(1); + final Date endDate = Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()); + + myBatch2DaoSvc.fetchResourceIdStream(startDate, endDate, RequestPartitionId.allPartitions(), "MessageHeader?_lastUpdated=ge2023-09-17T00:00:00.000000Z&_lastUpdated=le2025-09-23T23:59:59.999999Z&_expunge=true") + .visitStreamNoResult(x -> { + var z = x.toList(); + }); + final List queries = myCapturedQueries.stream().toList(); + + ourLog.info("queries: {}", queries); + } + public static final class TestDirtiesContextTestExecutionListener extends DirtiesContextTestExecutionListener { @Override