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();
}
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();
}
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();
}
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) + ")";
}
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) + ")");
}
Aggregations