OrFilter.getRight() returns an AndFilter when the filter holds three or more sub-filters (OrFilter.java:77-87):
if (subFilters.size() > 2) {
final LinkedList<Filter> right = new LinkedList<Filter>(subFilters);
right.removeFirst();
return new AndFilter(right); // should be new OrFilter(right)
}
FilterBuilder.or(Collection) and FilterBuilder.or(Filter...) build exactly such a flat OrFilter (FilterBuilder.java:456-479). Code that walks it through getLeft()/getRight() therefore turns or(a, b, c) into OR(a, AND(b, c)). An object that matches only b or only c then stops matching. OrFilter.accept(ConnectorObject) iterates over the flat list and is not affected.
Callers that walk getLeft()/getRight():
ObjectNormalizerFacade.normalizeFilter (the visitOrFilter branch): the normalized filter that SearchImpl passes to the connector already has the wrong structure.
AbstractFilterTranslator: normalizeNot, negate, simplifyAndDistribute and translateInternal, which every connector based on the translator uses.
FilterHandlers.CompositeFilterHandler.serialize: the filter is sent to a remote connector server as left/right, so the server receives OR(a, AND(b, c)).
MapFilterVisitor.visitOrFilter (groovy connector): scripts receive the same wrong tree.
This bug predates #145. It was found during that PR's review: #145 (review)
Fix: one line in OrFilter.getRight(), return new OrFilter(right);. It corrects every caller above at once.
Reproduction: build a, b and c as EqualsFilters on different values, and an obj that matches only c.
FilterBuilder.or(a, b, c).accept(obj) returns true.
new OrFilter(f.getLeft(), f.getRight()).accept(obj) returns false, where f = FilterBuilder.or(a, b, c). The same holds for normalizeFilter(f).accept(obj).
OrFilter.getRight()returns anAndFilterwhen the filter holds three or more sub-filters (OrFilter.java:77-87):FilterBuilder.or(Collection)andFilterBuilder.or(Filter...)build exactly such a flatOrFilter(FilterBuilder.java:456-479). Code that walks it throughgetLeft()/getRight()therefore turnsor(a, b, c)intoOR(a, AND(b, c)). An object that matches onlybor onlycthen stops matching.OrFilter.accept(ConnectorObject)iterates over the flat list and is not affected.Callers that walk
getLeft()/getRight():ObjectNormalizerFacade.normalizeFilter(thevisitOrFilterbranch): the normalized filter thatSearchImplpasses to the connector already has the wrong structure.AbstractFilterTranslator:normalizeNot,negate,simplifyAndDistributeandtranslateInternal, which every connector based on the translator uses.FilterHandlers.CompositeFilterHandler.serialize: the filter is sent to a remote connector server asleft/right, so the server receivesOR(a, AND(b, c)).MapFilterVisitor.visitOrFilter(groovy connector): scripts receive the same wrong tree.This bug predates #145. It was found during that PR's review: #145 (review)
Fix: one line in
OrFilter.getRight(),return new OrFilter(right);. It corrects every caller above at once.Reproduction: build
a,bandcasEqualsFilters on different values, and anobjthat matches onlyc.FilterBuilder.or(a, b, c).accept(obj)returnstrue.new OrFilter(f.getLeft(), f.getRight()).accept(obj)returnsfalse, wheref = FilterBuilder.or(a, b, c). The same holds fornormalizeFilter(f).accept(obj).