Search in sources :

Example 1 with LEFT

use of com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT in project presto by prestodb.

the class TestLogicalPlanner method testBroadcastCorrelatedSubqueryAvoidsRemoteExchangeBeforeAggregation.

@Test
public void testBroadcastCorrelatedSubqueryAvoidsRemoteExchangeBeforeAggregation() {
    Session broadcastJoin = Session.builder(this.getQueryRunner().getDefaultSession()).setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.BROADCAST.name()).setSystemProperty(FORCE_SINGLE_NODE_OUTPUT, Boolean.toString(false)).build();
    // make sure there is a remote exchange on the build side
    PlanMatchPattern joinBuildSideWithRemoteExchange = anyTree(node(JoinNode.class, anyTree(node(TableScanNode.class)), anyTree(exchange(REMOTE_STREAMING, ExchangeNode.Type.REPLICATE, anyTree(node(TableScanNode.class))))));
    // validates that there exists only one remote exchange
    Consumer<Plan> validateSingleRemoteExchange = plan -> assertEquals(countOfMatchingNodes(plan, node -> node instanceof ExchangeNode && ((ExchangeNode) node).getScope().isRemote()), 1);
    Consumer<Plan> validateSingleStreamingAggregation = plan -> assertEquals(countOfMatchingNodes(plan, node -> node instanceof AggregationNode && ((AggregationNode) node).getGroupingKeys().contains(new VariableReferenceExpression(Optional.empty(), "unique", BIGINT)) && ((AggregationNode) node).isStreamable()), 1);
    // region is unpartitioned, AssignUniqueId should provide satisfying partitioning for count(*) after LEFT JOIN
    assertPlanWithSession("SELECT (SELECT COUNT(*) FROM region r2 WHERE r2.regionkey > r1.regionkey) FROM region r1", broadcastJoin, false, joinBuildSideWithRemoteExchange, validateSingleRemoteExchange.andThen(validateSingleStreamingAggregation));
    // orders is naturally partitioned, AssignUniqueId should not overwrite its natural partitioning
    assertPlanWithSession("SELECT COUNT(COUNT) " + "FROM (SELECT o1.orderkey orderkey, (SELECT COUNT(*) FROM orders o2 WHERE o2.orderkey > o1.orderkey) COUNT FROM orders o1) " + "GROUP BY orderkey", broadcastJoin, false, joinBuildSideWithRemoteExchange, validateSingleRemoteExchange.andThen(validateSingleStreamingAggregation));
}
Also used : FORCE_SINGLE_NODE_OUTPUT(com.facebook.presto.SystemSessionProperties.FORCE_SINGLE_NODE_OUTPUT) PlanMatchPattern.filter(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.filter) PlanMatchPattern.anyTree(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.anyTree) REPLICATE(com.facebook.presto.sql.planner.plan.ExchangeNode.Type.REPLICATE) PlanMatchPattern.anyNot(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.anyNot) Test(org.testng.annotations.Test) DESCENDING(com.facebook.presto.sql.tree.SortItem.Ordering.DESCENDING) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) PlanMatchPattern(com.facebook.presto.sql.planner.assertions.PlanMatchPattern) PlanMatchPattern.join(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join) ASC_NULLS_LAST(com.facebook.presto.common.block.SortOrder.ASC_NULLS_LAST) IndexJoinNode(com.facebook.presto.sql.planner.plan.IndexJoinNode) PlanMatchPattern.expression(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.expression) Slices.utf8Slice(io.airlift.slice.Slices.utf8Slice) Assert.assertFalse(org.testng.Assert.assertFalse) PARTIAL(com.facebook.presto.spi.plan.AggregationNode.Step.PARTIAL) LateralJoinNode(com.facebook.presto.sql.planner.plan.LateralJoinNode) SUBQUERY_MULTIPLE_ROWS(com.facebook.presto.spi.StandardErrorCode.SUBQUERY_MULTIPLE_ROWS) PlanMatchPattern.semiJoin(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.semiJoin) LAST(com.facebook.presto.sql.tree.SortItem.NullOrdering.LAST) PlanMatchPattern.apply(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.apply) PlanMatchPattern.rowNumber(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.rowNumber) JOIN_DISTRIBUTION_TYPE(com.facebook.presto.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE) TASK_CONCURRENCY(com.facebook.presto.SystemSessionProperties.TASK_CONCURRENCY) REPLICATED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.REPLICATED) OPTIMIZE_NULLS_IN_JOINS(com.facebook.presto.SystemSessionProperties.OPTIMIZE_NULLS_IN_JOINS) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) ApplyNode(com.facebook.presto.sql.planner.plan.ApplyNode) PlanMatchPattern.strictProject(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.strictProject) PlanMatchPattern.node(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.node) PlanMatchPattern.specification(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.specification) PlanOptimizer(com.facebook.presto.sql.planner.optimizations.PlanOptimizer) GATHER(com.facebook.presto.sql.planner.plan.ExchangeNode.Type.GATHER) OFFSET_CLAUSE_ENABLED(com.facebook.presto.SystemSessionProperties.OFFSET_CLAUSE_ENABLED) DistinctLimitNode(com.facebook.presto.spi.plan.DistinctLimitNode) AddLocalExchanges(com.facebook.presto.sql.planner.optimizations.AddLocalExchanges) ASCENDING(com.facebook.presto.sql.tree.SortItem.Ordering.ASCENDING) PlanMatchPattern.functionCall(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.functionCall) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) Session(com.facebook.presto.Session) ELIMINATE_CROSS_JOINS(com.facebook.presto.sql.analyzer.FeaturesConfig.JoinReorderingStrategy.ELIMINATE_CROSS_JOINS) PlanMatchPattern.exchange(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.exchange) RIGHT(com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT) OPTIMIZE_JOINS_WITH_EMPTY_SOURCES(com.facebook.presto.SystemSessionProperties.OPTIMIZE_JOINS_WITH_EMPTY_SOURCES) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) SemiJoinNode(com.facebook.presto.sql.planner.plan.SemiJoinNode) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) QueryTemplate.queryTemplate(com.facebook.presto.tests.QueryTemplate.queryTemplate) BasePlanTest(com.facebook.presto.sql.planner.assertions.BasePlanTest) PlanMatchPattern.output(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.output) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) MorePredicates.isInstanceOfAny(com.facebook.presto.util.MorePredicates.isInstanceOfAny) PlanMatchPattern.window(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.window) JoinDistributionType(com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType) PlanMatchPattern.aggregation(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.aggregation) PlanMatchPattern.sort(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.sort) OPTIMIZE_HASH_GENERATION(com.facebook.presto.SystemSessionProperties.OPTIMIZE_HASH_GENERATION) PlanMatchPattern.project(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.project) ImmutableMap(com.google.common.collect.ImmutableMap) PlanMatchPattern.topN(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.topN) Predicate(java.util.function.Predicate) Domain.singleValue(com.facebook.presto.common.predicate.Domain.singleValue) PlanMatchPattern.constrainedTableScan(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.constrainedTableScan) String.format(java.lang.String.format) REMOTE_STREAMING(com.facebook.presto.sql.planner.plan.ExchangeNode.Scope.REMOTE_STREAMING) List(java.util.List) RowNumberSymbolMatcher(com.facebook.presto.sql.planner.assertions.RowNumberSymbolMatcher) ExpressionMatcher(com.facebook.presto.sql.planner.assertions.ExpressionMatcher) MorePredicates(com.facebook.presto.util.MorePredicates) JOIN_REORDERING_STRATEGY(com.facebook.presto.SystemSessionProperties.JOIN_REORDERING_STRATEGY) PlanMatchPattern.markDistinct(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.markDistinct) Optional(java.util.Optional) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) PlanMatchPattern.assignUniqueId(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.assignUniqueId) Assert.assertEquals(org.testng.Assert.assertEquals) SINGLE(com.facebook.presto.spi.plan.AggregationNode.Step.SINGLE) VarcharType.createVarcharType(com.facebook.presto.common.type.VarcharType.createVarcharType) DISTRIBUTED_SORT(com.facebook.presto.SystemSessionProperties.DISTRIBUTED_SORT) ENFORCE_FIXED_DISTRIBUTION_FOR_OUTPUT_OPERATOR(com.facebook.presto.SystemSessionProperties.ENFORCE_FIXED_DISTRIBUTION_FOR_OUTPUT_OPERATOR) PlanMatchPattern.singleGroupingSet(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.singleGroupingSet) FilterNode(com.facebook.presto.spi.plan.FilterNode) QueryTemplate(com.facebook.presto.tests.QueryTemplate) ImmutableList(com.google.common.collect.ImmutableList) LOCAL(com.facebook.presto.sql.planner.plan.ExchangeNode.Scope.LOCAL) REPARTITION(com.facebook.presto.sql.planner.plan.ExchangeNode.Type.REPARTITION) PlanMatchPattern.equiJoinClause(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause) FINAL(com.facebook.presto.spi.plan.AggregationNode.Step.FINAL) PlanMatchPattern.topNRowNumber(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.topNRowNumber) PlanMatchPattern.any(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.any) PlanMatchPattern.strictTableScan(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.strictTableScan) PlanNodeSearcher.searchFrom(com.facebook.presto.sql.planner.optimizations.PlanNodeSearcher.searchFrom) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) PlanMatchPattern.constrainedTableScanWithTableLayout(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.constrainedTableScanWithTableLayout) PlanMatchPattern.limit(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.limit) PlanMatchPattern.tableScan(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.tableScan) Consumer(java.util.function.Consumer) PlanNode(com.facebook.presto.spi.plan.PlanNode) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) PARTITIONED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.PARTITIONED) EnforceSingleRowNode(com.facebook.presto.sql.planner.plan.EnforceSingleRowNode) ExchangeNode(com.facebook.presto.sql.planner.plan.ExchangeNode) StatisticsWriterNode(com.facebook.presto.sql.planner.plan.StatisticsWriterNode) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) ExchangeNode(com.facebook.presto.sql.planner.plan.ExchangeNode) IndexJoinNode(com.facebook.presto.sql.planner.plan.IndexJoinNode) LateralJoinNode(com.facebook.presto.sql.planner.plan.LateralJoinNode) SemiJoinNode(com.facebook.presto.sql.planner.plan.SemiJoinNode) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) PlanMatchPattern(com.facebook.presto.sql.planner.assertions.PlanMatchPattern) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) Session(com.facebook.presto.Session) Test(org.testng.annotations.Test) BasePlanTest(com.facebook.presto.sql.planner.assertions.BasePlanTest)

