Java Code Examples for io.prestosql.spi.predicate.TupleDomain#columnWiseUnion()

The following examples show how to use io.prestosql.spi.predicate.TupleDomain#columnWiseUnion() . 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: LocalDynamicFilterConsumer.java    From presto with Apache License 2.0 5 votes vote down vote up
private synchronized void addPartition(TupleDomain<DynamicFilterId> tupleDomain)
{
    // Called concurrently by each DynamicFilterSourceOperator instance (when collection is over).
    verify(partitions.size() < partitionCount);
    // NOTE: may result in a bit more relaxed constraint if there are multiple columns and multiple rows.
    // See the comment at TupleDomain::columnWiseUnion() for more details.
    partitions.add(tupleDomain);
    if (partitions.size() == partitionCount) {
        TupleDomain<DynamicFilterId> result = TupleDomain.columnWiseUnion(partitions);
        // No more partitions are left to be processed.
        resultFuture.set(result);
    }
}
 
Example 2
Source File: TestTpchMetadata.java    From presto with Apache License 2.0 5 votes vote down vote up
private Constraint constraint(TpchColumn<?> column, String... values)
{
    List<TupleDomain<ColumnHandle>> valueDomains = stream(values)
            .map(value -> fixedValueTupleDomain(tpchMetadata, column, utf8Slice(value)))
            .collect(toList());
    TupleDomain<ColumnHandle> domain = TupleDomain.columnWiseUnion(valueDomains);
    return new Constraint(domain, convertToPredicate(domain, column));
}
 
Example 3
Source File: DomainTranslator.java    From presto with Apache License 2.0 4 votes vote down vote up
@Override
protected ExtractionResult visitLogicalBinaryExpression(LogicalBinaryExpression node, Boolean complement)
{
    ExtractionResult leftResult = process(node.getLeft(), complement);
    ExtractionResult rightResult = process(node.getRight(), complement);

    TupleDomain<Symbol> leftTupleDomain = leftResult.getTupleDomain();
    TupleDomain<Symbol> rightTupleDomain = rightResult.getTupleDomain();

    LogicalBinaryExpression.Operator operator = complement ? node.getOperator().flip() : node.getOperator();
    switch (operator) {
        case AND:
            return new ExtractionResult(
                    leftTupleDomain.intersect(rightTupleDomain),
                    combineConjuncts(metadata, leftResult.getRemainingExpression(), rightResult.getRemainingExpression()));

        case OR:
            TupleDomain<Symbol> columnUnionedTupleDomain = TupleDomain.columnWiseUnion(leftTupleDomain, rightTupleDomain);

            // In most cases, the columnUnionedTupleDomain is only a superset of the actual strict union
            // and so we can return the current node as the remainingExpression so that all bounds will be double checked again at execution time.
            Expression remainingExpression = complementIfNecessary(node, complement);

            // However, there are a few cases where the column-wise union is actually equivalent to the strict union, so we if can detect
            // some of these cases, we won't have to double check the bounds unnecessarily at execution time.

            // We can only make inferences if the remaining expressions on both side are equal and deterministic
            if (leftResult.getRemainingExpression().equals(rightResult.getRemainingExpression()) &&
                    DeterminismEvaluator.isDeterministic(leftResult.getRemainingExpression(), metadata)) {
                // The column-wise union is equivalent to the strict union if
                // 1) If both TupleDomains consist of the same exact single column (e.g. left TupleDomain => (a > 0), right TupleDomain => (a < 10))
                // 2) If one TupleDomain is a superset of the other (e.g. left TupleDomain => (a > 0, b > 0 && b < 10), right TupleDomain => (a > 5, b = 5))
                boolean matchingSingleSymbolDomains = !leftTupleDomain.isNone()
                        && !rightTupleDomain.isNone()
                        && leftTupleDomain.getDomains().get().size() == 1
                        && rightTupleDomain.getDomains().get().size() == 1
                        && leftTupleDomain.getDomains().get().keySet().equals(rightTupleDomain.getDomains().get().keySet());
                boolean oneSideIsSuperSet = leftTupleDomain.contains(rightTupleDomain) || rightTupleDomain.contains(leftTupleDomain);

                if (oneSideIsSuperSet) {
                    remainingExpression = leftResult.getRemainingExpression();
                }
                else if (matchingSingleSymbolDomains) {
                    // Types REAL and DOUBLE require special handling because they include NaN value. In this case, we cannot rely on the union of domains.
                    // That is because domains covering the value set partially might union up to a domain covering the whole value set.
                    // While the component domains didn't include NaN, the resulting domain could be further translated to predicate "TRUE" or "a IS NOT NULL",
                    // which is satisfied by NaN. So during domain union, NaN might be implicitly added.
                    // Example: Let 'a' be a column of type DOUBLE.
                    //          Let left TupleDomain => (a > 0) /false for NaN/, right TupleDomain => (a < 10) /false for NaN/.
                    //          Unioned TupleDomain => "is not null" /true for NaN/
                    // To guard against wrong results, the current node is returned as the remainingExpression.
                    Domain leftDomain = getOnlyElement(leftTupleDomain.getDomains().get().values());
                    Domain rightDomain = getOnlyElement(rightTupleDomain.getDomains().get().values());
                    Type type = leftDomain.getType();

                    // A Domain of a floating point type contains NaN in the following cases:
                    // 1. When it contains all the values of the type and null.
                    //    In such case the domain is 'all', and if it is the only domain
                    //    in the TupleDomain, the TupleDomain gets normalized to TupleDomain 'all'.
                    // 2. When it contains all the values of the type and doesn't contain null.
                    //    In such case no normalization on the level of TupleDomain takes place,
                    //    and the check for NaN is done by inspecting the Domain's valueSet.
                    //    NaN is included when the valueSet is 'all'.
                    boolean unionedDomainContainsNaN = columnUnionedTupleDomain.isAll() ||
                            (columnUnionedTupleDomain.getDomains().isPresent() &&
                                    getOnlyElement(columnUnionedTupleDomain.getDomains().get().values()).getValues().isAll());
                    boolean implicitlyAddedNaN = (type instanceof RealType || type instanceof DoubleType) &&
                            !leftDomain.getValues().isAll() &&
                            !rightDomain.getValues().isAll() &&
                            unionedDomainContainsNaN;
                    if (!implicitlyAddedNaN) {
                        remainingExpression = leftResult.getRemainingExpression();
                    }
                }
            }

            return new ExtractionResult(columnUnionedTupleDomain, remainingExpression);

        default:
            throw new AssertionError("Unknown operator: " + node.getOperator());
    }
}