JPA server can't use OR list on _tag:not (#1362)
* Add a failing test for :not tags * Add changelog and fix issue
This commit is contained in:
parent
c14f5c1520
commit
ce0c84db03
|
@ -834,8 +834,8 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
|
|
||||||
subQ.where(subQfrom.get("myTagId").as(Long.class).in(defJoin));
|
subQ.where(subQfrom.get("myTagId").as(Long.class).in(defJoin));
|
||||||
|
|
||||||
List<Predicate> orPredicates = createPredicateTagList(defJoinFrom, myBuilder, tagType, tokens);
|
Predicate tagListPredicate = createPredicateTagList(defJoinFrom, myBuilder, tagType, tokens);
|
||||||
defJoin.where(toArray(orPredicates));
|
defJoin.where(tagListPredicate);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -843,8 +843,8 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
Join<ResourceTable, ResourceTag> tagJoin = myResourceTableRoot.join("myTags", JoinType.LEFT);
|
Join<ResourceTable, ResourceTag> tagJoin = myResourceTableRoot.join("myTags", JoinType.LEFT);
|
||||||
From<ResourceTag, TagDefinition> defJoin = tagJoin.join("myTag");
|
From<ResourceTag, TagDefinition> defJoin = tagJoin.join("myTag");
|
||||||
|
|
||||||
List<Predicate> orPredicates = createPredicateTagList(defJoin, myBuilder, tagType, tokens);
|
Predicate tagListPredicate = createPredicateTagList(defJoin, myBuilder, tagType, tokens);
|
||||||
myPredicates.add(myBuilder.or(toArray(orPredicates)));
|
myPredicates.add(tagListPredicate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1334,20 +1334,21 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Predicate> createPredicateTagList(Path<TagDefinition> theDefJoin, CriteriaBuilder theBuilder, TagTypeEnum theTagType, List<Pair<String, String>> theTokens) {
|
private Predicate createPredicateTagList(Path<TagDefinition> theDefJoin, CriteriaBuilder theBuilder, TagTypeEnum theTagType, List<Pair<String, String>> theTokens) {
|
||||||
Predicate typePrediate = theBuilder.equal(theDefJoin.get("myTagType"), theTagType);
|
Predicate typePredicate = theBuilder.equal(theDefJoin.get("myTagType"), theTagType);
|
||||||
|
|
||||||
List<Predicate> orPredicates = Lists.newArrayList();
|
List<Predicate> orPredicates = Lists.newArrayList();
|
||||||
for (Pair<String, String> next : theTokens) {
|
for (Pair<String, String> next : theTokens) {
|
||||||
Predicate codePrediate = theBuilder.equal(theDefJoin.get("myCode"), next.getRight());
|
Predicate codePredicate = theBuilder.equal(theDefJoin.get("myCode"), next.getRight());
|
||||||
if (isNotBlank(next.getLeft())) {
|
if (isNotBlank(next.getLeft())) {
|
||||||
Predicate systemPrediate = theBuilder.equal(theDefJoin.get("mySystem"), next.getLeft());
|
Predicate systemPredicate = theBuilder.equal(theDefJoin.get("mySystem"), next.getLeft());
|
||||||
orPredicates.add(theBuilder.and(typePrediate, systemPrediate, codePrediate));
|
orPredicates.add(theBuilder.and(typePredicate, systemPredicate, codePredicate));
|
||||||
} else {
|
} else {
|
||||||
orPredicates.add(theBuilder.and(typePrediate, codePrediate));
|
orPredicates.add(theBuilder.and(typePredicate, codePredicate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return orPredicates;
|
|
||||||
|
return theBuilder.or(toArray(orPredicates));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Predicate> createPredicateToken(Collection<IQueryParameterType> theParameters, String theResourceName, String theParamName, CriteriaBuilder theBuilder,
|
private List<Predicate> createPredicateToken(Collection<IQueryParameterType> theParameters, String theResourceName, String theParamName, CriteriaBuilder theBuilder,
|
||||||
|
|
|
@ -158,11 +158,20 @@ public class CircularQueueCaptureQueriesListener extends BaseCaptureQueriesListe
|
||||||
/**
|
/**
|
||||||
* Log all captured SELECT queries
|
* Log all captured SELECT queries
|
||||||
*/
|
*/
|
||||||
public void logSelectQueriesForCurrentThread() {
|
public void logSelectQueriesForCurrentThread(int... theIndexes) {
|
||||||
List<String> queries = getSelectQueriesForCurrentThread()
|
List<String> queries = getSelectQueriesForCurrentThread()
|
||||||
.stream()
|
.stream()
|
||||||
.map(CircularQueueCaptureQueriesListener::formatQueryAsSql)
|
.map(CircularQueueCaptureQueriesListener::formatQueryAsSql)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (theIndexes != null && theIndexes.length > 0) {
|
||||||
|
List<String> newList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < theIndexes.length; i++) {
|
||||||
|
newList.add(queries.get(theIndexes[i]));
|
||||||
|
}
|
||||||
|
queries = newList;
|
||||||
|
}
|
||||||
|
|
||||||
ourLog.info("Select Queries:\n{}", String.join("\n", queries));
|
ourLog.info("Select Queries:\n{}", String.join("\n", queries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1839,6 +1839,52 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchNotTag() {
|
||||||
|
Patient p0 = new Patient();
|
||||||
|
p0.getMeta().addTag("http://system", "tag0", "Tag 0");
|
||||||
|
p0.setActive(true);
|
||||||
|
String p0id = myPatientDao.create(p0).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.getMeta().addTag("http://system", "tag1", "Tag 1");
|
||||||
|
p1.setActive(true);
|
||||||
|
String p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.getMeta().addTag("http://system", "tag2", "Tag 2");
|
||||||
|
p2.setActive(true);
|
||||||
|
String p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
String criteria = "_tag:not=http://system|tag0";
|
||||||
|
SearchParameterMap map = myMatchUrlService.translateMatchUrl(criteria, myFhirCtx.getResourceDefinition(Patient.class));
|
||||||
|
|
||||||
|
map.setLoadSynchronous(true);
|
||||||
|
|
||||||
|
myCaptureQueriesListener.clear();
|
||||||
|
IBundleProvider results = myPatientDao.search(map);
|
||||||
|
List<String> ids = toUnqualifiedVersionlessIdValues(results);
|
||||||
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
|
||||||
|
|
||||||
|
assertThat(ids, containsInAnyOrder(p1id, p2id));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
String criteria = "_tag:not=http://system|tag0,http://system|tag1";
|
||||||
|
SearchParameterMap map = myMatchUrlService.translateMatchUrl(criteria, myFhirCtx.getResourceDefinition(Patient.class));
|
||||||
|
|
||||||
|
map.setLoadSynchronous(true);
|
||||||
|
|
||||||
|
myCaptureQueriesListener.clear();
|
||||||
|
IBundleProvider results = myPatientDao.search(map);
|
||||||
|
List<String> ids = toUnqualifiedVersionlessIdValues(results);
|
||||||
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
|
||||||
|
|
||||||
|
assertThat(ids, containsInAnyOrder(p2id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchNumberParam() {
|
public void testSearchNumberParam() {
|
||||||
RiskAssessment e1 = new RiskAssessment();
|
RiskAssessment e1 = new RiskAssessment();
|
||||||
|
|
|
@ -141,6 +141,11 @@
|
||||||
Fix a build failure thanks to Maven pom errors. Thanks to Gary Teichrow for
|
Fix a build failure thanks to Maven pom errors. Thanks to Gary Teichrow for
|
||||||
the pull request!
|
the pull request!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="1362">
|
||||||
|
The JPA server did not correctly process searches with a
|
||||||
|
<![CDATA[<code>_tag:not</code>]]>
|
||||||
|
expression containing more than one comma separated value.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue