Search in sources :

Example 1 with ExtractionResult

use of io.trino.sql.planner.DomainTranslator.ExtractionResult in project trino by trinodb.

the class RemoveRedundantPredicateAboveTableScan method apply.

@Override
public Result apply(FilterNode filterNode, Captures captures, Context context) {
    Session session = context.getSession();
    TableScanNode node = captures.get(TABLE_SCAN);
    Expression predicate = filterNode.getPredicate();
    Expression deterministicPredicate = filterDeterministicConjuncts(plannerContext.getMetadata(), predicate);
    Expression nonDeterministicPredicate = filterNonDeterministicConjuncts(plannerContext.getMetadata(), predicate);
    ExtractionResult decomposedPredicate = getFullyExtractedPredicates(session, deterministicPredicate, context.getSymbolAllocator().getTypes());
    if (decomposedPredicate.getTupleDomain().isAll()) {
        // no conjunct could be fully converted to tuple domain
        return Result.empty();
    }
    TupleDomain<ColumnHandle> predicateDomain = decomposedPredicate.getTupleDomain().transformKeys(node.getAssignments()::get);
    if (predicateDomain.isNone()) {
        // to turn the subtree into a Values node
        return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
    }
    if (node.getEnforcedConstraint().isNone()) {
        // table scans with none domain should be converted to ValuesNode
        return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
    }
    // is not NONE
    Map<ColumnHandle, Domain> enforcedColumnDomains = node.getEnforcedConstraint().getDomains().orElseThrow();
    TupleDomain<ColumnHandle> unenforcedDomain = predicateDomain.transformDomains((columnHandle, predicateColumnDomain) -> {
        Type type = predicateColumnDomain.getType();
        Domain enforcedColumnDomain = Optional.ofNullable(enforcedColumnDomains.get(columnHandle)).orElseGet(() -> Domain.all(type));
        if (predicateColumnDomain.contains(enforcedColumnDomain)) {
            // full enforced
            return Domain.all(type);
        }
        return predicateColumnDomain.intersect(enforcedColumnDomain);
    });
    if (unenforcedDomain.equals(predicateDomain)) {
        // no change in filter predicate
        return Result.empty();
    }
    Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
    Expression resultingPredicate = createResultingPredicate(plannerContext, session, context.getSymbolAllocator(), typeAnalyzer, // Dynamic filters are included in decomposedPredicate.getRemainingExpression()
    TRUE_LITERAL, new DomainTranslator(plannerContext).toPredicate(session, unenforcedDomain.transformKeys(assignments::get)), nonDeterministicPredicate, decomposedPredicate.getRemainingExpression());
    if (!TRUE_LITERAL.equals(resultingPredicate)) {
        return Result.ofPlanNode(new FilterNode(context.getIdAllocator().getNextId(), node, resultingPredicate));
    }
    return Result.ofPlanNode(node);
}
Also used : ColumnHandle(io.trino.spi.connector.ColumnHandle) ValuesNode(io.trino.sql.planner.plan.ValuesNode) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) Type(io.trino.spi.type.Type) TableScanNode(io.trino.sql.planner.plan.TableScanNode) Expression(io.trino.sql.tree.Expression) DomainTranslator(io.trino.sql.planner.DomainTranslator) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Session(io.trino.Session)

Example 2 with ExtractionResult

use of io.trino.sql.planner.DomainTranslator.ExtractionResult in project trino by trinodb.

the class TestDomainTranslator method testNoneRoundTrip.

