Search in sources :

Example 11 with Range

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);
            }
        }
    }
}
Also used : ColumnHandle(io.trino.spi.connector.ColumnHandle) Ranges(io.trino.spi.predicate.Ranges) Schema(org.apache.kudu.Schema) ColumnSchema(org.apache.kudu.ColumnSchema) HashBucketSchema(org.apache.kudu.client.PartitionSchema.HashBucketSchema) EquatableValueSet(io.trino.spi.predicate.EquatableValueSet) ColumnSchema(org.apache.kudu.ColumnSchema) Range(io.trino.spi.predicate.Range) KuduPredicate(org.apache.kudu.client.KuduPredicate) Type(org.apache.kudu.Type) DecimalType(io.trino.spi.type.DecimalType) TupleDomain(io.trino.spi.predicate.TupleDomain) SortedRangeSet(io.trino.spi.predicate.SortedRangeSet) DiscreteValues(io.trino.spi.predicate.DiscreteValues) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Collectors.toList(java.util.stream.Collectors.toList) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) EquatableValueSet(io.trino.spi.predicate.EquatableValueSet) ValueSet(io.trino.spi.predicate.ValueSet)

Example 12 with Range

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());
}
Also used : Ranges(io.trino.spi.predicate.Ranges) JDBCType(java.sql.JDBCType) RaptorColumnHandle(io.trino.plugin.raptor.legacy.RaptorColumnHandle) ImmutableList(com.google.common.collect.ImmutableList) Range(io.trino.spi.predicate.Range) Type(io.trino.spi.type.Type) JDBCType(java.sql.JDBCType) ColumnIndexStatsUtils.jdbcType(io.trino.plugin.raptor.legacy.storage.ColumnIndexStatsUtils.jdbcType) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) StringJoiner(java.util.StringJoiner)

Example 13 with Range

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();
}
Also used : JDBCType(java.sql.JDBCType) ImmutableList(com.google.common.collect.ImmutableList) Slice(io.airlift.slice.Slice) Range(io.trino.spi.predicate.Range) StringJoiner(java.util.StringJoiner)

Example 14 with Range

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) + ")");
}
Also used : ArrayList(java.util.ArrayList) Range(io.trino.spi.predicate.Range)

Example 15 with Range

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();
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) ImmutableList(com.google.common.collect.ImmutableList) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Range(io.trino.spi.predicate.Range)

Aggregations

Range (io.trino.spi.predicate.Range)30 TupleDomain (io.trino.spi.predicate.TupleDomain)16 Domain (io.trino.spi.predicate.Domain)15 ValueSet (io.trino.spi.predicate.ValueSet)12 ArrayList (java.util.ArrayList)12 ImmutableList (com.google.common.collect.ImmutableList)10 ColumnHandle (io.trino.spi.connector.ColumnHandle)9 List (java.util.List)7 Test (org.testng.annotations.Test)7 ImmutableSet (com.google.common.collect.ImmutableSet)4 Instant (java.time.Instant)4 Objects.requireNonNull (java.util.Objects.requireNonNull)4 Set (java.util.Set)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)3 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)3 Slice (io.airlift.slice.Slice)3 PrometheusSplitManager.decimalSecondString (io.trino.plugin.prometheus.PrometheusSplitManager.decimalSecondString)3 Type (io.trino.spi.type.Type)3 String.format (java.lang.String.format)3