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

The following examples show how to use io.prestosql.spi.predicate.TupleDomain#intersect() . 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: AccumuloMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    AccumuloTableHandle handle = (AccumuloTableHandle) table;

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new AccumuloTableHandle(
            handle.getSchema(),
            handle.getTable(),
            handle.getRowId(),
            newDomain,
            handle.isExternal(),
            handle.getSerializerClassName(),
            handle.getScanAuthorizations());

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 2
Source File: MongoMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    MongoTableHandle handle = (MongoTableHandle) table;

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new MongoTableHandle(
            handle.getSchemaTableName(),
            newDomain);

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 3
Source File: ThriftMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    ThriftTableHandle handle = (ThriftTableHandle) table;

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new ThriftTableHandle(
            handle.getSchemaName(),
            handle.getTableName(),
            newDomain,
            handle.getDesiredColumns());

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 4
Source File: BigQueryMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(
        ConnectorSession session,
        ConnectorTableHandle handle,
        Constraint constraint)
{
    log.debug("applyFilter(session=%s, handle=%s, summary=%s, predicate=%s, columns=%s)",
            session, handle, constraint.getSummary(), constraint.predicate(), constraint.getPredicateColumns());
    BigQueryTableHandle bigQueryTableHandle = (BigQueryTableHandle) handle;

    TupleDomain<ColumnHandle> oldDomain = bigQueryTableHandle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    BigQueryTableHandle updatedHandle = bigQueryTableHandle.withConstraint(newDomain);

    return Optional.of(new ConstraintApplicationResult<>(updatedHandle, constraint.getSummary()));
}
 
Example 5
Source File: LocalFileMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    LocalFileTableHandle handle = (LocalFileTableHandle) table;

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new LocalFileTableHandle(
            handle.getSchemaTableName(),
            handle.getTimestampColumn(),
            handle.getServerAddressColumn(),
            newDomain);

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 6
Source File: KuduMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    KuduTableHandle handle = (KuduTableHandle) table;

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new KuduTableHandle(
            handle.getSchemaTableName(),
            handle.getTable(clientSession),
            newDomain,
            handle.getDesiredColumns(),
            handle.isDeleteHandle());

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 7
Source File: PinotMetadata.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    PinotTableHandle handle = (PinotTableHandle) table;
    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new PinotTableHandle(
            handle.getSchemaName(),
            handle.getTableName(),
            newDomain,
            handle.getLimit(),
            handle.getQuery());
    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 8
Source File: JmxMetadata.java    From presto with Apache License 2.0 5 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle handle, Constraint constraint)
{
    Optional<Map<ColumnHandle, Domain>> domains = constraint.getSummary().getDomains();
    if (domains.isEmpty()) {
        return Optional.empty();
    }

    JmxTableHandle tableHandle = (JmxTableHandle) handle;

    Map<ColumnHandle, Domain> nodeDomains = new LinkedHashMap<>();
    Map<ColumnHandle, Domain> otherDomains = new LinkedHashMap<>();
    domains.get().forEach((column, domain) -> {
        JmxColumnHandle columnHandle = (JmxColumnHandle) column;
        if (columnHandle.getColumnName().equals(NODE_COLUMN_NAME)) {
            nodeDomains.put(column, domain);
        }
        else {
            otherDomains.put(column, domain);
        }
    });

    TupleDomain<ColumnHandle> oldDomain = tableHandle.getNodeFilter();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(TupleDomain.withColumnDomains(nodeDomains));

    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    JmxTableHandle newTableHandle = new JmxTableHandle(tableHandle.getTableName(), tableHandle.getObjectNames(), tableHandle.getColumnHandles(), tableHandle.isLiveData(), newDomain);

    return Optional.of(new ConstraintApplicationResult<>(newTableHandle, TupleDomain.withColumnDomains(otherDomains)));
}
 
Example 9
Source File: JdbcMetadata.java    From presto with Apache License 2.0 5 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    JdbcTableHandle handle = (JdbcTableHandle) table;

    if (handle.getGroupingSets().isPresent()) {
        // handle's aggregations are applied after constraint, so we cannot apply filter if aggregates is already set
        // TODO (https://github.com/prestosql/presto/issues/4112) allow filter pushdown after aggregation pushdown
        return Optional.empty();
    }

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new JdbcTableHandle(
            handle.getSchemaTableName(),
            handle.getCatalogName(),
            handle.getSchemaName(),
            handle.getTableName(),
            newDomain,
            Optional.empty(), // groupBy
            handle.getLimit(),
            handle.getColumns());

    return Optional.of(new ConstraintApplicationResult<>(handle, constraint.getSummary()));
}
 
Example 10
Source File: SystemTablesMetadata.java    From presto with Apache License 2.0 5 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle handle, Constraint constraint)
{
    SystemTableHandle table = (SystemTableHandle) handle;

    TupleDomain<ColumnHandle> oldDomain = table.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain) && constraint.predicate().isEmpty()) {
        return Optional.empty();
    }

    SystemTable systemTable = checkAndGetTable(session, table);
    if (systemTable instanceof JdbcTable) {
        TupleDomain<ColumnHandle> filtered = ((JdbcTable) systemTable).applyFilter(session, new Constraint(newDomain, constraint.predicate(), constraint.getColumns()));
        newDomain = newDomain.intersect(filtered);
    }

    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    if (newDomain.isNone()) {
        // TODO (https://github.com/prestosql/presto/issues/3647) indicate the table scan is empty
    }
    table = new SystemTableHandle(table.getSchemaName(), table.getTableName(), newDomain);
    return Optional.of(new ConstraintApplicationResult<>(table, constraint.getSummary()));
}
 
Example 11
Source File: HBaseMetadata.java    From presto-hbase-connector with Apache License 2.0 5 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session,
                                                                               ConnectorTableHandle handle,
                                                                               Constraint constraint) {
    HBaseTableHandle tableHandle = (HBaseTableHandle) handle;
    TupleDomain<ColumnHandle> oldDomain = tableHandle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }
    tableHandle = new HBaseTableHandle(tableHandle.getSchemaTableName(), newDomain);
    return Optional.of(new ConstraintApplicationResult<>(tableHandle, constraint.getSummary()));
}
 
Example 12
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());
    }
}
 
Example 13
Source File: ElasticsearchMetadata.java    From presto with Apache License 2.0 4 votes vote down vote up
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint)
{
    ElasticsearchTableHandle handle = (ElasticsearchTableHandle) table;

    if (isPassthroughQuery(handle)) {
        // filter pushdown currently not supported for passthrough query
        return Optional.empty();
    }

    Map<ColumnHandle, Domain> supported = new HashMap<>();
    Map<ColumnHandle, Domain> unsupported = new HashMap<>();
    if (constraint.getSummary().getDomains().isPresent()) {
        for (Map.Entry<ColumnHandle, Domain> entry : constraint.getSummary().getDomains().get().entrySet()) {
            ElasticsearchColumnHandle column = (ElasticsearchColumnHandle) entry.getKey();

            if (column.isSupportsPredicates()) {
                supported.put(column, entry.getValue());
            }
            else {
                unsupported.put(column, entry.getValue());
            }
        }
    }

    TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
    TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(TupleDomain.withColumnDomains(supported));
    if (oldDomain.equals(newDomain)) {
        return Optional.empty();
    }

    handle = new ElasticsearchTableHandle(
            handle.getType(),
            handle.getSchema(),
            handle.getIndex(),
            newDomain,
            handle.getQuery(),
            handle.getLimit());

    return Optional.of(new ConstraintApplicationResult<>(handle, TupleDomain.withColumnDomains(unsupported)));
}