Search in sources :

Example 6 with ExtractionResult

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

the class PushPredicateThroughProjectIntoRowNumber method apply.

@Override
public Result apply(FilterNode filter, Captures captures, Context context) {
    ProjectNode project = captures.get(PROJECT);
    RowNumberNode rowNumber = captures.get(ROW_NUMBER);
    Symbol rowNumberSymbol = rowNumber.getRowNumberSymbol();
    if (!project.getAssignments().getSymbols().contains(rowNumberSymbol)) {
        return Result.empty();
    }
    ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, context.getSession(), filter.getPredicate(), context.getSymbolAllocator().getTypes());
    TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
    OptionalInt upperBound = extractUpperBound(tupleDomain, rowNumberSymbol);
    if (upperBound.isEmpty()) {
        return Result.empty();
    }
    if (upperBound.getAsInt() <= 0) {
        return Result.ofPlanNode(new ValuesNode(filter.getId(), filter.getOutputSymbols(), ImmutableList.of()));
    }
    boolean updatedMaxRowCountPerPartition = false;
    if (rowNumber.getMaxRowCountPerPartition().isEmpty() || rowNumber.getMaxRowCountPerPartition().get() > upperBound.getAsInt()) {
        rowNumber = new RowNumberNode(rowNumber.getId(), rowNumber.getSource(), rowNumber.getPartitionBy(), rowNumber.isOrderSensitive(), rowNumber.getRowNumberSymbol(), Optional.of(upperBound.getAsInt()), rowNumber.getHashSymbol());
        project = (ProjectNode) project.replaceChildren(ImmutableList.of(rowNumber));
        updatedMaxRowCountPerPartition = true;
    }
    if (!allRowNumberValuesInDomain(tupleDomain, rowNumberSymbol, rowNumber.getMaxRowCountPerPartition().get())) {
        if (updatedMaxRowCountPerPartition) {
            return Result.ofPlanNode(filter.replaceChildren(ImmutableList.of(project)));
        }
        return Result.empty();
    }
    // Remove the row number domain because it is absorbed into the node
    TupleDomain<Symbol> newTupleDomain = tupleDomain.filter((symbol, domain) -> !symbol.equals(rowNumberSymbol));
    Expression newPredicate = ExpressionUtils.combineConjuncts(plannerContext.getMetadata(), extractionResult.getRemainingExpression(), new DomainTranslator(plannerContext).toPredicate(context.getSession(), newTupleDomain));
    if (newPredicate.equals(TRUE_LITERAL)) {
        return Result.ofPlanNode(project);
    }
    return Result.ofPlanNode(new FilterNode(filter.getId(), project, newPredicate));
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) FilterNode(io.trino.sql.planner.plan.FilterNode) RowNumberNode(io.trino.sql.planner.plan.RowNumberNode) DomainTranslator(io.trino.sql.planner.DomainTranslator) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) OptionalInt(java.util.OptionalInt)

Example 7 with ExtractionResult

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

the class TestDomainTranslator method testExpressionConstantFolding.

@Test
public void testExpressionConstantFolding() {
    FunctionCall fromHex = functionResolution.functionCallBuilder(QualifiedName.of("from_hex")).addArgument(VARCHAR, stringLiteral("123456")).build();
    Expression originalExpression = comparison(GREATER_THAN, C_VARBINARY.toSymbolReference(), fromHex);
    ExtractionResult result = fromPredicate(originalExpression);
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    Slice value = Slices.wrappedBuffer(BaseEncoding.base16().decode("123456"));
    assertEquals(result.getTupleDomain(), tupleDomain(C_VARBINARY, Domain.create(ValueSet.ofRanges(Range.greaterThan(VARBINARY, value)), false)));
    Expression expression = toPredicate(result.getTupleDomain());
    assertEquals(expression, comparison(GREATER_THAN, C_VARBINARY.toSymbolReference(), varbinaryLiteral(value)));
}
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) Slices.utf8Slice(io.airlift.slice.Slices.utf8Slice) Slice(io.airlift.slice.Slice) FunctionCall(io.trino.sql.tree.FunctionCall) ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Test(org.testng.annotations.Test)

Example 8 with ExtractionResult

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

the class TestDomainTranslator method testToPredicateAllIgnored.

@Test
public void testToPredicateAllIgnored() {
    TupleDomain<Symbol> tupleDomain = tupleDomain(ImmutableMap.<Symbol, Domain>builder().put(C_BIGINT, Domain.singleValue(BIGINT, 1L)).put(C_DOUBLE, Domain.onlyNull(DOUBLE)).put(C_VARCHAR, Domain.notNull(VARCHAR)).put(C_BOOLEAN, Domain.all(BOOLEAN)).buildOrThrow());
    ExtractionResult result = fromPredicate(toPredicate(tupleDomain));
    assertEquals(result.getRemainingExpression(), TRUE_LITERAL);
    assertEquals(result.getTupleDomain(), tupleDomain(ImmutableMap.<Symbol, Domain>builder().put(C_BIGINT, Domain.singleValue(BIGINT, 1L)).put(C_DOUBLE, Domain.onlyNull(DOUBLE)).put(C_VARCHAR, Domain.notNull(VARCHAR)).buildOrThrow()));
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) Test(org.testng.annotations.Test)

Example 9 with ExtractionResult

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

the class TestDomainTranslator method testSimpleComparison.

private void testSimpleComparison(Expression expression, Symbol symbol, Expression expectedRemainingExpression, Domain expectedDomain) {
    ExtractionResult result = fromPredicate(expression);
    assertEquals(result.getRemainingExpression(), expectedRemainingExpression);
    TupleDomain<Symbol> actual = result.getTupleDomain();
    TupleDomain<Symbol> expected = tupleDomain(symbol, expectedDomain);
    if (!actual.equals(expected)) {
        fail(format("for comparison [%s] expected [%s] but found [%s]", expression.toString(), expected.toString(SESSION), actual.toString(SESSION)));
    }
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult)

Example 10 with ExtractionResult

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

the class TestDomainTranslator method assertNoFullPushdown.

private void assertNoFullPushdown(Expression expression) {
    ExtractionResult result = fromPredicate(expression);
    assertNotEquals(result.getRemainingExpression(), TRUE_LITERAL);
}
Also used : ExtractionResult(io.trino.sql.planner.DomainTranslator.ExtractionResult)

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