Example 2 with LEFT

use of com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT in project presto by prestodb.

the class TestDetermineJoinDistributionType method testChoosesLeftWhenCriteriaEmpty.

@Test
public void testChoosesLeftWhenCriteriaEmpty() {
    int aRows = 1_000__00;
    int bRows = 1_0;
    assertDetermineJoinDistributionType(new CostComparator(75, 10, 15)).setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).setSystemProperty(JOIN_MAX_BROADCAST_TABLE_SIZE, "1PB").overrideStats("valuesA", PlanNodeStatsEstimate.builder().setOutputRowCount(aRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "A1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build()).overrideStats("valuesB", PlanNodeStatsEstimate.builder().setOutputRowCount(bRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "B1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build()).on(p -> p.join(RIGHT, p.values(new PlanNodeId("valuesA"), aRows, p.variable("A1", BIGINT)), p.values(new PlanNodeId("valuesB"), bRows, p.variable("B1", BIGINT)), ImmutableList.of(), ImmutableList.of(p.variable("A1", BIGINT), p.variable("B1", BIGINT)), Optional.empty())).matches(join(LEFT, ImmutableList.of(), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("B1", 0)), values(ImmutableMap.of("A1", 0))));
}
Also used : CostComparator(com.facebook.presto.cost.CostComparator) Type(com.facebook.presto.sql.planner.plan.JoinNode.Type) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) PlanBuilder.castToRowExpression(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) FULL(com.facebook.presto.sql.planner.plan.JoinNode.Type.FULL) PlanMatchPattern.join(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join) JoinDistributionType(com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType) ImmutableList(com.google.common.collect.ImmutableList) JOIN_MAX_BROADCAST_TABLE_SIZE(com.facebook.presto.SystemSessionProperties.JOIN_MAX_BROADCAST_TABLE_SIZE) PlanMatchPattern.equiJoinClause(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause) PlanMatchPattern.enforceSingleRow(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.enforceSingleRow) RuleAssert(com.facebook.presto.sql.planner.iterative.rule.test.RuleAssert) TaskCountEstimator(com.facebook.presto.cost.TaskCountEstimator) DistributionType(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) AfterClass(org.testng.annotations.AfterClass) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PlanNodeStatsEstimate(com.facebook.presto.cost.PlanNodeStatsEstimate) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) JOIN_DISTRIBUTION_TYPE(com.facebook.presto.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE) RIGHT(com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT) PlanBuilder.constantExpressions(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.constantExpressions) REPLICATED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.REPLICATED) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) CostComparator(com.facebook.presto.cost.CostComparator) Optional(java.util.Optional) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) PARTITIONED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.PARTITIONED) VariableStatsEstimate(com.facebook.presto.cost.VariableStatsEstimate) RuleTester(com.facebook.presto.sql.planner.iterative.rule.test.RuleTester) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) VariableStatsEstimate(com.facebook.presto.cost.VariableStatsEstimate) Test(org.testng.annotations.Test)

