force the resource table to be the root of the query if we might be traversing a contained reference
This commit is contained in:
parent
5604cabbe8
commit
8a9e4e4328
|
@ -1139,8 +1139,14 @@ public class QueryStack {
|
|||
// For now, leave the incorrect implementation alone, just in case someone is relying on it,
|
||||
// until the complete fix is available.
|
||||
andPredicates.add(createPredicateReferenceForContainedResource(null, theResourceName, theParamName, nextParamDef, nextAnd, null, theRequest, theRequestPartitionId));
|
||||
} else if (nextAnd.stream().filter(t -> t instanceof ReferenceParam).map(t -> (ReferenceParam) t).anyMatch(t -> t.getChain().contains("."))) {
|
||||
// FIXME for now, restrict contained reference traversal to the last reference in the chain
|
||||
andPredicates.add(createPredicateReference(theSourceJoinColumn, theResourceName, theParamName, nextAnd, null, theRequest, theRequestPartitionId));
|
||||
} else {
|
||||
andPredicates.add(createPredicateReference(theSourceJoinColumn, theResourceName, theParamName, nextAnd, null, theRequest, theRequestPartitionId));
|
||||
andPredicates.add(toOrPredicate(
|
||||
createPredicateReference(theSourceJoinColumn, theResourceName, theParamName, nextAnd, null, theRequest, theRequestPartitionId),
|
||||
createPredicateReferenceForContainedResource(theSourceJoinColumn, theResourceName, theParamName, nextParamDef, nextAnd, null, theRequest, theRequestPartitionId)
|
||||
));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -373,7 +373,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
SearchQueryBuilder sqlBuilder = new SearchQueryBuilder(myContext, myDaoConfig.getModelConfig(), myPartitionSettings, myRequestPartitionId, sqlBuilderResourceName, mySqlBuilderFactory, myDialectProvider, theCount);
|
||||
QueryStack queryStack3 = new QueryStack(theParams, myDaoConfig, myDaoConfig.getModelConfig(), myContext, sqlBuilder, mySearchParamRegistry, myPartitionSettings);
|
||||
|
||||
if (theParams.keySet().size() > 1 || theParams.getSort() != null || theParams.keySet().contains(Constants.PARAM_HAS)) {
|
||||
if (theParams.keySet().size() > 1 || theParams.getSort() != null || theParams.keySet().contains(Constants.PARAM_HAS) || isTraverseContainedReferenceAtRoot(theParams)) {
|
||||
List<RuntimeSearchParam> activeComboParams = mySearchParamRegistry.getActiveComboSearchParams(myResourceName, theParams.keySet());
|
||||
if (activeComboParams.isEmpty()) {
|
||||
sqlBuilder.setNeedResourceTableRoot(true);
|
||||
|
@ -483,6 +483,13 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
return Optional.of(executor);
|
||||
}
|
||||
|
||||
private boolean isTraverseContainedReferenceAtRoot(SearchParameterMap theParams) {
|
||||
return myModelConfig.isIndexOnContainedResources() && theParams.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.flatMap(Collection::stream)
|
||||
.anyMatch(t -> t instanceof ReferenceParam);
|
||||
}
|
||||
|
||||
private List<Long> normalizeIdListForLastNInClause(List<Long> lastnResourceIds) {
|
||||
/*
|
||||
The following is a workaround to a known issue involving Hibernate. If queries are used with "in" clauses with large and varying
|
||||
|
|
|
@ -402,10 +402,6 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder {
|
|||
andPredicates.add(childQueryFactory.searchForIdsWithAndOr(myColumnTargetResourceId, subResourceName, chain, chainParamValues, theRequest, theRequestPartitionId, SearchContainedModeEnum.FALSE));
|
||||
|
||||
orPredicates.add(toAndPredicate(andPredicates));
|
||||
|
||||
if (getModelConfig().isIndexOnContainedResources() && theReferenceParam.getChain().contains(".")) {
|
||||
orPredicates.add(childQueryFactory.createPredicateReferenceForContainedResource(myColumnTargetResourceId, subResourceName, chain, param, orValues, null, theRequest, theRequestPartitionId));
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateTargetTypes.isEmpty()) {
|
||||
|
|
|
@ -12,9 +12,9 @@ import org.hl7.fhir.r4.model.IdType;
|
|||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Organization;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
|
@ -93,7 +93,6 @@ public class ChainedContainedR4SearchTest extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testShouldResolveATwoLinkChainWithAContainedResource() throws Exception {
|
||||
IIdType oid1;
|
||||
|
||||
|
@ -105,6 +104,7 @@ public class ChainedContainedR4SearchTest extends BaseJpaR4Test {
|
|||
Observation obs = new Observation();
|
||||
obs.getContained().add(p);
|
||||
obs.getCode().setText("Observation 1");
|
||||
obs.setValue(new StringType("Test"));
|
||||
obs.getSubject().setReference("#pat");
|
||||
|
||||
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
@ -113,6 +113,7 @@ public class ChainedContainedR4SearchTest extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
String url = "/Observation?subject.name=Smith";
|
||||
// String url = "/Observation?subject.name=Smith&value-string=Test";
|
||||
myCaptureQueriesListener.clear();
|
||||
List<String> oids = searchAndReturnUnqualifiedVersionlessIdValues(url);
|
||||
ourLog.info(">>> " + myCaptureQueriesListener.getSelectQueriesForCurrentThread());
|
||||
|
@ -198,7 +199,6 @@ public class ChainedContainedR4SearchTest extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testShouldResolveAThreeLinkChainWithAContainedResourceAtTheBeginningOfTheChain() throws Exception {
|
||||
// This case seems like it would be less frequent in production, but we don't want to
|
||||
// paint ourselves into a corner where we require the contained link to be the last
|
||||
|
|
Loading…
Reference in New Issue