Search in sources :

Example 1 with UNKNOWN_FILTER_COEFFICIENT

use of com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT in project presto by prestodb.

the class TestJoinStatsRule method testStatsForInnerJoinWithTwoEquiClausesAndNonEqualityFunction.

@Test
public void testStatsForInnerJoinWithTwoEquiClausesAndNonEqualityFunction() {
    double innerJoinRowCount = // driver join clause
    LEFT_ROWS_COUNT * RIGHT_ROWS_COUNT / LEFT_JOIN_COLUMN_2_NDV * LEFT_JOIN_COLUMN_2_NON_NULLS * RIGHT_JOIN_COLUMN_2_NON_NULLS * // auxiliary join clause
    UNKNOWN_FILTER_COEFFICIENT * // LEFT_JOIN_COLUMN < 10 non equality filter
    0.3333333333;
    PlanNodeStatsEstimate innerJoinStats = planNodeStats(innerJoinRowCount, variableStatistics(LEFT_JOIN_COLUMN, 5.0, 10.0, 0.0, RIGHT_JOIN_COLUMN_NDV * 0.3333333333), variableStatistics(RIGHT_JOIN_COLUMN, 5.0, 20.0, 0.0, RIGHT_JOIN_COLUMN_NDV), variableStatistics(LEFT_JOIN_COLUMN_2, 100.0, 200.0, 0.0, RIGHT_JOIN_COLUMN_2_NDV), variableStatistics(RIGHT_JOIN_COLUMN_2, 100.0, 200.0, 0.0, RIGHT_JOIN_COLUMN_2_NDV));
    tester().assertStatsFor(pb -> {
        VariableReferenceExpression leftJoinColumn = pb.variable(LEFT_JOIN_COLUMN);
        VariableReferenceExpression rightJoinColumn = pb.variable(RIGHT_JOIN_COLUMN);
        VariableReferenceExpression leftJoinColumn2 = pb.variable(LEFT_JOIN_COLUMN_2);
        VariableReferenceExpression rightJoinColumn2 = pb.variable(RIGHT_JOIN_COLUMN_2);
        ComparisonExpression leftJoinColumnLessThanTen = new ComparisonExpression(ComparisonExpression.Operator.LESS_THAN, new SymbolReference(leftJoinColumn.getName()), new LongLiteral("10"));
        return pb.join(INNER, pb.values(leftJoinColumn, leftJoinColumn2), pb.values(rightJoinColumn, rightJoinColumn2), ImmutableList.of(new EquiJoinClause(leftJoinColumn2, rightJoinColumn2), new EquiJoinClause(leftJoinColumn, rightJoinColumn)), ImmutableList.of(leftJoinColumn, leftJoinColumn2, rightJoinColumn, rightJoinColumn2), Optional.of(castToRowExpression(leftJoinColumnLessThanTen)));
    }).withSourceStats(0, planNodeStats(LEFT_ROWS_COUNT, LEFT_JOIN_COLUMN_STATS, LEFT_JOIN_COLUMN_2_STATS)).withSourceStats(1, planNodeStats(RIGHT_ROWS_COUNT, RIGHT_JOIN_COLUMN_STATS, RIGHT_JOIN_COLUMN_2_STATS)).check(stats -> stats.equalTo(innerJoinStats));
}
Also used : EquiJoinClause(com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause) PlanNodeStatsAssertion.assertThat(com.facebook.presto.cost.PlanNodeStatsAssertion.assertThat) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) MetadataManager(com.facebook.presto.metadata.MetadataManager) DOUBLE(com.facebook.presto.common.type.DoubleType.DOUBLE) UNKNOWN_FILTER_COEFFICIENT(com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) Assert.assertEquals(org.testng.Assert.assertEquals) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) FULL(com.facebook.presto.sql.planner.plan.JoinNode.Type.FULL) RIGHT(com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT) ImmutableList(com.google.common.collect.ImmutableList) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) NaN(java.lang.Double.NaN) MetadataManager.createTestMetadataManager(com.facebook.presto.metadata.MetadataManager.createTestMetadataManager) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) Optional(java.util.Optional) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) EquiJoinClause(com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause) Test(org.testng.annotations.Test)

Example 2 with UNKNOWN_FILTER_COEFFICIENT

use of com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT in project presto by prestodb.

the class SimpleFilterProjectSemiJoinStatsRule method calculate.

