Search in sources :

Example 6 with ValueSet

use of io.trino.spi.predicate.ValueSet in project trino by trinodb.

the class PushPredicateThroughProjectIntoRowNumber method extractUpperBound.

private static OptionalInt extractUpperBound(TupleDomain<Symbol> tupleDomain, Symbol symbol) {
    if (tupleDomain.isNone()) {
        return OptionalInt.empty();
    }
    Domain rowNumberDomain = tupleDomain.getDomains().get().get(symbol);
    if (rowNumberDomain == null) {
        return OptionalInt.empty();
    }
    ValueSet values = rowNumberDomain.getValues();
    if (values.isAll() || values.isNone() || values.getRanges().getRangeCount() <= 0) {
        return OptionalInt.empty();
    }
    Range span = values.getRanges().getSpan();
    if (span.isHighUnbounded()) {
        return OptionalInt.empty();
    }
    long upperBound = (Long) span.getHighBoundedValue();
    if (!span.isHighInclusive()) {
        upperBound--;
    }
    if (upperBound >= Integer.MIN_VALUE && upperBound <= Integer.MAX_VALUE) {
        return OptionalInt.of(toIntExact(upperBound));
    }
    return OptionalInt.empty();
}
Also used : Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Range(io.trino.spi.predicate.Range) ValueSet(io.trino.spi.predicate.ValueSet)

Example 7 with ValueSet

use of io.trino.spi.predicate.ValueSet in project trino by trinodb.

the class PushdownFilterIntoRowNumber method extractUpperBound.

private static OptionalInt extractUpperBound(TupleDomain<Symbol> tupleDomain, Symbol symbol) {
    if (tupleDomain.isNone()) {
        return OptionalInt.empty();
    }
    Domain rowNumberDomain = tupleDomain.getDomains().get().get(symbol);
    if (rowNumberDomain == null) {
        return OptionalInt.empty();
    }
    ValueSet values = rowNumberDomain.getValues();
    if (values.isAll() || values.isNone() || values.getRanges().getRangeCount() <= 0) {
        return OptionalInt.empty();
    }
    Range span = values.getRanges().getSpan();
    if (span.isHighUnbounded()) {
        return OptionalInt.empty();
    }
    verify(rowNumberDomain.getType().equals(BIGINT));
    long upperBound = (Long) span.getHighBoundedValue();
    if (!span.isHighInclusive()) {
        upperBound--;
    }
    if (upperBound >= Integer.MIN_VALUE && upperBound <= Integer.MAX_VALUE) {
        return OptionalInt.of(toIntExact(upperBound));
    }
    return OptionalInt.empty();
}
Also used : Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Range(io.trino.spi.predicate.Range) ValueSet(io.trino.spi.predicate.ValueSet)

Example 8 with ValueSet

use of io.trino.spi.predicate.ValueSet in project trino by trinodb.

the class PushdownFilterIntoWindow method extractUpperBound.

private static OptionalInt extractUpperBound(TupleDomain<Symbol> tupleDomain, Symbol symbol) {
    if (tupleDomain.isNone()) {
        return OptionalInt.empty();
    }
    Domain rowNumberDomain = tupleDomain.getDomains().get().get(symbol);
    if (rowNumberDomain == null) {
        return OptionalInt.empty();
    }
    ValueSet values = rowNumberDomain.getValues();
    if (values.isAll() || values.isNone() || values.getRanges().getRangeCount() <= 0) {
        return OptionalInt.empty();
    }
    Range span = values.getRanges().getSpan();
    if (span.isHighUnbounded()) {
        return OptionalInt.empty();
    }
    verify(rowNumberDomain.getType().equals(BIGINT));
    long upperBound = (Long) span.getHighBoundedValue();
    if (!span.isHighInclusive()) {
        upperBound--;
    }
    if (upperBound >= Integer.MIN_VALUE && upperBound <= Integer.MAX_VALUE) {
        return OptionalInt.of(toIntExact(upperBound));
    }
    return OptionalInt.empty();
}
Also used : Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Range(io.trino.spi.predicate.Range) ValueSet(io.trino.spi.predicate.ValueSet)

Example 9 with ValueSet

use of io.trino.spi.predicate.ValueSet in project trino by trinodb.

the class DefaultQueryBuilder method toPredicate.

protected String toPredicate(JdbcClient client, ConnectorSession session, Connection connection, JdbcColumnHandle column, ValueSet valueSet, Consumer<QueryParameter> accumulator) {
    checkArgument(!valueSet.isNone(), "none values should be handled earlier");
    if (!valueSet.isDiscreteSet()) {
        ValueSet complement = valueSet.complement();
        if (complement.isDiscreteSet()) {
            return format("NOT (%s)", toPredicate(client, session, connection, column, complement, accumulator));
        }
    }
    JdbcTypeHandle jdbcType = column.getJdbcTypeHandle();
    Type type = column.getColumnType();
    WriteFunction writeFunction = getWriteFunction(client, session, connection, jdbcType, type);
    List<String> disjuncts = new ArrayList<>();
    List<Object> singleValues = new ArrayList<>();
    for (Range range : valueSet.getRanges().getOrderedRanges()) {
        // Already checked
        checkState(!range.isAll());
        if (range.isSingleValue()) {
            singleValues.add(range.getSingleValue());
        } else {
            List<String> rangeConjuncts = new ArrayList<>();
            if (!range.isLowUnbounded()) {
                rangeConjuncts.add(toPredicate(client, session, column, jdbcType, type, writeFunction, range.isLowInclusive() ? ">=" : ">", range.getLowBoundedValue(), accumulator));
            }
            if (!range.isHighUnbounded()) {
                rangeConjuncts.add(toPredicate(client, session, column, jdbcType, type, writeFunction, range.isHighInclusive() ? "<=" : "<", range.getHighBoundedValue(), accumulator));
            }
            // If rangeConjuncts is null, then the range was ALL, which should already have been checked for
            checkState(!rangeConjuncts.isEmpty());
            if (rangeConjuncts.size() == 1) {
                disjuncts.add(getOnlyElement(rangeConjuncts));
            } else {
                disjuncts.add("(" + Joiner.on(" AND ").join(rangeConjuncts) + ")");
            }
        }
    }
    // Add back all of the possible single values either as an equality or an IN predicate
    if (singleValues.size() == 1) {
        disjuncts.add(toPredicate(client, session, column, jdbcType, type, writeFunction, "=", getOnlyElement(singleValues), accumulator));
    } else if (singleValues.size() > 1) {
        for (Object value : singleValues) {
            accumulator.accept(new QueryParameter(jdbcType, type, Optional.of(value)));
        }
        String values = Joiner.on(",").join(nCopies(singleValues.size(), writeFunction.getBindExpression()));
        disjuncts.add(client.quoted(column.getColumnName()) + " IN (" + values + ")");
    }
    checkState(!disjuncts.isEmpty());
    if (disjuncts.size() == 1) {
        return getOnlyElement(disjuncts);
    }
    return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}
