Java Code Examples for io.prestosql.spi.predicate.Domain#isNullAllowed()

The following examples show how to use io.prestosql.spi.predicate.Domain#isNullAllowed() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: IoPlanPrinter.java    From presto with Apache License 2.0 6 votes vote down vote up
private FormattedDomain parseDomain(Domain domain)
{
    ImmutableSet.Builder<FormattedRange> formattedRanges = ImmutableSet.builder();
    Type type = domain.getType();

    domain.getValues().getValuesProcessor().consume(
            ranges -> formattedRanges.addAll(
                    ranges.getOrderedRanges().stream()
                            .map(range -> new FormattedRange(formatMarker(range.getLow()), formatMarker(range.getHigh())))
                            .collect(toImmutableSet())),
            discreteValues -> formattedRanges.addAll(
                    discreteValues.getValues().stream()
                            .map(value -> valuePrinter.castToVarcharOrFail(type, value))
                            .map(value -> new FormattedMarker(Optional.of(value), EXACTLY))
                            .map(marker -> new FormattedRange(marker, marker))
                            .collect(toImmutableSet())),
            allOrNone -> {
                throw new IllegalStateException("Unreachable AllOrNone consumer");
            });

    return new FormattedDomain(domain.isNullAllowed(), formattedRanges.build());
}
 
Example 2
Source File: DomainTranslator.java    From presto with Apache License 2.0 6 votes vote down vote up
private Expression toPredicate(Domain domain, SymbolReference reference)
{
    if (domain.getValues().isNone()) {
        return domain.isNullAllowed() ? new IsNullPredicate(reference) : FALSE_LITERAL;
    }

    if (domain.getValues().isAll()) {
        return domain.isNullAllowed() ? TRUE_LITERAL : new NotExpression(new IsNullPredicate(reference));
    }

    List<Expression> disjuncts = new ArrayList<>();

    disjuncts.addAll(domain.getValues().getValuesProcessor().transform(
            ranges -> extractDisjuncts(domain.getType(), ranges, reference),
            discreteValues -> extractDisjuncts(domain.getType(), discreteValues, reference),
            allOrNone -> {
                throw new IllegalStateException("Case should not be reachable");
            }));

    // Add nullability disjuncts
    if (domain.isNullAllowed()) {
        disjuncts.add(new IsNullPredicate(reference));
    }

    return combineDisjunctsWithDefault(metadata, disjuncts, TRUE_LITERAL);
}
 
Example 3
Source File: TupleDomainOrcPredicate.java    From presto with Apache License 2.0 5 votes vote down vote up
private boolean columnOverlaps(Domain predicateDomain, long numberOfRows, ColumnStatistics columnStatistics)
{
    Domain stripeDomain = getDomain(predicateDomain.getType(), numberOfRows, columnStatistics);
    if (!stripeDomain.overlaps(predicateDomain)) {
        // there is no overlap between the predicate and this column
        return false;
    }

    // if bloom filters are not enabled, we cannot restrict the range overlap
    if (!orcBloomFiltersEnabled) {
        return true;
    }

    // if there an overlap in null values, the bloom filter cannot eliminate the overlap
    if (predicateDomain.isNullAllowed() && stripeDomain.isNullAllowed()) {
        return true;
    }

    // extract the discrete values from the predicate
    Optional<Collection<Object>> discreteValues = extractDiscreteValues(predicateDomain.getValues());
    if (discreteValues.isEmpty()) {
        // values are not discrete, so we can't exclude this section
        return true;
    }

    BloomFilter bloomFilter = columnStatistics.getBloomFilter();
    if (bloomFilter == null) {
        // no bloom filter so we can't exclude this section
        return true;
    }

    // if none of the discrete predicate values are found in the bloom filter, there is no overlap and the section should be skipped
    return discreteValues.get().stream().anyMatch(value -> checkInBloomFilter(bloomFilter, value, stripeDomain.getType()));
}
 
