Work on uniques
This commit is contained in:
parent
62d867902f
commit
8e714b6b14
|
@ -871,7 +871,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
|
||||
addPredicateCompositeStringUnique(theParams, indexString);
|
||||
addPredicateCompositeStringUnique(theParams, indexString, myPartitionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -886,9 +886,16 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private void addPredicateCompositeStringUnique(@Nonnull SearchParameterMap theParams, String theIndexedString) {
|
||||
myQueryRoot.setHasIndexJoins(true);
|
||||
private void addPredicateCompositeStringUnique(@Nonnull SearchParameterMap theParams, String theIndexedString, PartitionId thePartitionId) {
|
||||
Join<ResourceTable, ResourceIndexedCompositeStringUnique> join = myQueryRoot.join("myParamsCompositeStringUnique", JoinType.LEFT);
|
||||
|
||||
if (thePartitionId != null) {
|
||||
Integer partitionId = thePartitionId.getPartitionId();
|
||||
Predicate predicate = myCriteriaBuilder.equal(join.get("myPartitionIdValue").as(Integer.class), partitionId);
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
}
|
||||
|
||||
myQueryRoot.setHasIndexJoins(true);
|
||||
Predicate predicate = myCriteriaBuilder.equal(join.get("myIndexString"), theIndexedString);
|
||||
myQueryRoot.addPredicate(predicate);
|
||||
|
||||
|
|
|
@ -24,9 +24,11 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndex;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.SearchParamPresent;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
|
@ -203,6 +205,14 @@ abstract class BasePredicateBuilder {
|
|||
return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, num);
|
||||
}
|
||||
|
||||
void addPartitionIdPredicate(PartitionId thePartitionId, Join<ResourceTable, ? extends BaseResourceIndex> theJoin, List<Predicate> theCodePredicates) {
|
||||
if (thePartitionId != null) {
|
||||
Integer partitionId = thePartitionId.getPartitionId();
|
||||
Predicate partitionPredicate = myCriteriaBuilder.equal(theJoin.get("myPartitionIdValue").as(Integer.class), partitionId);
|
||||
myQueryRoot.addPredicate(partitionPredicate);
|
||||
}
|
||||
}
|
||||
|
||||
static String createLeftAndRightMatchLikeExpression(String likeExpression) {
|
||||
return "%" + likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
|
|
@ -55,40 +55,40 @@ public class PredicateBuilder {
|
|||
myPredicateBuilderUri = thePredicateBuilderFactory.newPredicateBuilderUri(theSearchBuilder);
|
||||
}
|
||||
|
||||
void addPredicateCoords(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd) {
|
||||
myPredicateBuilderCoords.addPredicate(theResourceName, theParamName, theNextAnd, null);
|
||||
void addPredicateCoords(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, PartitionId thePartitionId) {
|
||||
myPredicateBuilderCoords.addPredicate(theResourceName, theParamName, theNextAnd, null, thePartitionId);
|
||||
}
|
||||
|
||||
Predicate addPredicateDate(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderDate.addPredicate(theResourceName, theParamName, theNextAnd, theOperation);
|
||||
Predicate addPredicateDate(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderDate.addPredicate(theResourceName, theParamName, theNextAnd, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
Predicate addPredicateNumber(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderNumber.addPredicate(theResourceName, theParamName, theNextAnd, theOperation);
|
||||
Predicate addPredicateNumber(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderNumber.addPredicate(theResourceName, theParamName, theNextAnd, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
Predicate addPredicateQuantity(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderQuantity.addPredicate(theResourceName, theParamName, theNextAnd, theOperation);
|
||||
Predicate addPredicateQuantity(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderQuantity.addPredicate(theResourceName, theParamName, theNextAnd, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
void addPredicateString(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd) {
|
||||
myPredicateBuilderString.addPredicate(theResourceName, theParamName, theNextAnd, SearchFilterParser.CompareOperation.sw);
|
||||
void addPredicateString(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, PartitionId thePartitionId) {
|
||||
myPredicateBuilderString.addPredicate(theResourceName, theParamName, theNextAnd, SearchFilterParser.CompareOperation.sw, thePartitionId);
|
||||
}
|
||||
|
||||
Predicate addPredicateString(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderString.addPredicate(theResourceName, theParamName, theNextAnd, theOperation);
|
||||
Predicate addPredicateString(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderString.addPredicate(theResourceName, theParamName, theNextAnd, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
void addPredicateTag(List<List<IQueryParameterType>> theAndOrParams, String theParamName) {
|
||||
myPredicateBuilderTag.addPredicateTag(theAndOrParams, theParamName);
|
||||
}
|
||||
|
||||
Predicate addPredicateToken(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderToken.addPredicate(theResourceName, theParamName, theNextAnd, theOperation);
|
||||
Predicate addPredicateToken(String theResourceName, String theParamName, List<? extends IQueryParameterType> theNextAnd, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderToken.addPredicate(theResourceName, theParamName, theNextAnd, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
Predicate addPredicateUri(String theResourceName, String theName, List<? extends IQueryParameterType> theSingletonList, SearchFilterParser.CompareOperation theOperation) {
|
||||
return myPredicateBuilderUri.addPredicate(theResourceName, theName, theSingletonList, theOperation);
|
||||
Predicate addPredicateUri(String theResourceName, String theName, List<? extends IQueryParameterType> theSingletonList, SearchFilterParser.CompareOperation theOperation, PartitionId thePartitionId) {
|
||||
return myPredicateBuilderUri.addPredicate(theResourceName, theName, theSingletonList, theOperation, thePartitionId);
|
||||
}
|
||||
|
||||
public void searchForIdsWithAndOr(String theResourceName, String theNextParamName, List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest, PartitionId thePartitionId) {
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.util.CoordCalculator;
|
||||
|
@ -147,15 +148,18 @@ public class PredicateBuilderCoords extends BasePredicateBuilder implements IPre
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation theOperation) {
|
||||
SearchFilterParser.CompareOperation theOperation,
|
||||
PartitionId thePartitionId) {
|
||||
Join<ResourceTable, ResourceIndexedSearchParamCoords> join = createJoin(SearchBuilderJoinEnum.COORDS, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
|
||||
Predicate singleCode = createPredicateCoords(nextOr,
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -58,7 +59,8 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation operation) {
|
||||
SearchFilterParser.CompareOperation operation,
|
||||
PartitionId thePartitionId) {
|
||||
|
||||
boolean newJoin = false;
|
||||
if (myJoinMap == null) {
|
||||
|
@ -75,11 +77,13 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
|
|||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
Boolean missing = theList.get(0).getMissing();
|
||||
addPredicateParamMissing(theResourceName, theParamName, missing, join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, missing, join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
IQueryParameterType params = nextOr;
|
||||
Predicate p = createPredicateDate(params,
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamNumber;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -53,16 +54,19 @@ class PredicateBuilderNumber extends BasePredicateBuilder implements IPredicateB
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation operation) {
|
||||
SearchFilterParser.CompareOperation operation,
|
||||
PartitionId thePartitionId) {
|
||||
|
||||
Join<ResourceTable, ResourceIndexedSearchParamNumber> join = createJoin(SearchBuilderJoinEnum.NUMBER, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
|
||||
if (nextOr instanceof NumberParam) {
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
|
|||
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -51,16 +52,19 @@ class PredicateBuilderQuantity extends BasePredicateBuilder implements IPredicat
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation operation) {
|
||||
SearchFilterParser.CompareOperation theOperation,
|
||||
PartitionId thePartitionId) {
|
||||
|
||||
Join<ResourceTable, ResourceIndexedSearchParamQuantity> join = createJoin(SearchBuilderJoinEnum.QUANTITY, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
|
||||
Predicate singleCode = createPredicateQuantity(nextOr,
|
||||
|
@ -68,7 +72,7 @@ class PredicateBuilderQuantity extends BasePredicateBuilder implements IPredicat
|
|||
theParamName,
|
||||
myCriteriaBuilder,
|
||||
join,
|
||||
operation);
|
||||
theOperation);
|
||||
codePredicates.add(singleCode);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
// Resources by ID
|
||||
List<ResourcePersistentId> targetPids = myIdHelperService.resolveResourcePersistentIds(targetIds, theRequest);
|
||||
|
@ -538,12 +539,12 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
switch (nextParamDef.getParamType()) {
|
||||
case DATE:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
myPredicateBuilder.addPredicateDate(theResourceName, theParamName, nextAnd, null);
|
||||
myPredicateBuilder.addPredicateDate(theResourceName, theParamName, nextAnd, null, thePartitionId);
|
||||
}
|
||||
break;
|
||||
case QUANTITY:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
myPredicateBuilder.addPredicateQuantity(theResourceName, theParamName, nextAnd, null);
|
||||
myPredicateBuilder.addPredicateQuantity(theResourceName, theParamName, nextAnd, null, thePartitionId);
|
||||
}
|
||||
break;
|
||||
case REFERENCE:
|
||||
|
@ -553,21 +554,21 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
break;
|
||||
case STRING:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
myPredicateBuilder.addPredicateString(theResourceName, theParamName, nextAnd, SearchFilterParser.CompareOperation.sw);
|
||||
myPredicateBuilder.addPredicateString(theResourceName, theParamName, nextAnd, SearchFilterParser.CompareOperation.sw, thePartitionId);
|
||||
}
|
||||
break;
|
||||
case TOKEN:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
if ("Location.position".equals(nextParamDef.getPath())) {
|
||||
myPredicateBuilder.addPredicateCoords(theResourceName, theParamName, nextAnd);
|
||||
myPredicateBuilder.addPredicateCoords(theResourceName, theParamName, nextAnd, thePartitionId);
|
||||
} else {
|
||||
myPredicateBuilder.addPredicateToken(theResourceName, theParamName, nextAnd, null);
|
||||
myPredicateBuilder.addPredicateToken(theResourceName, theParamName, nextAnd, null, thePartitionId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NUMBER:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
myPredicateBuilder.addPredicateNumber(theResourceName, theParamName, nextAnd, null);
|
||||
myPredicateBuilder.addPredicateNumber(theResourceName, theParamName, nextAnd, null, thePartitionId);
|
||||
}
|
||||
break;
|
||||
case COMPOSITE:
|
||||
|
@ -577,14 +578,14 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
break;
|
||||
case URI:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
myPredicateBuilder.addPredicateUri(theResourceName, theParamName, nextAnd, SearchFilterParser.CompareOperation.eq);
|
||||
myPredicateBuilder.addPredicateUri(theResourceName, theParamName, nextAnd, SearchFilterParser.CompareOperation.eq, thePartitionId);
|
||||
}
|
||||
break;
|
||||
case HAS:
|
||||
case SPECIAL:
|
||||
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
|
||||
if ("Location.position".equals(nextParamDef.getPath())) {
|
||||
myPredicateBuilder.addPredicateCoords(theResourceName, theParamName, nextAnd);
|
||||
myPredicateBuilder.addPredicateCoords(theResourceName, theParamName, nextAnd, thePartitionId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -688,13 +689,13 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
} else {
|
||||
RestSearchParameterTypeEnum typeEnum = searchParam.getParamType();
|
||||
if (typeEnum == RestSearchParameterTypeEnum.URI) {
|
||||
return myPredicateBuilder.addPredicateUri(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new UriParam(theFilter.getValue())), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateUri(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new UriParam(theFilter.getValue())), theFilter.getOperation(), thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.STRING) {
|
||||
return myPredicateBuilder.addPredicateString(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new StringParam(theFilter.getValue())), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateString(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new StringParam(theFilter.getValue())), theFilter.getOperation(), thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.DATE) {
|
||||
return myPredicateBuilder.addPredicateDate(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new DateParam(theFilter.getValue())), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateDate(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new DateParam(theFilter.getValue())), theFilter.getOperation(), thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.NUMBER) {
|
||||
return myPredicateBuilder.addPredicateNumber(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new NumberParam(theFilter.getValue())), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateNumber(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new NumberParam(theFilter.getValue())), theFilter.getOperation(), thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.REFERENCE) {
|
||||
String paramName = theFilter.getParamPath().getName();
|
||||
SearchFilterParser.CompareOperation operation = theFilter.getOperation();
|
||||
|
@ -704,7 +705,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
ReferenceParam referenceParam = new ReferenceParam(resourceType, chain, value);
|
||||
return addPredicate(theResourceName, paramName, Collections.singletonList(referenceParam), operation, theRequest, thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.QUANTITY) {
|
||||
return myPredicateBuilder.addPredicateQuantity(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new QuantityParam(theFilter.getValue())), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateQuantity(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(new QuantityParam(theFilter.getValue())), theFilter.getOperation(), thePartitionId);
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.COMPOSITE) {
|
||||
throw new InvalidRequestException("Composite search parameters not currently supported with _filter clauses");
|
||||
} else if (typeEnum == RestSearchParameterTypeEnum.TOKEN) {
|
||||
|
@ -713,7 +714,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
null,
|
||||
null,
|
||||
theFilter.getValue());
|
||||
return myPredicateBuilder.addPredicateToken(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(param), theFilter.getOperation());
|
||||
return myPredicateBuilder.addPredicateToken(theResourceName, theFilter.getParamPath().getName(), Collections.singletonList(param), theFilter.getOperation(), thePartitionId);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -754,6 +755,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
qp = new SpecialParam();
|
||||
break;
|
||||
}
|
||||
throw new InternalErrorException("Don't know how to convert param type: " + theParam.getParamType());
|
||||
case URI:
|
||||
case HAS:
|
||||
default:
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.predicate;
|
|||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.util.StringNormalizer;
|
||||
|
@ -56,16 +57,19 @@ class PredicateBuilderString extends BasePredicateBuilder implements IPredicateB
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation operation) {
|
||||
SearchFilterParser.CompareOperation theOperation,
|
||||
PartitionId thePartitionId) {
|
||||
|
||||
Join<ResourceTable, ResourceIndexedSearchParamString> join = createJoin(SearchBuilderJoinEnum.STRING, theParamName);
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
IQueryParameterType theParameter = nextOr;
|
||||
Predicate singleCode = createPredicateString(theParameter,
|
||||
|
@ -73,7 +77,7 @@ class PredicateBuilderString extends BasePredicateBuilder implements IPredicateB
|
|||
theParamName,
|
||||
myCriteriaBuilder,
|
||||
join,
|
||||
operation);
|
||||
theOperation);
|
||||
codePredicates.add(singleCode);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import java.util.List;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
// FIXME: add partition
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
class PredicateBuilderTag extends BasePredicateBuilder {
|
||||
|
|
|
@ -26,6 +26,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
|||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
|
@ -70,22 +71,24 @@ class PredicateBuilderToken extends BasePredicateBuilder implements IPredicateBu
|
|||
public Predicate addPredicate(String theResourceName,
|
||||
String theParamName,
|
||||
List<? extends IQueryParameterType> theList,
|
||||
SearchFilterParser.CompareOperation operation) {
|
||||
SearchFilterParser.CompareOperation theOperation,
|
||||
PartitionId thePartitionId) {
|
||||
|
||||
if (theList.get(0).getMissing() != null) {
|
||||
Join<ResourceTable, ResourceIndexedSearchParamToken> join = createJoin(SearchBuilderJoinEnum.TOKEN, theParamName);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join);
|
||||
addPredicateParamMissing(theResourceName, theParamName, theList.get(0).getMissing(), join, thePartitionId);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
|
||||
List<IQueryParameterType> tokens = new ArrayList<>();
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
|
||||
if (nextOr instanceof TokenParam) {
|
||||
TokenParam id = (TokenParam) nextOr;
|
||||
if (id.isText()) {
|
||||
myPredicateBuilder.addPredicateString(theResourceName, theParamName, theList);
|
||||
myPredicateBuilder.addPredicateString(theResourceName, theParamName, theList, thePartitionId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +101,9 @@ class PredicateBuilderToken extends BasePredicateBuilder implements IPredicateBu
|
|||
}
|
||||
|
||||
Join<ResourceTable, ResourceIndexedSearchParamToken> join = createJoin(SearchBuilderJoinEnum.TOKEN, theParamName);
|
||||
Collection<Predicate> singleCode = createPredicateToken(tokens, theResourceName, theParamName, myCriteriaBuilder, join, operation);
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
Collection<Predicate> singleCode = createPredicateToken(tokens, theResourceName, theParamName, myCriteriaBuilder, join, theOperation);
|
||||
assert singleCode != null;
|
||||
codePredicates.addAll(singleCode);
|
||||
|
||||
|
|
|
@ -67,10 +67,7 @@ class PredicateBuilderUri extends BasePredicateBuilder implements IPredicateBuil
|
|||
}
|
||||
|
||||
List<Predicate> codePredicates = new ArrayList<>();
|
||||
if (thePartitionId != null) {
|
||||
Predicate partitionPredicate = myCriteriaBuilder.like(join.get("myUri").as(String.class), createLeftMatchLikeExpression(value));
|
||||
codePredicates.add(partitionPredicate);
|
||||
}
|
||||
addPartitionIdPredicate(thePartitionId, join, codePredicates);
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
|
||||
|
@ -185,4 +182,5 @@ class PredicateBuilderUri extends BasePredicateBuilder implements IPredicateBuil
|
|||
myQueryRoot.addPredicate(outerPredicate);
|
||||
return outerPredicate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import ca.uhn.fhir.jpa.model.entity.*;
|
|||
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
@ -379,6 +381,107 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_StringParam_SearchAllTenants() {
|
||||
IIdType patientIdNull = createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
IIdType patientId2 = createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
addReadTenant(null);
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_FAMILY, new StringParam("FAMILY"));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
assertThat(ids, Matchers.contains(patientIdNull, patientId1, patientId2));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_VALUE_NORMALIZED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_StringParam_SearchOneTenant() {
|
||||
createPatient(null, withFamily("FAMILY"));
|
||||
IIdType patientId1 = createPatient(1, withFamily("FAMILY"));
|
||||
createPatient(2, withFamily("FAMILY"));
|
||||
|
||||
addReadTenant(1);
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_FAMILY, new StringParam("FAMILY"));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||
assertThat(ids, Matchers.contains(patientId1));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "SP_VALUE_NORMALIZED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch_UniqueParam_SearchAllTenants() {
|
||||
createUniqueCompositeSp();
|
||||
|
||||
IIdType id = createPatient(1, withBirthdate("2020-01-01"));
|
||||
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_BIRTHDATE, new DateParam("2020-01-01"));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||
assertThat(ids, Matchers.contains(id));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(0, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "IDX_STRING='Patient?birthdate=2020-01-01'"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearch_UniqueParam_SearchOneTenant() {
|
||||
createUniqueCompositeSp();
|
||||
|
||||
IIdType id = createPatient(1, withBirthdate("2020-01-01"));
|
||||
|
||||
addReadTenant(1);
|
||||
myCaptureQueriesListener.clear();
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Patient.SP_BIRTHDATE, new DateParam("2020-01-01"));
|
||||
map.setLoadSynchronous(true);
|
||||
IBundleProvider results = myPatientDao.search(map);
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(results);
|
||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||
assertThat(ids, Matchers.contains(id));
|
||||
|
||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||
ourLog.info("Search SQL:\n{}", searchSql);
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||
assertEquals(1, StringUtils.countMatches(searchSql, "IDX_STRING='Patient?birthdate=2020-01-01'"));
|
||||
|
||||
// Same query, different partition
|
||||
addReadTenant(2);
|
||||
myCaptureQueriesListener.clear();
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_BIRTHDATE, new DateParam("2020-01-01"));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIds(results);
|
||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||
assertThat(ids, Matchers.empty());
|
||||
|
||||
}
|
||||
|
||||
private void createUniqueCompositeSp() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-birthdate");
|
||||
|
@ -447,6 +550,14 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
|||
return t -> t.setActive(true);
|
||||
}
|
||||
|
||||
private Consumer<Patient> withFamily(String theFamily) {
|
||||
return t -> t.addName().setFamily(theFamily);
|
||||
}
|
||||
|
||||
private Consumer<Patient> withBirthdate(String theBirthdate) {
|
||||
return t -> t.getBirthDateElement().setValueAsString(theBirthdate);
|
||||
}
|
||||
|
||||
private Consumer<Patient> withId(String theId) {
|
||||
return t -> {
|
||||
assertThat(theId, matchesPattern("[a-zA-Z0-9]+"));
|
||||
|
|
|
@ -50,6 +50,12 @@ public class ResourceIndexedCompositeStringUnique implements Comparable<Resource
|
|||
private String myIndexString;
|
||||
@Embedded
|
||||
private PartitionId myPartitionId;
|
||||
/**
|
||||
* This is here to support queries only, do not set this field directly
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = PartitionId.PARTITION_ID, insertable = false, updatable = false, nullable = true)
|
||||
private Integer myPartitionIdValue;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
Loading…
Reference in New Issue