use of io.trino.spi.predicate.Range in project trino by trinodb.
the class KuduClientSession method addConstraintPredicates.
/**
* translates TupleDomain to KuduPredicates.
*/
private void addConstraintPredicates(KuduTable table, KuduScanToken.KuduScanTokenBuilder builder, TupleDomain<ColumnHandle> constraintSummary) {
verify(!constraintSummary.isNone(), "constraintSummary is none");
if (constraintSummary.isAll()) {
return;
}
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();
verify(!domain.isNone(), "Domain is none");
if (domain.isAll()) {
// no restriction
} else if (domain.isOnlyNull()) {
builder.addPredicate(KuduPredicate.newIsNullPredicate(columnSchema));
} else if (!domain.getValues().isNone() && domain.isNullAllowed()) {
// no restriction
} 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();
List<Range> rangeList = ranges.getOrderedRanges();
if (rangeList.stream().allMatch(Range::isSingleValue)) {
io.trino.spi.type.Type type = TypeHelper.fromKuduColumn(columnSchema);
List<Object> javaValues = rangeList.stream().map(range -> TypeHelper.getJavaValue(type, range.getSingleValue())).collect(toImmutableList());
KuduPredicate predicate = KuduPredicate.newInListPredicate(columnSchema, javaValues);
builder.addPredicate(predicate);
} else {
Range span = ranges.getSpan();
if (!span.isLowUnbounded()) {
KuduPredicate.ComparisonOp op = span.isLowInclusive() ? GREATER_EQUAL : GREATER;
KuduPredicate predicate = createComparisonPredicate(columnSchema, op, span.getLowBoundedValue());
builder.addPredicate(predicate);
}
if (!span.isHighUnbounded()) {
KuduPredicate.ComparisonOp op = span.isHighInclusive() ? LESS_EQUAL : LESS;
KuduPredicate predicate = createComparisonPredicate(columnSchema, op, span.getHighBoundedValue());
builder.addPredicate(predicate);
}
}
} else {
throw new IllegalStateException("Unexpected domain: " + domain);
}
}
}
}
use of io.trino.spi.predicate.Range in project trino by trinodb.
the class ShardPredicate method create.
public static ShardPredicate create(TupleDomain<RaptorColumnHandle> tupleDomain) {
StringJoiner predicate = new StringJoiner(" AND ").setEmptyValue("true");
ImmutableList.Builder<JDBCType> types = ImmutableList.builder();
ImmutableList.Builder<Object> values = ImmutableList.builder();
for (Entry<RaptorColumnHandle, Domain> entry : tupleDomain.getDomains().get().entrySet()) {
Domain domain = entry.getValue();
if (domain.isNullAllowed() || domain.isAll()) {
continue;
}
RaptorColumnHandle handle = entry.getKey();
Type type = handle.getColumnType();
JDBCType jdbcType = jdbcType(type);
if (jdbcType == null) {
continue;
}
if (handle.isShardUuid()) {
predicate.add(createShardPredicate(types, values, domain, jdbcType));
continue;
}
if (!domain.getType().isOrderable()) {
continue;
}
StringJoiner columnPredicate = new StringJoiner(" OR ", "(", ")").setEmptyValue("true");
Ranges ranges = domain.getValues().getRanges();
// prevent generating complicated metadata queries
if (ranges.getRangeCount() > MAX_RANGE_COUNT) {
continue;
}
for (Range range : ranges.getOrderedRanges()) {
String min;
String max;
if (handle.isBucketNumber()) {
min = "bucket_number";
max = "bucket_number";
} else {
min = minColumn(handle.getColumnId());
max = maxColumn(handle.getColumnId());
}
StringJoiner rangePredicate = new StringJoiner(" AND ", "(", ")").setEmptyValue("true");
if (!range.isLowUnbounded()) {
rangePredicate.add(format("(%s >= ? OR %s IS NULL)", max, max));
types.add(jdbcType);
values.add(range.getLowBoundedValue());
}
if (!range.isHighUnbounded()) {
rangePredicate.add(format("(%s <= ? OR %s IS NULL)", min, min));
types.add(jdbcType);
values.add(range.getHighBoundedValue());
}
columnPredicate.add(rangePredicate.toString());
}
predicate.add(columnPredicate.toString());
}
return new ShardPredicate(predicate.toString(), types.build(), values.build());
}
use of io.trino.spi.predicate.Range in project trino by trinodb.
the class ShardPredicate method createShardPredicate.
private static String createShardPredicate(ImmutableList.Builder<JDBCType> types, ImmutableList.Builder<Object> values, Domain domain, JDBCType jdbcType) {
List<Range> ranges = domain.getValues().getRanges().getOrderedRanges();
// only apply predicates if all ranges are single values
if (ranges.isEmpty() || !ranges.stream().allMatch(Range::isSingleValue)) {
return "true";
}
ImmutableList.Builder<Object> valuesBuilder = ImmutableList.builder();
ImmutableList.Builder<JDBCType> typesBuilder = ImmutableList.builder();
StringJoiner rangePredicate = new StringJoiner(" OR ");
for (Range range : ranges) {
Slice uuidText = (Slice) range.getSingleValue();
try {
Slice uuidBytes = uuidStringToBytes(uuidText);
typesBuilder.add(jdbcType);
valuesBuilder.add(uuidBytes);
} catch (IllegalArgumentException e) {
return "true";
}
rangePredicate.add("shard_uuid = ?");
}
types.addAll(typesBuilder.build());
values.addAll(valuesBuilder.build());
return rangePredicate.toString();
}
use of io.trino.spi.predicate.Range in project trino by trinodb.
the class BigQueryFilterQueryBuilder method toPredicate.
private Optional<String> toPredicate(String columnName, Domain domain, BigQueryColumnHandle column) {
if (domain.getValues().isNone()) {
String predicate = domain.isNullAllowed() ? quote(columnName) + " IS NULL" : "FALSE";
return Optional.of(predicate);
}
if (domain.getValues().isAll()) {
String predicate = domain.isNullAllowed() ? "TRUE" : quote(columnName) + " IS NOT NULL";
return Optional.of(predicate);
}
List<String> disjuncts = new ArrayList<>();
List<String> singleValues = new ArrayList<>();
for (Range range : domain.getValues().getRanges().getOrderedRanges()) {
// Already checked
checkState(!range.isAll());
if (range.isSingleValue()) {
Optional<String> value = column.getBigQueryType().convertToString(column.getTrinoType(), range.getSingleValue());
if (value.isEmpty()) {
return Optional.empty();
}
singleValues.add(value.get());
} else {
List<String> rangeConjuncts = new ArrayList<>();
if (!range.isLowUnbounded()) {
Optional<String> predicate = toPredicate(columnName, range.isLowInclusive() ? ">=" : ">", range.getLowBoundedValue(), column);
if (predicate.isEmpty()) {
return Optional.empty();
}
rangeConjuncts.add(predicate.get());
}
if (!range.isHighUnbounded()) {
Optional<String> predicate = toPredicate(columnName, range.isHighInclusive() ? "<=" : "<", range.getHighBoundedValue(), column);
if (predicate.isEmpty()) {
return Optional.empty();
}
rangeConjuncts.add(predicate.get());
}
// If rangeConjuncts is null, then the range was ALL, which should already have been checked for
checkState(!rangeConjuncts.isEmpty());
disjuncts.add("(" + concat(rangeConjuncts) + ")");
}
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
String predicate = quote(columnName) + " = " + getOnlyElement(singleValues);
disjuncts.add(predicate);
} else if (singleValues.size() > 1) {
String values = String.join(",", singleValues);
disjuncts.add(quote(columnName) + " IN (" + values + ")");
}
// Add nullability disjuncts
checkState(!disjuncts.isEmpty());
if (domain.isNullAllowed()) {
disjuncts.add(quote(columnName) + " IS NULL");
}
return Optional.of("(" + String.join(" OR ", disjuncts) + ")");
}
use of io.trino.spi.predicate.Range in project trino by trinodb.
the class CassandraPartitionManager method getPartitionKeysList.
private static List<Set<Object>> getPartitionKeysList(CassandraTable table, TupleDomain<ColumnHandle> tupleDomain) {
ImmutableList.Builder<Set<Object>> partitionColumnValues = ImmutableList.builder();
for (CassandraColumnHandle columnHandle : table.getPartitionKeyColumns()) {
Domain domain = tupleDomain.getDomains().get().get(columnHandle);
// if there is no constraint on a partition key, return an empty set
if (domain == null) {
return ImmutableList.of();
}
// todo does cassandra allow null partition keys?
if (domain.isNullAllowed()) {
return ImmutableList.of();
}
Set<Object> values = domain.getValues().getValuesProcessor().transform(ranges -> {
ImmutableSet.Builder<Object> columnValues = ImmutableSet.builder();
for (Range range : ranges.getOrderedRanges()) {
// if the range is not a single value, we cannot perform partition pruning
if (!range.isSingleValue()) {
return ImmutableSet.of();
}
Object value = range.getSingleValue();
CassandraType valueType = columnHandle.getCassandraType();
if (valueType.isSupportedPartitionKey()) {
columnValues.add(value);
}
}
return columnValues.build();
}, discreteValues -> {
if (discreteValues.isInclusive()) {
return ImmutableSet.copyOf(discreteValues.getValues());
}
return ImmutableSet.of();
}, allOrNone -> ImmutableSet.of());
partitionColumnValues.add(values);
}
return partitionColumnValues.build();
}
Aggregations