use of com.facebook.presto.common.predicate.TupleDomainFilter.DoubleRange in project presto by prestodb.
the class TupleDomainFilterUtils method toFilter.
public static TupleDomainFilter toFilter(Domain domain) {
ValueSet values = domain.getValues();
boolean nullAllowed = domain.isNullAllowed();
if (values.isAll()) {
checkArgument(!nullAllowed, "Unexpected allways-true filter");
return IS_NOT_NULL;
}
if (values.isNone()) {
checkArgument(nullAllowed, "Unexpected allways-false filter");
return IS_NULL;
}
checkArgument(values instanceof SortedRangeSet, "Unexpected domain type: " + values.getClass().getSimpleName());
List<Range> ranges = ((SortedRangeSet) values).getOrderedRanges();
if (ranges.isEmpty() && nullAllowed) {
return IS_NULL;
}
Type type = domain.getType();
if (ranges.size() == 1) {
return createRangeFilter(type, ranges.get(0), nullAllowed);
}
if (type == BOOLEAN) {
return createBooleanFilter(ranges, nullAllowed);
}
List<TupleDomainFilter> rangeFilters = ranges.stream().map(range -> createRangeFilter(type, range, false)).filter(rangeFilter -> !rangeFilter.equals(ALWAYS_FALSE)).collect(toList());
if (rangeFilters.isEmpty()) {
return nullAllowed ? IS_NULL : ALWAYS_FALSE;
}
TupleDomainFilter firstRangeFilter = rangeFilters.get(0);
if (firstRangeFilter instanceof BigintRange) {
List<BigintRange> bigintRanges = rangeFilters.stream().map(BigintRange.class::cast).collect(toList());
if (bigintRanges.stream().allMatch(BigintRange::isSingleValue)) {
return toBigintValues(bigintRanges.stream().mapToLong(BigintRange::getLower).toArray(), nullAllowed);
}
return BigintMultiRange.of(bigintRanges, nullAllowed);
}
if (firstRangeFilter instanceof BytesRange) {
List<BytesRange> bytesRanges = rangeFilters.stream().map(BytesRange.class::cast).collect(toList());
if (bytesRanges.stream().allMatch(BytesRange::isSingleValue)) {
return BytesValues.of(bytesRanges.stream().map(BytesRange::getLower).toArray(byte[][]::new), nullAllowed);
}
if (isNotIn(ranges)) {
return BytesValuesExclusive.of(bytesRanges.stream().map(BytesRange::getLower).filter(Objects::nonNull).toArray(byte[][]::new), nullAllowed);
}
}
if (firstRangeFilter instanceof DoubleRange || firstRangeFilter instanceof FloatRange) {
// != and NOT IN filters should return true when applied to NaN
// E.g. NaN != 1.0 as well as NaN NOT IN (1.0, 2.5, 3.6) should return true; otherwise false.
boolean nanAllowed = isNotIn(ranges);
return MultiRange.of(rangeFilters, nullAllowed, nanAllowed);
}
return MultiRange.of(rangeFilters, nullAllowed, false);
}
Aggregations