Example 4
Source File: QueryBuilder.java    From presto with Apache License 2.0 4 votes vote down vote up
private String toPredicate(String columnName, Domain domain, JdbcColumnHandle column, List<TypeAndValue> accumulator)
{
    if (domain.getValues().isNone()) {
        return domain.isNullAllowed() ? quote(columnName) + " IS NULL" : ALWAYS_FALSE;
    }

    if (domain.getValues().isAll()) {
        return domain.isNullAllowed() ? ALWAYS_TRUE : quote(columnName) + " IS NOT NULL";
    }

    List<String> disjuncts = new ArrayList<>();
    List<Object> singleValues = new ArrayList<>();
    for (Range range : domain.getValues().getRanges().getOrderedRanges()) {
        checkState(!range.isAll()); // Already checked
        if (range.isSingleValue()) {
            singleValues.add(range.getLow().getValue());
        }
        else {
            List<String> rangeConjuncts = new ArrayList<>();
            if (!range.getLow().isLowerUnbounded()) {
                switch (range.getLow().getBound()) {
                    case ABOVE:
                        rangeConjuncts.add(toPredicate(columnName, ">", range.getLow().getValue(), column, accumulator));
                        break;
                    case EXACTLY:
                        rangeConjuncts.add(toPredicate(columnName, ">=", range.getLow().getValue(), column, accumulator));
                        break;
                    case BELOW:
                        throw new IllegalArgumentException("Low marker should never use BELOW bound");
                    default:
                        throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
                }
            }
            if (!range.getHigh().isUpperUnbounded()) {
                switch (range.getHigh().getBound()) {
                    case ABOVE:
                        throw new IllegalArgumentException("High marker should never use ABOVE bound");
                    case EXACTLY:
                        rangeConjuncts.add(toPredicate(columnName, "<=", range.getHigh().getValue(), column, accumulator));
                        break;
                    case BELOW:
                        rangeConjuncts.add(toPredicate(columnName, "<", range.getHigh().getValue(), column, accumulator));
                        break;
                    default:
                        throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
                }
            }
            // If rangeConjuncts is null, then the range was ALL, which should already have been checked for
            checkState(!rangeConjuncts.isEmpty());
            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(columnName, "=", getOnlyElement(singleValues), column, accumulator));
    }
    else if (singleValues.size() > 1) {
        for (Object value : singleValues) {
            bindValue(value, column, accumulator);
        }
        String values = Joiner.on(",").join(nCopies(singleValues.size(), "?"));
        disjuncts.add(quote(columnName) + " IN (" + values + ")");
    }

    // Add nullability disjuncts
    checkState(!disjuncts.isEmpty());
    if (domain.isNullAllowed()) {
        disjuncts.add(quote(columnName) + " IS NULL");
    }

    return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}
 
Example 5
Source File: PrestoThriftDomain.java    From presto with Apache License 2.0 4 votes vote down vote up
public static PrestoThriftDomain fromDomain(Domain domain)
{
    return new PrestoThriftDomain(fromValueSet(domain.getValues()), domain.isNullAllowed());
}
 
Example 6
Source File: ShardPredicate.java    From presto with Apache License 2.0 4 votes vote down vote up
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()) {
            Object minValue = null;
            Object maxValue = null;
            if (range.isSingleValue()) {
                minValue = range.getSingleValue();
                maxValue = range.getSingleValue();
            }
            else {
                if (!range.getLow().isLowerUnbounded()) {
                    minValue = range.getLow().getValue();
                }
                if (!range.getHigh().isUpperUnbounded()) {
                    maxValue = range.getHigh().getValue();
                }
            }

            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 (minValue != null) {
                rangePredicate.add(format("(%s >= ? OR %s IS NULL)", max, max));
                types.add(jdbcType);
                values.add(minValue);
            }
            if (maxValue != null) {
                rangePredicate.add(format("(%s <= ? OR %s IS NULL)", min, min));
                types.add(jdbcType);
                values.add(maxValue);
            }
            columnPredicate.add(rangePredicate.toString());
        }
        predicate.add(columnPredicate.toString());
    }
    return new ShardPredicate(predicate.toString(), types.build(), values.build());
}
 
Example 7
Source File: ExpressionConverter.java    From presto with Apache License 2.0 4 votes vote down vote up
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 EquatableValueSet) {
        expression = firstNonNull(expression, alwaysFalse());
        EquatableValueSet valueSet = (EquatableValueSet) domainValues;
        if (valueSet.isWhiteList()) {
            // if whitelist is true than this is a case of "in", otherwise this is a case of "not in".
            return or(expression, equal(columnName, valueSet.getValues()));
        }
        return or(expression, notEqual(columnName, valueSet.getValues()));
    }

    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 and EquatableValueSet but got " + domainValues.getClass().getSimpleName());
}
 