private Optional<PlanNodeStatsEstimate> calculate(FilterNode filterNode, SemiJoinNode semiJoinNode, StatsProvider statsProvider, Session session, TypeProvider types) {
    PlanNodeStatsEstimate sourceStats = statsProvider.getStats(semiJoinNode.getSource());
    PlanNodeStatsEstimate filteringSourceStats = statsProvider.getStats(semiJoinNode.getFilteringSource());
    VariableReferenceExpression filteringSourceJoinVariable = semiJoinNode.getFilteringSourceJoinVariable();
    VariableReferenceExpression sourceJoinVariable = semiJoinNode.getSourceJoinVariable();
    Optional<SemiJoinOutputFilter> semiJoinOutputFilter;
    VariableReferenceExpression semiJoinOutput = semiJoinNode.getSemiJoinOutput();
    if (isExpression(filterNode.getPredicate())) {
        semiJoinOutputFilter = extractSemiJoinOutputFilter(castToExpression(filterNode.getPredicate()), semiJoinOutput);
    } else {
        semiJoinOutputFilter = extractSemiJoinOutputFilter(filterNode.getPredicate(), semiJoinOutput);
    }
    if (!semiJoinOutputFilter.isPresent()) {
        return Optional.empty();
    }
    PlanNodeStatsEstimate semiJoinStats;
    if (semiJoinOutputFilter.get().isNegated()) {
        semiJoinStats = computeAntiJoin(sourceStats, filteringSourceStats, sourceJoinVariable, filteringSourceJoinVariable);
    } else {
        semiJoinStats = computeSemiJoin(sourceStats, filteringSourceStats, sourceJoinVariable, filteringSourceJoinVariable);
    }
    if (semiJoinStats.isOutputRowCountUnknown()) {
        return Optional.of(PlanNodeStatsEstimate.unknown());
    }
    // apply remaining predicate
    PlanNodeStatsEstimate filteredStats;
    if (isExpression(filterNode.getPredicate())) {
        filteredStats = filterStatsCalculator.filterStats(semiJoinStats, castToExpression(semiJoinOutputFilter.get().getRemainingPredicate()), session, types);
    } else {
        filteredStats = filterStatsCalculator.filterStats(semiJoinStats, semiJoinOutputFilter.get().getRemainingPredicate(), session);
    }
    if (filteredStats.isOutputRowCountUnknown()) {
        return Optional.of(semiJoinStats.mapOutputRowCount(rowCount -> rowCount * UNKNOWN_FILTER_COEFFICIENT));
    }
    return Optional.of(filteredStats);
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) Iterables(com.google.common.collect.Iterables) ExpressionUtils.extractConjuncts(com.facebook.presto.sql.ExpressionUtils.extractConjuncts) OriginalExpressionUtils.isExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.isExpression) ExpressionUtils.combineConjuncts(com.facebook.presto.sql.ExpressionUtils.combineConjuncts) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpressionDeterminismEvaluator(com.facebook.presto.sql.relational.RowExpressionDeterminismEvaluator) Patterns.filter(com.facebook.presto.sql.planner.plan.Patterns.filter) Pattern(com.facebook.presto.matching.Pattern) FilterNode(com.facebook.presto.spi.plan.FilterNode) OriginalExpressionUtils.castToExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToExpression) LogicalRowExpressions(com.facebook.presto.expressions.LogicalRowExpressions) TypeProvider(com.facebook.presto.sql.planner.TypeProvider) Objects.requireNonNull(java.util.Objects.requireNonNull) FunctionResolution(com.facebook.presto.sql.relational.FunctionResolution) CallExpression(com.facebook.presto.spi.relation.CallExpression) SemiJoinStatsCalculator.computeAntiJoin(com.facebook.presto.cost.SemiJoinStatsCalculator.computeAntiJoin) ProjectNodeUtils.isIdentity(com.facebook.presto.sql.relational.ProjectNodeUtils.isIdentity) NotExpression(com.facebook.presto.sql.tree.NotExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) Session(com.facebook.presto.Session) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) UNKNOWN_FILTER_COEFFICIENT(com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) Lookup(com.facebook.presto.sql.planner.iterative.Lookup) Preconditions.checkState(com.google.common.base.Preconditions.checkState) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) Expression(com.facebook.presto.sql.tree.Expression) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) SemiJoinStatsCalculator.computeSemiJoin(com.facebook.presto.cost.SemiJoinStatsCalculator.computeSemiJoin) SemiJoinNode(com.facebook.presto.sql.planner.plan.SemiJoinNode) Optional(java.util.Optional) ExpressionTreeUtils.createSymbolReference(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.createSymbolReference) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression)

Example 3 with UNKNOWN_FILTER_COEFFICIENT

use of com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT in project presto by prestodb.

the class ConnectorFilterStatsCalculatorService method filterStats.