Example 3 with LEFT

use of com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT in project presto by prestodb.

the class TestDetermineJoinDistributionType method testFlipAndReplicateRightOuterJoinWhenJoinCardinalityUnknown.

@Test
public void testFlipAndReplicateRightOuterJoinWhenJoinCardinalityUnknown() {
    int aRows = 10;
    int bRows = 1_000_000;
    assertDetermineJoinDistributionType(new CostComparator(75, 10, 15)).setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).overrideStats("valuesA", PlanNodeStatsEstimate.builder().setOutputRowCount(aRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "A1", BIGINT), VariableStatsEstimate.unknown())).build()).overrideStats("valuesB", PlanNodeStatsEstimate.builder().setOutputRowCount(bRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "B1", BIGINT), VariableStatsEstimate.unknown())).build()).on(p -> p.join(RIGHT, p.values(new PlanNodeId("valuesA"), aRows, p.variable("A1", BIGINT)), p.values(new PlanNodeId("valuesB"), bRows, p.variable("B1", BIGINT)), ImmutableList.of(new JoinNode.EquiJoinClause(p.variable("A1", BIGINT), p.variable("B1", BIGINT))), ImmutableList.of(p.variable("A1", BIGINT), p.variable("B1", BIGINT)), Optional.empty())).matches(join(LEFT, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0))));
}
Also used : CostComparator(com.facebook.presto.cost.CostComparator) Type(com.facebook.presto.sql.planner.plan.JoinNode.Type) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) PlanBuilder.castToRowExpression(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) FULL(com.facebook.presto.sql.planner.plan.JoinNode.Type.FULL) PlanMatchPattern.join(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join) JoinDistributionType(com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType) ImmutableList(com.google.common.collect.ImmutableList) JOIN_MAX_BROADCAST_TABLE_SIZE(com.facebook.presto.SystemSessionProperties.JOIN_MAX_BROADCAST_TABLE_SIZE) PlanMatchPattern.equiJoinClause(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause) PlanMatchPattern.enforceSingleRow(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.enforceSingleRow) RuleAssert(com.facebook.presto.sql.planner.iterative.rule.test.RuleAssert) TaskCountEstimator(com.facebook.presto.cost.TaskCountEstimator) DistributionType(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) AfterClass(org.testng.annotations.AfterClass) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PlanNodeStatsEstimate(com.facebook.presto.cost.PlanNodeStatsEstimate) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) JOIN_DISTRIBUTION_TYPE(com.facebook.presto.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE) RIGHT(com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT) PlanBuilder.constantExpressions(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.constantExpressions) REPLICATED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.REPLICATED) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) CostComparator(com.facebook.presto.cost.CostComparator) Optional(java.util.Optional) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) PARTITIONED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.PARTITIONED) VariableStatsEstimate(com.facebook.presto.cost.VariableStatsEstimate) RuleTester(com.facebook.presto.sql.planner.iterative.rule.test.RuleTester) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test)