Example 8
Source File: BigQueryFilterQueryBuilder.java    From presto with Apache License 2.0 4 votes vote down vote up
private String toPredicate(String columnName, Domain domain, BigQueryColumnHandle column)
{
    if (domain.getValues().isNone()) {
        return domain.isNullAllowed() ? quote(columnName) + " IS NULL" : "FALSE";
    }

    if (domain.getValues().isAll()) {
        return domain.isNullAllowed() ? "TRUE" : quote(columnName) + " IS NOT NULL";
    }

    List<String> disjuncts = new ArrayList<>();
    List<Object> singleValues = new ArrayList<>();
    for (Range range : domain.getValues().getRanges().getOrderedRanges()) {
        checkState(!range.isAll()); // Already checked
        if (range.isSingleValue()) {
            singleValues.add(range.getLow().getValue());
        }
        else {
            List<String> rangeConjuncts = new ArrayList<>();
            if (!range.getLow().isLowerUnbounded()) {
                switch (range.getLow().getBound()) {
                    case ABOVE:
                        rangeConjuncts.add(toPredicate(columnName, ">", range.getLow().getValue(), column));
                        break;
                    case EXACTLY:
                        rangeConjuncts.add(toPredicate(columnName, ">=", range.getLow().getValue(), column));
                        break;
                    case BELOW:
                        throw new IllegalArgumentException("Low marker should never use BELOW bound");
                    default:
                        throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
                }
            }
            if (!range.getHigh().isUpperUnbounded()) {
                switch (range.getHigh().getBound()) {
                    case ABOVE:
                        throw new IllegalArgumentException("High marker should never use ABOVE bound");
                    case EXACTLY:
                        rangeConjuncts.add(toPredicate(columnName, "<=", range.getHigh().getValue(), column));
                        break;
                    case BELOW:
                        rangeConjuncts.add(toPredicate(columnName, "<", range.getHigh().getValue(), column));
                        break;
                    default:
                        throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
                }
            }
            // 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) {
        disjuncts.add(toPredicate(columnName, "=", getOnlyElement(singleValues), column));
    }
    else if (singleValues.size() > 1) {
        String values = singleValues.stream()
                .map(column.getBigQueryType()::convertToString)
                .collect(joining(","));
        disjuncts.add(quote(columnName) + " IN (" + values + ")");
    }

    // Add nullability disjuncts
    checkState(!disjuncts.isEmpty());
    if (domain.isNullAllowed()) {
        disjuncts.add(quote(columnName) + " IS NULL");
    }

    return "(" + String.join(" OR ", disjuncts) + ")";
}
 
Example 9
Source File: CassandraPartitionManager.java    From presto with Apache License 2.0 4 votes vote down vote up
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.isWhiteList()) {
                        return ImmutableSet.copyOf(discreteValues.getValues());
                    }
                    return ImmutableSet.of();
                },
                allOrNone -> ImmutableSet.of());
        partitionColumnValues.add(values);
    }
    return partitionColumnValues.build();
}
 
Example 10
Source File: IonSqlQueryBuilder.java    From presto with Apache License 2.0 4 votes vote down vote up
private String toPredicate(Domain domain, Type type, int position)
{
    checkArgument(domain.getType().isOrderable(), "Domain type must be orderable");

    if (domain.getValues().isNone()) {
        if (domain.isNullAllowed()) {
            return format("s._%d", position + 1) + " = '' ";
        }
        return "FALSE";
    }

    if (domain.getValues().isAll()) {
        if (domain.isNullAllowed()) {
            return "TRUE";
        }
        return format("s._%d", position + 1) + " <> '' ";
    }

    List<String> disjuncts = new ArrayList<>();
    List<Object> singleValues = new ArrayList<>();
    for (Range range : domain.getValues().getRanges().getOrderedRanges()) {
        checkState(!range.isAll());
        if (range.isSingleValue()) {
            singleValues.add(range.getLow().getValue());
            continue;
        }
        List<String> rangeConjuncts = new ArrayList<>();
        if (!range.getLow().isLowerUnbounded()) {
            switch (range.getLow().getBound()) {
                case ABOVE:
                    rangeConjuncts.add(toPredicate(">", range.getLow().getValue(), type, position));
                    break;
                case EXACTLY:
                    rangeConjuncts.add(toPredicate(">=", range.getLow().getValue(), type, position));
                    break;
                case BELOW:
                    throw new IllegalArgumentException("Low marker should never use BELOW bound");
                default:
                    throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
            }
        }
        if (!range.getHigh().isUpperUnbounded()) {
            switch (range.getHigh().getBound()) {
                case ABOVE:
                    throw new IllegalArgumentException("High marker should never use ABOVE bound");
                case EXACTLY:
                    rangeConjuncts.add(toPredicate("<=", range.getHigh().getValue(), type, position));
                    break;
                case BELOW:
                    rangeConjuncts.add(toPredicate("<", range.getHigh().getValue(), type, position));
                    break;
                default:
                    throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
            }
        }
        // If rangeConjuncts is null, then the range was ALL, which should already have been checked for
        checkState(!rangeConjuncts.isEmpty());
        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("=", getOnlyElement(singleValues), type, position));
    }
    else if (singleValues.size() > 1) {
        List<String> values = new ArrayList<>();
        for (Object value : singleValues) {
            checkType(type);
            values.add(valueToQuery(type, value));
        }
        disjuncts.add(createColumn(type, position) + " IN (" + Joiner.on(",").join(values) + ")");
    }

    // Add nullability disjuncts
    checkState(!disjuncts.isEmpty());
    if (domain.isNullAllowed()) {
        disjuncts.add(format("s._%d", position + 1) + " = '' ");
    }

    return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}