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));
}
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);
}
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();
}
Aggregations