use of com.facebook.presto.common.predicate.SortedRangeSet in project presto by prestodb.
the class ExpressionConverter method toIcebergExpression.
private static Expression toIcebergExpression(String columnName, Type type, Domain domain) {
if (domain.isAll()) {
return alwaysTrue();
}
if (domain.getValues().isNone()) {
return domain.isNullAllowed() ? isNull(columnName) : alwaysFalse();
}
if (domain.getValues().isAll()) {
return domain.isNullAllowed() ? alwaysTrue() : not(isNull(columnName));
}
// Skip structural types. TODO: Evaluate Apache Iceberg's support for predicate on structural types
if (type instanceof ArrayType || type instanceof MapType || type instanceof RowType) {
return alwaysTrue();
}
ValueSet domainValues = domain.getValues();
Expression expression = null;
if (domain.isNullAllowed()) {
expression = isNull(columnName);
}
if (domainValues instanceof SortedRangeSet) {
List<Range> orderedRanges = ((SortedRangeSet) domainValues).getOrderedRanges();
expression = firstNonNull(expression, alwaysFalse());
for (Range range : orderedRanges) {
Marker low = range.getLow();
Marker high = range.getHigh();
Marker.Bound lowBound = low.getBound();
Marker.Bound highBound = high.getBound();
// case col <> 'val' is represented as (col < 'val' or col > 'val')
if (lowBound == EXACTLY && highBound == EXACTLY) {
// case ==
if (getIcebergLiteralValue(type, low).equals(getIcebergLiteralValue(type, high))) {
expression = or(expression, equal(columnName, getIcebergLiteralValue(type, low)));
} else {
// case between
Expression between = and(greaterThanOrEqual(columnName, getIcebergLiteralValue(type, low)), lessThanOrEqual(columnName, getIcebergLiteralValue(type, high)));
expression = or(expression, between);
}
} else {
if (lowBound == EXACTLY && low.getValueBlock().isPresent()) {
// case >=
expression = or(expression, greaterThanOrEqual(columnName, getIcebergLiteralValue(type, low)));
} else if (lowBound == ABOVE && low.getValueBlock().isPresent()) {
// case >
expression = or(expression, greaterThan(columnName, getIcebergLiteralValue(type, low)));
}
if (highBound == EXACTLY && high.getValueBlock().isPresent()) {
// case <=
if (low.getValueBlock().isPresent()) {
expression = and(expression, lessThanOrEqual(columnName, getIcebergLiteralValue(type, high)));
} else {
expression = or(expression, lessThanOrEqual(columnName, getIcebergLiteralValue(type, high)));
}
} else if (highBound == BELOW && high.getValueBlock().isPresent()) {
// case <
if (low.getValueBlock().isPresent()) {
expression = and(expression, lessThan(columnName, getIcebergLiteralValue(type, high)));
} else {
expression = or(expression, lessThan(columnName, getIcebergLiteralValue(type, high)));
}
}
}
}
return expression;
}
throw new VerifyException("Did not expect a domain value set other than SortedRangeSet but got " + domainValues.getClass().getSimpleName());
}
use of com.facebook.presto.common.predicate.SortedRangeSet in project presto by prestodb.
the class RowExpressionDomainTranslator method extractDisjuncts.
private List<RowExpression> extractDisjuncts(Type type, Ranges ranges, RowExpression reference) {
List<RowExpression> disjuncts = new ArrayList<>();
List<RowExpression> singleValues = new ArrayList<>();
List<Range> orderedRanges = ranges.getOrderedRanges();
SortedRangeSet sortedRangeSet = SortedRangeSet.copyOf(type, orderedRanges);
SortedRangeSet complement = sortedRangeSet.complement();
List<Range> singleValueExclusionsList = complement.getOrderedRanges().stream().filter(Range::isSingleValue).collect(toList());
List<Range> originalUnionSingleValues = SortedRangeSet.copyOf(type, singleValueExclusionsList).union(sortedRangeSet).getOrderedRanges();
PeekingIterator<Range> singleValueExclusions = peekingIterator(singleValueExclusionsList.iterator());
for (Range range : originalUnionSingleValues) {
if (range.isSingleValue()) {
singleValues.add(toRowExpression(reference.getSourceLocation(), range.getSingleValue(), type));
continue;
}
// attempt to optimize ranges that can be coalesced as long as single value points are excluded
List<RowExpression> singleValuesInRange = new ArrayList<>();
while (singleValueExclusions.hasNext() && range.contains(singleValueExclusions.peek())) {
singleValuesInRange.add(toRowExpression(reference.getSourceLocation(), singleValueExclusions.next().getSingleValue(), type));
}
if (!singleValuesInRange.isEmpty()) {
disjuncts.add(combineRangeWithExcludedPoints(type, reference, range, singleValuesInRange));
continue;
}
disjuncts.add(processRange(type, range, reference));
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
disjuncts.add(equal(reference, getOnlyElement(singleValues)));
} else if (singleValues.size() > 1) {
disjuncts.add(in(reference, singleValues));
}
return disjuncts;
}
use of com.facebook.presto.common.predicate.SortedRangeSet in project presto by prestodb.
the class KuduClientSession method addConstraintPredicates.
/**
* translates TupleDomain to KuduPredicates.
*
* @return false if TupleDomain or one of its domains is none
*/
private boolean addConstraintPredicates(KuduTable table, KuduScanToken.KuduScanTokenBuilder builder, TupleDomain<ColumnHandle> constraintSummary) {
if (constraintSummary.isNone()) {
return false;
} else if (!constraintSummary.isAll()) {
Schema schema = table.getSchema();
for (TupleDomain.ColumnDomain<ColumnHandle> columnDomain : constraintSummary.getColumnDomains().get()) {
int position = ((KuduColumnHandle) columnDomain.getColumn()).getOrdinalPosition();
ColumnSchema columnSchema = schema.getColumnByIndex(position);
Domain domain = columnDomain.getDomain();
if (domain.isNone()) {
return false;
} else if (domain.isAll()) {
// no restriction
} else if (domain.isOnlyNull()) {
builder.addPredicate(KuduPredicate.newIsNullPredicate(columnSchema));
} else if (domain.getValues().isAll() && domain.isNullAllowed()) {
builder.addPredicate(KuduPredicate.newIsNotNullPredicate(columnSchema));
} else if (domain.isSingleValue()) {
KuduPredicate predicate = createEqualsPredicate(columnSchema, domain.getSingleValue());
builder.addPredicate(predicate);
} else {
ValueSet valueSet = domain.getValues();
if (valueSet instanceof EquatableValueSet) {
DiscreteValues discreteValues = valueSet.getDiscreteValues();
KuduPredicate predicate = createInListPredicate(columnSchema, discreteValues);
builder.addPredicate(predicate);
} else if (valueSet instanceof SortedRangeSet) {
Ranges ranges = ((SortedRangeSet) valueSet).getRanges();
Range span = ranges.getSpan();
Marker low = span.getLow();
if (!low.isLowerUnbounded()) {
KuduPredicate.ComparisonOp op = (low.getBound() == Marker.Bound.ABOVE) ? KuduPredicate.ComparisonOp.GREATER : KuduPredicate.ComparisonOp.GREATER_EQUAL;
KuduPredicate predicate = createComparisonPredicate(columnSchema, op, low.getValue());
builder.addPredicate(predicate);
}
Marker high = span.getHigh();
if (!high.isUpperUnbounded()) {
KuduPredicate.ComparisonOp op = (low.getBound() == Marker.Bound.BELOW) ? KuduPredicate.ComparisonOp.LESS : KuduPredicate.ComparisonOp.LESS_EQUAL;
KuduPredicate predicate = createComparisonPredicate(columnSchema, op, high.getValue());
builder.addPredicate(predicate);
}
} else {
throw new IllegalStateException("Unexpected domain: " + domain);
}
}
}
}
return true;
}
use of com.facebook.presto.common.predicate.SortedRangeSet in project presto by prestodb.
the class ExpressionDomainTranslator method extractDisjuncts.
private List<Expression> extractDisjuncts(Type type, Ranges ranges, SymbolReference reference) {
List<Expression> disjuncts = new ArrayList<>();
List<Expression> singleValues = new ArrayList<>();
List<Range> orderedRanges = ranges.getOrderedRanges();
SortedRangeSet sortedRangeSet = SortedRangeSet.copyOf(type, orderedRanges);
SortedRangeSet complement = sortedRangeSet.complement();
List<Range> singleValueExclusionsList = complement.getOrderedRanges().stream().filter(Range::isSingleValue).collect(toList());
List<Range> originalUnionSingleValues = SortedRangeSet.copyOf(type, singleValueExclusionsList).union(sortedRangeSet).getOrderedRanges();
PeekingIterator<Range> singleValueExclusions = peekingIterator(singleValueExclusionsList.iterator());
for (Range range : originalUnionSingleValues) {
if (range.isSingleValue()) {
singleValues.add(literalEncoder.toExpression(range.getSingleValue(), type));
continue;
}
// attempt to optimize ranges that can be coalesced as long as single value points are excluded
List<Expression> singleValuesInRange = new ArrayList<>();
while (singleValueExclusions.hasNext() && range.contains(singleValueExclusions.peek())) {
singleValuesInRange.add(literalEncoder.toExpression(singleValueExclusions.next().getSingleValue(), type));
}
if (!singleValuesInRange.isEmpty()) {
disjuncts.add(combineRangeWithExcludedPoints(type, reference, range, singleValuesInRange));
continue;
}
disjuncts.add(processRange(type, range, reference));
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
disjuncts.add(new ComparisonExpression(EQUAL, reference, getOnlyElement(singleValues)));
} else if (singleValues.size() > 1) {
disjuncts.add(new InPredicate(reference, new InListExpression(singleValues)));
}
return disjuncts;
}
Aggregations