use of com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause in project presto by prestodb.
the class TestPredicatePushdown method testPredicatePushDownCreatesValidJoin.
@Test
public void testPredicatePushDownCreatesValidJoin() {
RuleTester tester = new RuleTester();
tester.assertThat(new PredicatePushDown(tester.getMetadata(), tester.getSqlParser())).on(p -> p.join(INNER, p.filter(p.comparison(OperatorType.EQUAL, p.variable("a1"), constant(1L, INTEGER)), p.values(p.variable("a1"))), p.values(p.variable("b1")), ImmutableList.of(new EquiJoinClause(p.variable("a1"), p.variable("b1"))), ImmutableList.of(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(PARTITIONED), ImmutableMap.of())).matches(project(join(INNER, ImmutableList.of(), Optional.empty(), Optional.of(REPLICATED), project(filter("a1=1", values("a1"))), project(filter("1=b1", values("b1"))))));
}
use of com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause in project presto by prestodb.
the class JoinStatsRule method filterByEquiJoinClauses.
private PlanNodeStatsEstimate filterByEquiJoinClauses(PlanNodeStatsEstimate stats, EquiJoinClause drivingClause, Collection<EquiJoinClause> remainingClauses, Session session, TypeProvider types) {
ComparisonExpression drivingPredicate = new ComparisonExpression(EQUAL, new SymbolReference(getNodeLocation(drivingClause.getLeft().getSourceLocation()), drivingClause.getLeft().getName()), new SymbolReference(getNodeLocation(drivingClause.getRight().getSourceLocation()), drivingClause.getRight().getName()));
PlanNodeStatsEstimate filteredStats = filterStatsCalculator.filterStats(stats, drivingPredicate, session, types);
for (EquiJoinClause clause : remainingClauses) {
filteredStats = filterByAuxiliaryClause(filteredStats, clause);
}
return filteredStats;
}
use of com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause 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.sql.planner.plan.JoinNode.EquiJoinClause in project presto by prestodb.
the class JoinStatsRule method filterByEquiJoinClauses.
private PlanNodeStatsEstimate filterByEquiJoinClauses(PlanNodeStatsEstimate stats, Collection<EquiJoinClause> clauses, Session session, TypeProvider types) {
checkArgument(!clauses.isEmpty(), "clauses is empty");
PlanNodeStatsEstimate result = PlanNodeStatsEstimate.unknown();
// Join equality clauses are usually correlated. Therefore we shouldn't treat each join equality
// clause separately because stats estimates would be way off. Instead we choose so called
// "driving clause" which mostly reduces join output rows cardinality and apply UNKNOWN_FILTER_COEFFICIENT
// for other (auxiliary) clauses.
Queue<EquiJoinClause> remainingClauses = new LinkedList<>(clauses);
EquiJoinClause drivingClause = remainingClauses.poll();
for (int i = 0; i < clauses.size(); i++) {
PlanNodeStatsEstimate estimate = filterByEquiJoinClauses(stats, drivingClause, remainingClauses, session, types);
if (result.isOutputRowCountUnknown() || (!estimate.isOutputRowCountUnknown() && estimate.getOutputRowCount() < result.getOutputRowCount())) {
result = estimate;
}
remainingClauses.add(drivingClause);
drivingClause = remainingClauses.poll();
}
return result;
}
use of com.facebook.presto.sql.planner.plan.JoinNode.EquiJoinClause in project presto by prestodb.
the class TestReorderJoins method testReplicatedScalarJoinEvenWhereSessionRequiresRepartitioned.
@Test
public void testReplicatedScalarJoinEvenWhereSessionRequiresRepartitioned() {
PlanMatchPattern expectedPlan = join(INNER, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0)));
PlanNodeStatsEstimate valuesA = PlanNodeStatsEstimate.builder().setOutputRowCount(10000).addVariableStatistics(ImmutableMap.of(variable("A1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build();
PlanNodeStatsEstimate valuesB = PlanNodeStatsEstimate.builder().setOutputRowCount(10000).addVariableStatistics(ImmutableMap.of(variable("B1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build();
assertReorderJoins().setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.PARTITIONED.name()).on(p -> p.join(INNER, // matches isAtMostScalar
p.values(new PlanNodeId("valuesA"), p.variable("A1")), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.variable("B1")), TWO_ROWS), ImmutableList.of(new EquiJoinClause(p.variable("A1"), p.variable("B1"))), ImmutableList.of(p.variable("A1"), p.variable("B1")), Optional.empty())).overrideStats("valuesA", valuesA).overrideStats("valuesB", valuesB).matches(expectedPlan);
assertReorderJoins().setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.PARTITIONED.name()).on(p -> p.join(INNER, p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.variable("B1")), TWO_ROWS), // matches isAtMostScalar
p.values(new PlanNodeId("valuesA"), p.variable("A1")), ImmutableList.of(new EquiJoinClause(p.variable("A1"), p.variable("B1"))), ImmutableList.of(p.variable("A1"), p.variable("B1")), Optional.empty())).overrideStats("valuesA", valuesA).overrideStats("valuesB", valuesB).matches(expectedPlan);
}
Aggregations