Example 4 with LEFT

use of com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT in project presto by prestodb.

the class TestDetermineJoinDistributionType method testReplicateLeftOuterJoin.

@Test
public void testReplicateLeftOuterJoin() {
    int aRows = 10_000;
    int bRows = 10;
    assertDetermineJoinDistributionType(new CostComparator(75, 10, 15)).setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).overrideStats("valuesA", PlanNodeStatsEstimate.builder().setOutputRowCount(aRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "A1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build()).overrideStats("valuesB", PlanNodeStatsEstimate.builder().setOutputRowCount(bRows).addVariableStatistics(ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "B1", BIGINT), new VariableStatsEstimate(0, 100, 0, 640000, 100))).build()).on(p -> p.join(LEFT, p.values(new PlanNodeId("valuesA"), aRows, p.variable("A1", BIGINT)), p.values(new PlanNodeId("valuesB"), bRows, p.variable("B1", BIGINT)), ImmutableList.of(new JoinNode.EquiJoinClause(p.variable("A1", BIGINT), p.variable("B1", BIGINT))), ImmutableList.of(p.variable("A1", BIGINT), p.variable("B1", BIGINT)), Optional.empty())).matches(join(LEFT, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0))));
}
Also used : CostComparator(com.facebook.presto.cost.CostComparator) Type(com.facebook.presto.sql.planner.plan.JoinNode.Type) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) PlanBuilder.castToRowExpression(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) FULL(com.facebook.presto.sql.planner.plan.JoinNode.Type.FULL) PlanMatchPattern.join(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join) JoinDistributionType(com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType) ImmutableList(com.google.common.collect.ImmutableList) JOIN_MAX_BROADCAST_TABLE_SIZE(com.facebook.presto.SystemSessionProperties.JOIN_MAX_BROADCAST_TABLE_SIZE) PlanMatchPattern.equiJoinClause(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause) PlanMatchPattern.enforceSingleRow(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.enforceSingleRow) RuleAssert(com.facebook.presto.sql.planner.iterative.rule.test.RuleAssert) TaskCountEstimator(com.facebook.presto.cost.TaskCountEstimator) DistributionType(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) AfterClass(org.testng.annotations.AfterClass) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PlanNodeStatsEstimate(com.facebook.presto.cost.PlanNodeStatsEstimate) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) JOIN_DISTRIBUTION_TYPE(com.facebook.presto.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE) RIGHT(com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT) PlanBuilder.constantExpressions(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder.constantExpressions) REPLICATED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.REPLICATED) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) CostComparator(com.facebook.presto.cost.CostComparator) Optional(java.util.Optional) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) PARTITIONED(com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.PARTITIONED) VariableStatsEstimate(com.facebook.presto.cost.VariableStatsEstimate) RuleTester(com.facebook.presto.sql.planner.iterative.rule.test.RuleTester) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) VariableStatsEstimate(com.facebook.presto.cost.VariableStatsEstimate) Test(org.testng.annotations.Test)