@Override
public TableStatistics filterStats(TableStatistics tableStatistics, RowExpression predicate, ConnectorSession session, Map<ColumnHandle, String> columnNames, Map<String, Type> columnTypes) {
    PlanNodeStatsEstimate tableStats = toPlanNodeStats(tableStatistics, columnNames, columnTypes);
    PlanNodeStatsEstimate filteredStats = filterStatsCalculator.filterStats(tableStats, predicate, session);
    if (filteredStats.isOutputRowCountUnknown()) {
        filteredStats = tableStats.mapOutputRowCount(sourceRowCount -> tableStats.getOutputRowCount() * UNKNOWN_FILTER_COEFFICIENT);
    }
    TableStatistics filteredStatistics = toTableStatistics(filteredStats, ImmutableBiMap.copyOf(columnNames).inverse());
    // Fill in the totalSize after filter, estimated proportional to the rowCount after versus before filter.
    TableStatistics.Builder filteredStatsWithSize = TableStatistics.builder();
    filteredStatsWithSize.setRowCount(filteredStatistics.getRowCount());
    filteredStatistics.getColumnStatistics().forEach(filteredStatsWithSize::setColumnStatistics);
    // If the rowCount before or after filter is zero, totalSize will also be zero
    if (!tableStatistics.getRowCount().isUnknown() && tableStatistics.getRowCount().getValue() == 0 || !filteredStatistics.getRowCount().isUnknown() && filteredStatistics.getRowCount().getValue() == 0) {
        filteredStatsWithSize.setTotalSize(Estimate.of(0));
    } else if (!tableStatistics.getTotalSize().isUnknown() && !filteredStatistics.getRowCount().isUnknown() && !tableStatistics.getRowCount().isUnknown()) {
        double totalSizeAfterFilter = filteredStatistics.getRowCount().getValue() / tableStatistics.getRowCount().getValue() * tableStatistics.getTotalSize().getValue();
        filteredStatsWithSize.setTotalSize(Estimate.of(totalSizeAfterFilter));
    }
    return filteredStatsWithSize.build();
}
Also used : FilterStatsCalculatorService(com.facebook.presto.spi.plan.FilterStatsCalculatorService) RowExpression(com.facebook.presto.spi.relation.RowExpression) ColumnStatistics(com.facebook.presto.spi.statistics.ColumnStatistics) TableStatistics(com.facebook.presto.spi.statistics.TableStatistics) UNKNOWN_FILTER_COEFFICIENT(com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ConnectorSession(com.facebook.presto.spi.ConnectorSession) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) DoubleRange(com.facebook.presto.spi.statistics.DoubleRange) ColumnHandle(com.facebook.presto.spi.ColumnHandle) Estimate(com.facebook.presto.spi.statistics.Estimate) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) StatsUtil.toVariableStatsEstimate(com.facebook.presto.cost.StatsUtil.toVariableStatsEstimate) Builder(com.facebook.presto.spi.statistics.ColumnStatistics.Builder) Optional(java.util.Optional) Type(com.facebook.presto.common.type.Type) TableStatistics(com.facebook.presto.spi.statistics.TableStatistics)

Aggregations

UNKNOWN_FILTER_COEFFICIENT (com.facebook.presto.cost.FilterStatsCalculator.UNKNOWN_FILTER_COEFFICIENT)3 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)3 Optional (java.util.Optional)3 RowExpression (com.facebook.presto.spi.relation.RowExpression)2 OriginalExpressionUtils.castToRowExpression (com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression)2 SymbolReference (com.facebook.presto.sql.tree.SymbolReference)2 Objects.requireNonNull (java.util.Objects.requireNonNull)2 Session (com.facebook.presto.Session)1 BIGINT (com.facebook.presto.common.type.BigintType.BIGINT)1 DOUBLE (com.facebook.presto.common.type.DoubleType.DOUBLE)1 Type (com.facebook.presto.common.type.Type)1 PlanNodeStatsAssertion.assertThat (com.facebook.presto.cost.PlanNodeStatsAssertion.assertThat)1 SemiJoinStatsCalculator.computeAntiJoin (com.facebook.presto.cost.SemiJoinStatsCalculator.computeAntiJoin)1 SemiJoinStatsCalculator.computeSemiJoin (com.facebook.presto.cost.SemiJoinStatsCalculator.computeSemiJoin)1 StatsUtil.toVariableStatsEstimate (com.facebook.presto.cost.StatsUtil.toVariableStatsEstimate)1 LogicalRowExpressions (com.facebook.presto.expressions.LogicalRowExpressions)1 Pattern (com.facebook.presto.matching.Pattern)1 FunctionAndTypeManager (com.facebook.presto.metadata.FunctionAndTypeManager)1 MetadataManager (com.facebook.presto.metadata.MetadataManager)1 MetadataManager.createTestMetadataManager (com.facebook.presto.metadata.MetadataManager.createTestMetadataManager)1