Also used : Type(io.trino.spi.type.Type) JoinType(io.trino.spi.connector.JoinType) ArrayList(java.util.ArrayList) Range(io.trino.spi.predicate.Range) ValueSet(io.trino.spi.predicate.ValueSet)

Example 10 with ValueSet

use of io.trino.spi.predicate.ValueSet in project trino by trinodb.

the class GlueExpressionUtil method buildGlueExpressionForSingleDomain.

/**
 * Converts domain to a valid glue expression per
 * https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog-partitions.html#aws-glue-api-catalog-partitions-GetPartitions
 *
 * @return optional glue-compatible expression. if empty, either tye type of the {@link Domain} cannot be converted to a string, or the filter is {@link Domain#all}
 */
@VisibleForTesting
static Optional<String> buildGlueExpressionForSingleDomain(String columnName, Domain domain, boolean assumeCanonicalPartitionKeys) {
    ValueSet valueSet = domain.getValues();
    if (domain.isAll() || !canConvertSqlTypeToStringForGlue(domain.getType(), assumeCanonicalPartitionKeys)) {
        // if the type can't be converted or Domain.all()
        return Optional.empty();
    }
    if (domain.getValues().isAll()) {
        return Optional.of(format("(%s <> '%s')", columnName, NULL_STRING));
    }
    // null must be allowed for this case since callers must filter Domain.none() out
    if (domain.getValues().isNone()) {
        return Optional.of(format("(%s = '%s')", columnName, NULL_STRING));
    }
    List<String> disjuncts = new ArrayList<>();
    List<String> singleValues = new ArrayList<>();
    for (Range range : valueSet.getRanges().getOrderedRanges()) {
        // Already checked
        checkState(!range.isAll());
        if (range.isSingleValue()) {
            singleValues.add(valueToString(range.getType(), range.getSingleValue()));
        } else {
            List<String> rangeConjuncts = new ArrayList<>();
            if (!range.isLowUnbounded()) {
                rangeConjuncts.add(format("%s %s %s", columnName, range.isLowInclusive() ? ">=" : ">", valueToString(range.getType(), range.getLowBoundedValue())));
            }
            if (!range.isHighUnbounded()) {
                rangeConjuncts.add(format("%s %s %s", columnName, range.isHighInclusive() ? "<=" : "<", valueToString(range.getType(), range.getHighBoundedValue())));
            }
            // If rangeConjuncts is null, then the range was ALL, which should already have been checked for by callers
            checkState(!rangeConjuncts.isEmpty());
            disjuncts.add("(" + CONJUNCT_JOINER.join(rangeConjuncts) + ")");
        }
    }
    if (singleValues.size() == 1) {
        String equalsTest = format("(%s = %s)", columnName, getOnlyElement(singleValues));
        disjuncts.add(equalsTest);
    } else if (singleValues.size() > 1) {
        String values = Joiner.on(", ").join(singleValues);
        String inClause = format("(%s in (%s))", columnName, values);
        disjuncts.add(inClause);
    }
    return Optional.of("(" + DISJUNCT_JOINER.join(disjuncts) + ")");
}
Also used : ArrayList(java.util.ArrayList) Range(io.trino.spi.predicate.Range) ValueSet(io.trino.spi.predicate.ValueSet) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

ValueSet (io.trino.spi.predicate.ValueSet)15 Domain (io.trino.spi.predicate.Domain)13 TupleDomain (io.trino.spi.predicate.TupleDomain)13 Range (io.trino.spi.predicate.Range)11 ColumnHandle (io.trino.spi.connector.ColumnHandle)8 VisibleForTesting (com.google.common.annotations.VisibleForTesting)4 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)4 List (java.util.List)4 TrinoException (io.trino.spi.TrinoException)3 ConnectorSession (io.trino.spi.connector.ConnectorSession)3 Ranges (io.trino.spi.predicate.Ranges)3 SortedRangeSet (io.trino.spi.predicate.SortedRangeSet)3 String.format (java.lang.String.format)3 Instant (java.time.Instant)3 Map (java.util.Map)3 Optional (java.util.Optional)3 Set (java.util.Set)3 Test (org.testng.annotations.Test)3 Verify.verify (com.google.common.base.Verify.verify)2 ImmutableList (com.google.common.collect.ImmutableList)2