use of com.apple.foundationdb.record.query.predicates.ValueComparisonRangePredicate.Sargable in project fdb-record-layer by FoundationDB.
the class SelectExpression method partitionPredicates.
private static List<? extends QueryPredicate> partitionPredicates(final List<? extends QueryPredicate> predicates) {
final ImmutableList<QueryPredicate> flattenedAndPredicates = predicates.stream().flatMap(predicate -> flattenAndPredicate(predicate).stream()).collect(ImmutableList.toImmutableList());
// partition predicates in value-based predicates and non-value-based predicates
final ImmutableList.Builder<PredicateWithValue> predicateWithValuesBuilder = ImmutableList.builder();
final ImmutableList.Builder<QueryPredicate> resultPredicatesBuilder = ImmutableList.builder();
for (final QueryPredicate flattenedAndPredicate : flattenedAndPredicates) {
if (flattenedAndPredicate instanceof PredicateWithValue) {
predicateWithValuesBuilder.add((PredicateWithValue) flattenedAndPredicate);
} else {
resultPredicatesBuilder.add(flattenedAndPredicate);
}
}
final ImmutableList<PredicateWithValue> predicateWithValues = predicateWithValuesBuilder.build();
final AliasMap boundIdentitiesMap = AliasMap.identitiesFor(flattenedAndPredicates.stream().flatMap(predicate -> predicate.getCorrelatedTo().stream()).collect(ImmutableSet.toImmutableSet()));
final BoundEquivalence boundEquivalence = new BoundEquivalence(boundIdentitiesMap);
final HashMultimap<Equivalence.Wrapper<Value>, PredicateWithValue> partitionedPredicatesWithValues = predicateWithValues.stream().collect(Multimaps.toMultimap(predicate -> boundEquivalence.wrap(predicate.getValue()), Function.identity(), HashMultimap::create));
partitionedPredicatesWithValues.asMap().forEach((valueWrapper, predicatesOnValue) -> {
final Value value = Objects.requireNonNull(valueWrapper.get());
ComparisonRange resultRange = ComparisonRange.EMPTY;
for (final PredicateWithValue predicateOnValue : predicatesOnValue) {
if (predicateOnValue instanceof ValuePredicate) {
final Comparisons.Comparison comparison = ((ValuePredicate) predicateOnValue).getComparison();
final ComparisonRange.MergeResult mergeResult = resultRange.merge(comparison);
resultRange = mergeResult.getComparisonRange();
mergeResult.getResidualComparisons().forEach(residualComparison -> resultPredicatesBuilder.add(value.withComparison(residualComparison)));
} else if (predicateOnValue instanceof Sargable) {
final Sargable valueComparisonRangePredicate = (Sargable) predicateOnValue;
final ComparisonRange comparisonRange = valueComparisonRangePredicate.getComparisonRange();
final ComparisonRange.MergeResult mergeResult = resultRange.merge(comparisonRange);
resultRange = mergeResult.getComparisonRange();
mergeResult.getResidualComparisons().forEach(residualComparison -> resultPredicatesBuilder.add(value.withComparison(residualComparison)));
} else {
resultPredicatesBuilder.add(predicateOnValue);
}
}
if (!resultRange.isEmpty()) {
resultPredicatesBuilder.add(ValueComparisonRangePredicate.sargable(value, resultRange));
}
});
return resultPredicatesBuilder.build();
}
Aggregations