Search in sources :

Example 11 with ExtractionResult

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

the class TestDomainTranslator method assertPredicateTranslates.

private void assertPredicateTranslates(Expression expression, TupleDomain<Symbol> tupleDomain, Expression remainingExpression) {
    ExtractionResult result = fromPredicate(expression);
    assertEquals(result.getTupleDomain(), tupleDomain);
    assertEquals(result.getRemainingExpression(), remainingExpression);
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult)

Example 12 with ExtractionResult

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

the class TestDomainTranslator method testFromOrPredicate.

@Test
public void testFromOrPredicate() {
    Expression originalPredicate = or(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(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.notNull(BIGINT)));
    originalPredicate = or(and(equal(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(equal(C_BIGINT, bigintLiteral(2L)), unprocessableExpression2(C_BIGINT)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.ofRanges(Range.equal(BIGINT, 1L), Range.equal(BIGINT, 2L)), false)));
    originalPredicate = or(and(lessThan(C_BIGINT, bigintLiteral(20L)), unprocessableExpression1(C_BIGINT)), and(greaterThan(C_BIGINT, bigintLiteral(10L)), unprocessableExpression2(C_BIGINT)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.all(BIGINT), false)));
    // Same unprocessableExpression means that we can do more extraction
    // If both sides are operating on the same single symbol
    originalPredicate = or(and(equal(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(equal(C_BIGINT, bigintLiteral(2L)), unprocessableExpression1(C_BIGINT)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), unprocessableExpression1(C_BIGINT));
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.ofRanges(Range.equal(BIGINT, 1L), Range.equal(BIGINT, 2L)), false)));
    // And not if they have different symbols
    assertUnsupportedPredicate(or(and(equal(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(equal(C_DOUBLE, doubleLiteral(2.0)), unprocessableExpression1(C_BIGINT))));
    // Domain union implicitly adds NaN as an accepted value
    // The original predicate is returned as the RemainingExpression
    // (even if left and right unprocessableExpressions are the same)
    originalPredicate = or(greaterThan(C_DOUBLE, doubleLiteral(2.0)), lessThan(C_DOUBLE, doubleLiteral(5.0)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_DOUBLE, Domain.notNull(DOUBLE)));
    originalPredicate = or(greaterThan(C_REAL, realLiteral("2.0")), lessThan(C_REAL, realLiteral("5.0")), isNull(C_REAL));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), TupleDomain.all());
    originalPredicate = or(and(greaterThan(C_DOUBLE, doubleLiteral(2.0)), unprocessableExpression1(C_DOUBLE)), and(lessThan(C_DOUBLE, doubleLiteral(5.0)), unprocessableExpression1(C_DOUBLE)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_DOUBLE, Domain.notNull(DOUBLE)));
    originalPredicate = or(and(greaterThan(C_REAL, realLiteral("2.0")), unprocessableExpression1(C_REAL)), and(lessThan(C_REAL, realLiteral("5.0")), unprocessableExpression1(C_REAL)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_REAL, Domain.notNull(REAL)));
    // We can make another optimization if one side is the super set of the other side
    originalPredicate = or(and(greaterThan(C_BIGINT, bigintLiteral(1L)), greaterThan(C_DOUBLE, doubleLiteral(1.0)), unprocessableExpression1(C_BIGINT)), and(greaterThan(C_BIGINT, bigintLiteral(2L)), greaterThan(C_DOUBLE, doubleLiteral(2.0)), unprocessableExpression1(C_BIGINT)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), unprocessableExpression1(C_BIGINT));
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.ofRanges(Range.greaterThan(BIGINT, 1L)), false), C_DOUBLE, Domain.create(ValueSet.ofRanges(Range.greaterThan(DOUBLE, 1.0)), false)));
    // We can't make those inferences if the unprocessableExpressions are non-deterministic
    originalPredicate = or(and(equal(C_BIGINT, bigintLiteral(1L)), randPredicate(C_BIGINT, BIGINT)), and(equal(C_BIGINT, bigintLiteral(2L)), randPredicate(C_BIGINT, BIGINT)));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), originalPredicate);
    assertEquals(result.getTupleDomain(), tupleDomain(C_BIGINT, Domain.create(ValueSet.ofRanges(Range.equal(BIGINT, 1L), Range.equal(BIGINT, 2L)), false)));
    // Test complements
    originalPredicate = not(or(and(greaterThan(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT)), and(lessThan(C_BIGINT, bigintLiteral(5L)), unprocessableExpression2(C_BIGINT))));
    result = fromPredicate(originalPredicate);
    assertEquals(result.getRemainingExpression(), and(not(and(greaterThan(C_BIGINT, bigintLiteral(1L)), unprocessableExpression1(C_BIGINT))), not(and(lessThan(C_BIGINT, bigintLiteral(5L)), unprocessableExpression2(C_BIGINT)))));
    assertTrue(result.getTupleDomain().isAll());
    originalPredicate = not(or(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(), 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)));
}
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)

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