Example 5 with LEFT

use of com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT in project presto by prestodb.

the class ExtractSpatialJoins method tryCreateSpatialJoin.

private static Result tryCreateSpatialJoin(Context context, JoinNode joinNode, RowExpression filter, PlanNodeId nodeId, List<VariableReferenceExpression> outputVariables, CallExpression spatialFunction, Optional<RowExpression> radius, Metadata metadata, SplitManager splitManager, PageSourceManager pageSourceManager) {
    FunctionAndTypeManager functionAndTypeManager = metadata.getFunctionAndTypeManager();
    List<RowExpression> arguments = spatialFunction.getArguments();
    verify(arguments.size() == 2);
    RowExpression firstArgument = arguments.get(0);
    RowExpression secondArgument = arguments.get(1);
    // Currently, only inner joins are supported for spherical geometries.
    if (joinNode.getType() != INNER && isSphericalJoin(metadata, firstArgument, secondArgument)) {
        return Result.empty();
    }
    Set<VariableReferenceExpression> firstVariables = extractUnique(firstArgument);
    Set<VariableReferenceExpression> secondVariables = extractUnique(secondArgument);
    if (firstVariables.isEmpty() || secondVariables.isEmpty()) {
        return Result.empty();
    }
    // If either firstArgument or secondArgument is not a
    // VariableReferenceExpression, will replace the left/right join node
    // with a projection that adds the argument as a variable.
    Optional<VariableReferenceExpression> newFirstVariable = newGeometryVariable(context, firstArgument);
    Optional<VariableReferenceExpression> newSecondVariable = newGeometryVariable(context, secondArgument);
    PlanNode leftNode = joinNode.getLeft();
    PlanNode rightNode = joinNode.getRight();
    PlanNode newLeftNode;
    PlanNode newRightNode;
    // Check if the order of arguments of the spatial function matches the order of join sides
    int alignment = checkAlignment(joinNode, firstVariables, secondVariables);
    if (alignment > 0) {
        newLeftNode = newFirstVariable.map(variable -> addProjection(context, leftNode, variable, firstArgument)).orElse(leftNode);
        newRightNode = newSecondVariable.map(variable -> addProjection(context, rightNode, variable, secondArgument)).orElse(rightNode);
    } else if (alignment < 0) {
        newLeftNode = newSecondVariable.map(variable -> addProjection(context, leftNode, variable, secondArgument)).orElse(leftNode);
        newRightNode = newFirstVariable.map(variable -> addProjection(context, rightNode, variable, firstArgument)).orElse(rightNode);
    } else {
        return Result.empty();
    }
    RowExpression newFirstArgument = mapToExpression(newFirstVariable, firstArgument);
    RowExpression newSecondArgument = mapToExpression(newSecondVariable, secondArgument);
    // Implement partitioned spatial joins:
    // If the session parameter points to a valid spatial partitioning, use
    // that to assign to each probe and build rows the partitions that the
    // geometry intersects.  This is a projection that adds an array of ints
    // which is subsequently unnested.
    Optional<String> spatialPartitioningTableName = canPartitionSpatialJoin(joinNode) ? getSpatialPartitioningTableName(context.getSession()) : Optional.empty();
    Optional<KdbTree> kdbTree = spatialPartitioningTableName.map(tableName -> loadKdbTree(tableName, context.getSession(), metadata, splitManager, pageSourceManager));
    Optional<VariableReferenceExpression> leftPartitionVariable = Optional.empty();
    Optional<VariableReferenceExpression> rightPartitionVariable = Optional.empty();
    if (kdbTree.isPresent()) {
        leftPartitionVariable = Optional.of(context.getVariableAllocator().newVariable(newFirstArgument.getSourceLocation(), "pid", INTEGER));
        rightPartitionVariable = Optional.of(context.getVariableAllocator().newVariable(newSecondArgument.getSourceLocation(), "pid", INTEGER));
        if (alignment > 0) {
            newLeftNode = addPartitioningNodes(context, functionAndTypeManager, newLeftNode, leftPartitionVariable.get(), kdbTree.get(), newFirstArgument, Optional.empty());
            newRightNode = addPartitioningNodes(context, functionAndTypeManager, newRightNode, rightPartitionVariable.get(), kdbTree.get(), newSecondArgument, radius);
        } else {
            newLeftNode = addPartitioningNodes(context, functionAndTypeManager, newLeftNode, leftPartitionVariable.get(), kdbTree.get(), newSecondArgument, Optional.empty());
            newRightNode = addPartitioningNodes(context, functionAndTypeManager, newRightNode, rightPartitionVariable.get(), kdbTree.get(), newFirstArgument, radius);
        }
    }
    CallExpression newSpatialFunction = new CallExpression(spatialFunction.getSourceLocation(), spatialFunction.getDisplayName(), spatialFunction.getFunctionHandle(), spatialFunction.getType(), ImmutableList.of(newFirstArgument, newSecondArgument));
    RowExpression newFilter = RowExpressionNodeInliner.replaceExpression(filter, ImmutableMap.of(spatialFunction, newSpatialFunction));
    return Result.ofPlanNode(new SpatialJoinNode(joinNode.getSourceLocation(), nodeId, SpatialJoinNode.Type.fromJoinNodeType(joinNode.getType()), newLeftNode, newRightNode, outputVariables, newFilter, leftPartitionVariable, rightPartitionVariable, kdbTree.map(KdbTreeUtils::toJson)));
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) WarningCollector(com.facebook.presto.spi.WarningCollector) Page(com.facebook.presto.common.Page) SpatialJoinNode(com.facebook.presto.sql.planner.plan.SpatialJoinNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TypeSignature(com.facebook.presto.common.type.TypeSignature) MoreFutures.getFutureValue(com.facebook.airlift.concurrent.MoreFutures.getFutureValue) NOT_PARTITIONED(com.facebook.presto.spi.connector.NotPartitionedPartitionHandle.NOT_PARTITIONED) SpatialJoinUtils.getFlippedFunctionHandle(com.facebook.presto.util.SpatialJoinUtils.getFlippedFunctionHandle) Pattern(com.facebook.presto.matching.Pattern) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Capture(com.facebook.presto.matching.Capture) SpatialJoinUtils.flip(com.facebook.presto.util.SpatialJoinUtils.flip) Map(java.util.Map) UNGROUPED_SCHEDULING(com.facebook.presto.spi.connector.ConnectorSplitManager.SplitSchedulingStrategy.UNGROUPED_SCHEDULING) LOCAL(com.facebook.presto.spi.plan.ProjectNode.Locality.LOCAL) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) SystemSessionProperties.isSpatialJoinEnabled(com.facebook.presto.SystemSessionProperties.isSpatialJoinEnabled) Slices.utf8Slice(io.airlift.slice.Slices.utf8Slice) CallExpression(com.facebook.presto.spi.relation.CallExpression) Splitter(com.google.common.base.Splitter) SplitSource(com.facebook.presto.split.SplitSource) Lifespan(com.facebook.presto.execution.Lifespan) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) SplitManager(com.facebook.presto.split.SplitManager) String.format(java.lang.String.format) KDB_TREE(com.facebook.presto.common.type.KdbTreeType.KDB_TREE) UncheckedIOException(java.io.UncheckedIOException) FunctionMetadata(com.facebook.presto.spi.function.FunctionMetadata) List(java.util.List) SpatialJoinUtils.extractSupportedSpatialFunctions(com.facebook.presto.util.SpatialJoinUtils.extractSupportedSpatialFunctions) KdbTreeUtils(com.facebook.presto.geospatial.KdbTreeUtils) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) Capture.newCapture(com.facebook.presto.matching.Capture.newCapture) INTEGER(com.facebook.presto.common.type.IntegerType.INTEGER) Optional(java.util.Optional) CAST(com.facebook.presto.metadata.CastType.CAST) VariablesExtractor.extractUnique(com.facebook.presto.sql.planner.VariablesExtractor.extractUnique) INNER(com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER) PlanNodeId(com.facebook.presto.spi.plan.PlanNodeId) Iterables(com.google.common.collect.Iterables) TableLayoutResult(com.facebook.presto.metadata.TableLayoutResult) VARCHAR(com.facebook.presto.common.type.VarcharType.VARCHAR) Captures(com.facebook.presto.matching.Captures) Assignments(com.facebook.presto.spi.plan.Assignments) Result(com.facebook.presto.sql.planner.iterative.Rule.Result) PrestoException(com.facebook.presto.spi.PrestoException) Patterns.join(com.facebook.presto.sql.planner.plan.Patterns.join) TypeSignatureProvider.fromTypes(com.facebook.presto.sql.analyzer.TypeSignatureProvider.fromTypes) Patterns.filter(com.facebook.presto.sql.planner.plan.Patterns.filter) FilterNode(com.facebook.presto.spi.plan.FilterNode) SplitBatch(com.facebook.presto.split.SplitSource.SplitBatch) RowExpressionNodeInliner(com.facebook.presto.expressions.RowExpressionNodeInliner) ImmutableList(com.google.common.collect.ImmutableList) PageSourceManager(com.facebook.presto.split.PageSourceManager) Verify.verify(com.google.common.base.Verify.verify) Objects.requireNonNull(java.util.Objects.requireNonNull) SpatialJoinUtils.extractSupportedSpatialComparisons(com.facebook.presto.util.SpatialJoinUtils.extractSupportedSpatialComparisons) ArrayType(com.facebook.presto.common.type.ArrayType) TableHandle(com.facebook.presto.spi.TableHandle) Expressions(com.facebook.presto.sql.relational.Expressions) KdbTree(com.facebook.presto.geospatial.KdbTree) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) Type(com.facebook.presto.common.type.Type) RowExpression(com.facebook.presto.spi.relation.RowExpression) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) INVALID_SPATIAL_PARTITIONING(com.facebook.presto.spi.StandardErrorCode.INVALID_SPATIAL_PARTITIONING) SystemSessionProperties.getSpatialPartitioningTableName(com.facebook.presto.SystemSessionProperties.getSpatialPartitioningTableName) Session(com.facebook.presto.Session) Rule(com.facebook.presto.sql.planner.iterative.Rule) Constraint(com.facebook.presto.spi.Constraint) IOException(java.io.IOException) OperatorType(com.facebook.presto.common.function.OperatorType) Patterns.source(com.facebook.presto.sql.planner.plan.Patterns.source) PlanNode(com.facebook.presto.spi.plan.PlanNode) ConnectorPageSource(com.facebook.presto.spi.ConnectorPageSource) TypeSignature.parseTypeSignature(com.facebook.presto.common.type.TypeSignature.parseTypeSignature) LEFT(com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT) ColumnHandle(com.facebook.presto.spi.ColumnHandle) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) Split(com.facebook.presto.metadata.Split) Context(com.facebook.presto.sql.planner.iterative.Rule.Context) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Metadata(com.facebook.presto.metadata.Metadata) RowExpressionNodeInliner.replaceExpression(com.facebook.presto.expressions.RowExpressionNodeInliner.replaceExpression) KdbTreeUtils(com.facebook.presto.geospatial.KdbTreeUtils) KdbTree(com.facebook.presto.geospatial.KdbTree) RowExpression(com.facebook.presto.spi.relation.RowExpression) SpatialJoinNode(com.facebook.presto.sql.planner.plan.SpatialJoinNode) Constraint(com.facebook.presto.spi.Constraint) PlanNode(com.facebook.presto.spi.plan.PlanNode) FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Aggregations

VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)7 JoinNode (com.facebook.presto.sql.planner.plan.JoinNode)7 LEFT (com.facebook.presto.sql.planner.plan.JoinNode.Type.LEFT)7 Optional (java.util.Optional)7 PARTITIONED (com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.PARTITIONED)6 REPLICATED (com.facebook.presto.sql.planner.plan.JoinNode.DistributionType.REPLICATED)6 INNER (com.facebook.presto.sql.planner.plan.JoinNode.Type.INNER)6 RIGHT (com.facebook.presto.sql.planner.plan.JoinNode.Type.RIGHT)6 ImmutableList (com.google.common.collect.ImmutableList)6 ImmutableMap (com.google.common.collect.ImmutableMap)6 JOIN_DISTRIBUTION_TYPE (com.facebook.presto.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE)5 BIGINT (com.facebook.presto.common.type.BigintType.BIGINT)5 PlanNodeId (com.facebook.presto.spi.plan.PlanNodeId)5 JOIN_MAX_BROADCAST_TABLE_SIZE (com.facebook.presto.SystemSessionProperties.JOIN_MAX_BROADCAST_TABLE_SIZE)4 JoinDistributionType (com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType)4 PlanMatchPattern.equiJoinClause (com.facebook.presto.sql.planner.assertions.PlanMatchPattern.equiJoinClause)4 PlanMatchPattern.join (com.facebook.presto.sql.planner.assertions.PlanMatchPattern.join)4 PlanMatchPattern.values (com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values)4 Test (org.testng.annotations.Test)4 CostComparator (com.facebook.presto.cost.CostComparator)3