@Test
public void testNoneRoundTrip() {
    TupleDomain<Symbol> tupleDomain = TupleDomain.none();
    ExtractionResult result = fromPredicate(toPredicate(tupleDomain));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    assertEquals(result.getTupleDomain(), tupleDomain);
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Test(org.testng.annotations.Test)

Example 3 with ExtractionResult

use of io.trino.sql.planner.DomainTranslator.ExtractionResult in project trino by trinodb.

the class TestDomainTranslator method testAllRoundTrip.

@Test
public void testAllRoundTrip() {
    TupleDomain<Symbol> tupleDomain = TupleDomain.all();
    ExtractionResult result = fromPredicate(toPredicate(tupleDomain));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    assertEquals(result.getTupleDomain(), tupleDomain);
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Test(org.testng.annotations.Test)

Example 4 with ExtractionResult

use of io.trino.sql.planner.DomainTranslator.ExtractionResult in project trino by trinodb.

the class TestDomainTranslator method testFromAndPredicate.

@Test
public void testFromAndPredicate() {
    Expression originalPredicate = and(and(greaterThan(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(lessThan(C_BIGINT, bigintLiteral(5L)), unprocessableExpression2(C_BIGINT)));
    ExtractionResult result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), and(unprocessableExpression1(C_BIGINT), unprocessableExpression2(C_BIGINT)));
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.ofRanges(Range.range(BIGINT, 1L, false, 5L, false)), false)));
    // Test complements
    assertUnsupportedPredicate(not(and(and(greaterThan(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(lessThan(C_BIGINT, bigintLiteral(5L)), unprocessableExpression2(C_BIGINT)))));
    originalPredicate = not(and(not(and(greaterThan(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT))), not(and(lessThan(C_BIGINT, bigintLiteral(5L)), unprocessableExpression2(C_BIGINT)))));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.notNull(BIGINT)));
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Test(org.testng.annotations.Test)

Example 5 with ExtractionResult

use of io.trino.sql.planner.DomainTranslator.ExtractionResult in project trino by trinodb.

the class TestDomainTranslator method testFromSingleBooleanReference.

@Test
public void testFromSingleBooleanReference() {
    Expression originalPredicate = C_BOOLEAN.toSymbolReference();
    ExtractionResult result = fromPredicate(originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BOOLEAN, Domain.create(ValueSet.ofRanges(Range.equal(BOOLEAN, true)), false)));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    originalPredicate = not(C_BOOLEAN.toSymbolReference());
    result = fromPredicate(originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BOOLEAN, Domain.create(ValueSet.ofRanges(Range.equal(BOOLEAN, true)).complement(), false)));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    originalPredicate = and(C_BOOLEAN.toSymbolReference(), C_BOOLEAN_1.toSymbolReference());
    result = fromPredicate(originalPredicate);
    Domain domain = Domain.create(ValueSet.ofRanges(Range.equal(BOOLEAN, true)), false);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BOOLEAN, domain, C_BOOLEAN_1, domain));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    originalPredicate = or(C_BOOLEAN.toSymbolReference(), C_BOOLEAN_1.toSymbolReference());
    result = fromPredicate(originalPredicate);
    assertEquals(result.getTupleDomain(), TupleDomain.all());
    assertEquals(result.getRemainingExpression(), originalPredicate);
    originalPredicate = not(and(C_BOOLEAN.toSymbolReference(), C_BOOLEAN_1.toSymbolReference()));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getTupleDomain(), TupleDomain.all());
    assertEquals(result.getRemainingExpression(), originalPredicate);
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Test(org.testng.annotations.Test)

Aggregations

ExtractionResult (io.trino.sql.planner.DomainTranslator.ExtractionResult)12 Test (org.testng.annotations.Test)7 Expression (io.trino.sql.tree.Expression)6 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)4 InListExpression (io.trino.sql.tree.InListExpression)4 NotExpression (io.trino.sql.tree.NotExpression)4 Domain (io.trino.spi.predicate.Domain)3 TupleDomain (io.trino.spi.predicate.TupleDomain)3 DomainTranslator (io.trino.sql.planner.DomainTranslator)2 Symbol (io.trino.sql.planner.Symbol)2 FilterNode (io.trino.sql.planner.plan.FilterNode)2 ValuesNode (io.trino.sql.planner.plan.ValuesNode)2 Slice (io.airlift.slice.Slice)1 Slices.utf8Slice (io.airlift.slice.Slices.utf8Slice)1 Session (io.trino.Session)1 ColumnHandle (io.trino.spi.connector.ColumnHandle)1 Type (io.trino.spi.type.Type)1 ProjectNode (io.trino.sql.planner.plan.ProjectNode)1 RowNumberNode (io.trino.sql.planner.plan.RowNumberNode)1 TableScanNode (io.trino.sql.planner.plan.TableScanNode)1