Search in sources :

Example 11 with LEFT

use of io.trino.sql.planner.plan.JoinNode.Type.LEFT in project trino by trinodb.

the class TestDetermineJoinDistributionType method testReplicatesWhenSourceIsSmall.

@Test
public void testReplicatesWhenSourceIsSmall() {
    // variable width so that average row size is respected
    VarcharType symbolType = createUnboundedVarcharType();
    int aRows = 10_000;
    int bRows = 10;
    // output size exceeds AUTOMATIC_RESTRICTED limit
    PlanNodeStatsEstimate aStatsEstimate = PlanNodeStatsEstimate.builder().setOutputRowCount(aRows).addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 640000d * 10000, 10))).build();
    // output size exceeds AUTOMATIC_RESTRICTED limit
    PlanNodeStatsEstimate bStatsEstimate = PlanNodeStatsEstimate.builder().setOutputRowCount(bRows).addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000d * 10000, 10))).build();
    // output size does not  exceed AUTOMATIC_RESTRICTED limit
    PlanNodeStatsEstimate bSourceStatsEstimate = PlanNodeStatsEstimate.builder().setOutputRowCount(bRows).addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 64, 10))).build();
    // immediate join sources exceeds AUTOMATIC_RESTRICTED limit but build tables are small
    // therefore replicated distribution type is chosen
    assertDetermineJoinDistributionType().setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).setSystemProperty(JOIN_MAX_BROADCAST_TABLE_SIZE, "100MB").overrideStats("valuesA", aStatsEstimate).overrideStats("filterB", bStatsEstimate).overrideStats("valuesB", bSourceStatsEstimate).on(p -> {
        Symbol a1 = p.symbol("A1", symbolType);
        Symbol b1 = p.symbol("B1", symbolType);
        return p.join(INNER, p.values(new PlanNodeId("valuesA"), aRows, a1), p.filter(new PlanNodeId("filterB"), TRUE_LITERAL, p.values(new PlanNodeId("valuesB"), bRows, b1)), ImmutableList.of(new JoinNode.EquiJoinClause(a1, b1)), ImmutableList.of(a1), ImmutableList.of(b1), Optional.empty());
    }).matches(join(INNER, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), filter("true", values(ImmutableMap.of("B1", 0)))));
    // same but with join sides reversed
    assertDetermineJoinDistributionType().setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).setSystemProperty(JOIN_MAX_BROADCAST_TABLE_SIZE, "100MB").overrideStats("valuesA", aStatsEstimate).overrideStats("filterB", bStatsEstimate).overrideStats("valuesB", bSourceStatsEstimate).on(p -> {
        Symbol a1 = p.symbol("A1", symbolType);
        Symbol b1 = p.symbol("B1", symbolType);
        return p.join(INNER, p.filter(new PlanNodeId("filterB"), TRUE_LITERAL, p.values(new PlanNodeId("valuesB"), bRows, b1)), p.values(new PlanNodeId("valuesA"), aRows, a1), ImmutableList.of(new JoinNode.EquiJoinClause(b1, a1)), ImmutableList.of(b1), ImmutableList.of(a1), Optional.empty());
    }).matches(join(INNER, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), filter("true", values(ImmutableMap.of("B1", 0)))));
    // only probe side (with small tables) source stats are available, join sides should be flipped
    assertDetermineJoinDistributionType().setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.AUTOMATIC.name()).setSystemProperty(JOIN_MAX_BROADCAST_TABLE_SIZE, "100MB").overrideStats("valuesA", PlanNodeStatsEstimate.unknown()).overrideStats("filterB", PlanNodeStatsEstimate.unknown()).overrideStats("valuesB", bSourceStatsEstimate).on(p -> {
        Symbol a1 = p.symbol("A1", symbolType);
        Symbol b1 = p.symbol("B1", symbolType);
        return p.join(LEFT, p.filter(new PlanNodeId("filterB"), TRUE_LITERAL, p.values(new PlanNodeId("valuesB"), bRows, b1)), p.values(new PlanNodeId("valuesA"), aRows, a1), ImmutableList.of(new JoinNode.EquiJoinClause(b1, a1)), ImmutableList.of(b1), ImmutableList.of(a1), Optional.empty());
    }).matches(join(RIGHT, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(PARTITIONED), values(ImmutableMap.of("A1", 0)), filter("true", values(ImmutableMap.of("B1", 0)))));
}
Also used : PARTITIONED(io.trino.sql.planner.plan.JoinNode.DistributionType.PARTITIONED) INNER(io.trino.sql.planner.plan.JoinNode.Type.INNER) VarcharType.createUnboundedVarcharType(io.trino.spi.type.VarcharType.createUnboundedVarcharType) Assert.assertEquals(org.testng.Assert.assertEquals) Test(org.testng.annotations.Test) PlanMatchPattern.filter(io.trino.sql.planner.assertions.PlanMatchPattern.filter) REPLICATED(io.trino.sql.planner.plan.JoinNode.DistributionType.REPLICATED) Lookup.noLookup(io.trino.sql.planner.iterative.Lookup.noLookup) VarcharType(io.trino.spi.type.VarcharType) LEFT(io.trino.sql.planner.plan.JoinNode.Type.LEFT) RuleAssert(io.trino.sql.planner.iterative.rule.test.RuleAssert) Type(io.trino.sql.planner.plan.JoinNode.Type) PlanBuilder.expressions(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expressions) ImmutableList(com.google.common.collect.ImmutableList) NaN(java.lang.Double.NaN) DistributionType(io.trino.sql.planner.plan.JoinNode.DistributionType) PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) PlanBuilder(io.trino.sql.planner.iterative.rule.test.PlanBuilder) PlanMatchPattern.equiJoinClause(io.trino.sql.planner.assertions.PlanMatchPattern.equiJoinClause) JoinNode(io.trino.sql.planner.plan.JoinNode) TableScanNode(io.trino.sql.planner.plan.TableScanNode) PlanMatchPattern.join(io.trino.sql.planner.assertions.PlanMatchPattern.join) PlanNodeStatsEstimate(io.trino.cost.PlanNodeStatsEstimate) JOIN_MAX_BROADCAST_TABLE_SIZE(io.trino.SystemSessionProperties.JOIN_MAX_BROADCAST_TABLE_SIZE) TaskCountEstimator(io.trino.cost.TaskCountEstimator) Symbol(io.trino.sql.planner.Symbol) AfterClass(org.testng.annotations.AfterClass) SymbolStatsEstimate(io.trino.cost.SymbolStatsEstimate) RuleTester.defaultRuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester.defaultRuleTester) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) FULL(io.trino.sql.planner.plan.JoinNode.Type.FULL) RuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) JoinDistributionType(io.trino.sql.planner.OptimizerConfig.JoinDistributionType) DetermineJoinDistributionType.getSourceTablesSizeInBytes(io.trino.sql.planner.iterative.rule.DetermineJoinDistributionType.getSourceTablesSizeInBytes) CostComparator(io.trino.cost.CostComparator) PlanMatchPattern.enforceSingleRow(io.trino.sql.planner.assertions.PlanMatchPattern.enforceSingleRow) BIGINT(io.trino.spi.type.BigintType.BIGINT) RIGHT(io.trino.sql.planner.plan.JoinNode.Type.RIGHT) JOIN_DISTRIBUTION_TYPE(io.trino.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) Optional(java.util.Optional) ValuesNode(io.trino.sql.planner.plan.ValuesNode) TestingColumnHandle(io.trino.testing.TestingMetadata.TestingColumnHandle) PlanBuilder.expression(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expression) PlanNodeIdAllocator(io.trino.sql.planner.PlanNodeIdAllocator) PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) VarcharType.createUnboundedVarcharType(io.trino.spi.type.VarcharType.createUnboundedVarcharType) VarcharType(io.trino.spi.type.VarcharType) PlanNodeStatsEstimate(io.trino.cost.PlanNodeStatsEstimate) Symbol(io.trino.sql.planner.Symbol) JoinNode(io.trino.sql.planner.plan.JoinNode) SymbolStatsEstimate(io.trino.cost.SymbolStatsEstimate) Test(org.testng.annotations.Test)

Example 12 with LEFT

use of io.trino.sql.planner.plan.JoinNode.Type.LEFT in project trino by trinodb.

the class TestPushLimitThroughOuterJoin method testLimitWithPreSortedInputsLeftJoin.

@Test
public void testLimitWithPreSortedInputsLeftJoin() {
    tester().assertThat(new PushLimitThroughOuterJoin()).on(p -> {
        Symbol leftKey = p.symbol("leftKey");
        Symbol rightKey = p.symbol("rightKey");
        return p.limit(1, false, ImmutableList.of(rightKey), p.join(LEFT, p.values(5, leftKey), p.values(5, rightKey), new EquiJoinClause(leftKey, rightKey)));
    }).doesNotFire();
    tester().assertThat(new PushLimitThroughOuterJoin()).on(p -> {
        Symbol leftKey = p.symbol("leftKey");
        Symbol rightKey = p.symbol("rightKey");
        return p.limit(1, false, ImmutableList.of(leftKey), p.join(LEFT, p.values(5, leftKey), p.values(5, rightKey), new EquiJoinClause(leftKey, rightKey)));
    }).matches(limit(1, ImmutableList.of(), false, ImmutableList.of("leftKey"), join(LEFT, ImmutableList.of(equiJoinClause("leftKey", "rightKey")), limit(1, ImmutableList.of(), true, ImmutableList.of("leftKey"), values("leftKey")), values("rightKey"))));
}
Also used : Symbol(io.trino.sql.planner.Symbol) PlanMatchPattern.limit(io.trino.sql.planner.assertions.PlanMatchPattern.limit) LEFT(io.trino.sql.planner.plan.JoinNode.Type.LEFT) ImmutableList(com.google.common.collect.ImmutableList) RIGHT(io.trino.sql.planner.plan.JoinNode.Type.RIGHT) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) FULL(io.trino.sql.planner.plan.JoinNode.Type.FULL) PlanMatchPattern.equiJoinClause(io.trino.sql.planner.assertions.PlanMatchPattern.equiJoinClause) Test(org.testng.annotations.Test) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) PlanMatchPattern.join(io.trino.sql.planner.assertions.PlanMatchPattern.join) Symbol(io.trino.sql.planner.Symbol) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Example 13 with LEFT

use of io.trino.sql.planner.plan.JoinNode.Type.LEFT in project trino by trinodb.

the class TestPushAggregationThroughOuterJoin method testDoesNotFireWhenAggregationOnMultipleSymbolsDoesNotHaveSomeSymbols.

@Test
public void testDoesNotFireWhenAggregationOnMultipleSymbolsDoesNotHaveSomeSymbols() {
    tester().assertThat(new PushAggregationThroughOuterJoin()).on(p -> p.aggregation(ab -> ab.source(p.join(LEFT, p.values(ImmutableList.of(p.symbol("COL1")), ImmutableList.of(expressions("10"))), p.values(ImmutableList.of(p.symbol("COL2"), p.symbol("COL3")), ImmutableList.of(expressions("20", "30"))), ImmutableList.of(new EquiJoinClause(new Symbol("COL1"), new Symbol("COL2"))), ImmutableList.of(new Symbol("COL1")), ImmutableList.of(new Symbol("COL2")), Optional.empty(), Optional.empty(), Optional.empty())).addAggregation(new Symbol("MIN_BY"), PlanBuilder.expression("min_by(COL2, COL1)"), ImmutableList.of(DOUBLE, DOUBLE)).singleGroupingSet(new Symbol("COL1")))).doesNotFire();
    tester().assertThat(new PushAggregationThroughOuterJoin()).on(p -> p.aggregation(ab -> ab.source(p.join(LEFT, p.values(ImmutableList.of(p.symbol("COL1")), ImmutableList.of(expressions("10"))), p.values(ImmutableList.of(p.symbol("COL2"), p.symbol("COL3")), ImmutableList.of(expressions("20", "30"))), ImmutableList.of(new EquiJoinClause(new Symbol("COL1"), new Symbol("COL2"))), ImmutableList.of(new Symbol("COL1")), ImmutableList.of(new Symbol("COL2")), Optional.empty(), Optional.empty(), Optional.empty())).addAggregation(new Symbol("SUM"), PlanBuilder.expression("sum(COL2)"), ImmutableList.of(DOUBLE)).addAggregation(new Symbol("MIN_BY"), PlanBuilder.expression("min_by(COL2, COL3)"), ImmutableList.of(DOUBLE, DOUBLE)).addAggregation(new Symbol("MAX_BY"), PlanBuilder.expression("max_by(COL2, COL1)"), ImmutableList.of(DOUBLE, DOUBLE)).singleGroupingSet(new Symbol("COL1")))).doesNotFire();
}
Also used : PlanMatchPattern.aggregation(io.trino.sql.planner.assertions.PlanMatchPattern.aggregation) INNER(io.trino.sql.planner.plan.JoinNode.Type.INNER) SINGLE(io.trino.sql.planner.plan.AggregationNode.Step.SINGLE) Test(org.testng.annotations.Test) LEFT(io.trino.sql.planner.plan.JoinNode.Type.LEFT) PlanBuilder.expressions(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expressions) ImmutableList(com.google.common.collect.ImmutableList) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) PlanBuilder(io.trino.sql.planner.iterative.rule.test.PlanBuilder) PlanMatchPattern.equiJoinClause(io.trino.sql.planner.assertions.PlanMatchPattern.equiJoinClause) PlanMatchPattern.join(io.trino.sql.planner.assertions.PlanMatchPattern.join) Symbol(io.trino.sql.planner.Symbol) PlanMatchPattern.expression(io.trino.sql.planner.assertions.PlanMatchPattern.expression) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Assignments(io.trino.sql.planner.plan.Assignments) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) PlanMatchPattern.globalAggregation(io.trino.sql.planner.assertions.PlanMatchPattern.globalAggregation) PlanMatchPattern.singleGroupingSet(io.trino.sql.planner.assertions.PlanMatchPattern.singleGroupingSet) PlanMatchPattern.functionCall(io.trino.sql.planner.assertions.PlanMatchPattern.functionCall) DOUBLE(io.trino.spi.type.DoubleType.DOUBLE) AggregationNode.groupingSets(io.trino.sql.planner.plan.AggregationNode.groupingSets) BIGINT(io.trino.spi.type.BigintType.BIGINT) PlanMatchPattern.project(io.trino.sql.planner.assertions.PlanMatchPattern.project) RIGHT(io.trino.sql.planner.plan.JoinNode.Type.RIGHT) Optional(java.util.Optional) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) Symbol(io.trino.sql.planner.Symbol) Test(org.testng.annotations.Test) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest)

Example 14 with LEFT

use of io.trino.sql.planner.plan.JoinNode.Type.LEFT in project trino by trinodb.

the class TestPushAggregationThroughOuterJoin method testDoesNotFireWhenNotDistinct.

@Test
public void testDoesNotFireWhenNotDistinct() {
    tester().assertThat(new PushAggregationThroughOuterJoin()).on(p -> p.aggregation(ab -> ab.source(p.join(LEFT, p.values(ImmutableList.of(p.symbol("COL1")), ImmutableList.of(expressions("10"), expressions("11"))), p.values(new Symbol("COL2")), ImmutableList.of(new EquiJoinClause(new Symbol("COL1"), new Symbol("COL2"))), ImmutableList.of(p.symbol("COL1")), ImmutableList.of(p.symbol("COL2")), Optional.empty(), Optional.empty(), Optional.empty())).addAggregation(new Symbol("AVG"), PlanBuilder.expression("avg(COL2)"), ImmutableList.of(DOUBLE)).singleGroupingSet(new Symbol("COL1")))).doesNotFire();
    // https://github.com/prestodb/presto/issues/10592
    tester().assertThat(new PushAggregationThroughOuterJoin()).on(p -> p.aggregation(ab -> ab.source(p.join(LEFT, p.project(Assignments.builder().putIdentity(p.symbol("COL1", BIGINT)).build(), p.aggregation(builder -> builder.singleGroupingSet(p.symbol("COL1"), p.symbol("unused")).source(p.values(ImmutableList.of(p.symbol("COL1"), p.symbol("unused")), ImmutableList.of(expressions("10", "1"), expressions("10", "2")))))), p.values(p.symbol("COL2")), ImmutableList.of(new EquiJoinClause(p.symbol("COL1"), p.symbol("COL2"))), ImmutableList.of(p.symbol("COL1")), ImmutableList.of(p.symbol("COL2")), Optional.empty(), Optional.empty(), Optional.empty())).addAggregation(p.symbol("AVG", DOUBLE), PlanBuilder.expression("avg(COL2)"), ImmutableList.of(DOUBLE)).singleGroupingSet(p.symbol("COL1")))).doesNotFire();
}
Also used : PlanMatchPattern.aggregation(io.trino.sql.planner.assertions.PlanMatchPattern.aggregation) INNER(io.trino.sql.planner.plan.JoinNode.Type.INNER) SINGLE(io.trino.sql.planner.plan.AggregationNode.Step.SINGLE) Test(org.testng.annotations.Test) LEFT(io.trino.sql.planner.plan.JoinNode.Type.LEFT) PlanBuilder.expressions(io.trino.sql.planner.iterative.rule.test.PlanBuilder.expressions) ImmutableList(com.google.common.collect.ImmutableList) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) PlanBuilder(io.trino.sql.planner.iterative.rule.test.PlanBuilder) PlanMatchPattern.equiJoinClause(io.trino.sql.planner.assertions.PlanMatchPattern.equiJoinClause) PlanMatchPattern.join(io.trino.sql.planner.assertions.PlanMatchPattern.join) Symbol(io.trino.sql.planner.Symbol) PlanMatchPattern.expression(io.trino.sql.planner.assertions.PlanMatchPattern.expression) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Assignments(io.trino.sql.planner.plan.Assignments) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) PlanMatchPattern.globalAggregation(io.trino.sql.planner.assertions.PlanMatchPattern.globalAggregation) PlanMatchPattern.singleGroupingSet(io.trino.sql.planner.assertions.PlanMatchPattern.singleGroupingSet) PlanMatchPattern.functionCall(io.trino.sql.planner.assertions.PlanMatchPattern.functionCall) DOUBLE(io.trino.spi.type.DoubleType.DOUBLE) AggregationNode.groupingSets(io.trino.sql.planner.plan.AggregationNode.groupingSets) BIGINT(io.trino.spi.type.BigintType.BIGINT) PlanMatchPattern.project(io.trino.sql.planner.assertions.PlanMatchPattern.project) RIGHT(io.trino.sql.planner.plan.JoinNode.Type.RIGHT) Optional(java.util.Optional) Symbol(io.trino.sql.planner.Symbol) EquiJoinClause(io.trino.sql.planner.plan.JoinNode.EquiJoinClause) Test(org.testng.annotations.Test) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)14 LEFT (io.trino.sql.planner.plan.JoinNode.Type.LEFT)14 Symbol (io.trino.sql.planner.Symbol)13 Optional (java.util.Optional)13 ImmutableMap (com.google.common.collect.ImmutableMap)12 INNER (io.trino.sql.planner.plan.JoinNode.Type.INNER)11 BIGINT (io.trino.spi.type.BigintType.BIGINT)10 PlanMatchPattern.values (io.trino.sql.planner.assertions.PlanMatchPattern.values)9 RIGHT (io.trino.sql.planner.plan.JoinNode.Type.RIGHT)9 Test (org.testng.annotations.Test)9 PlanMatchPattern.equiJoinClause (io.trino.sql.planner.assertions.PlanMatchPattern.equiJoinClause)8 PlanMatchPattern.join (io.trino.sql.planner.assertions.PlanMatchPattern.join)8 TRUE_LITERAL (io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL)8 ImmutableSet (com.google.common.collect.ImmutableSet)7 Assignments (io.trino.sql.planner.plan.Assignments)7 FULL (io.trino.sql.planner.plan.JoinNode.Type.FULL)7 PlanNodeId (io.trino.sql.planner.plan.PlanNodeId)7 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)6 PlanNodeIdAllocator (io.trino.sql.planner.PlanNodeIdAllocator)6 JOIN_DISTRIBUTION_TYPE (io.trino.SystemSessionProperties.JOIN_DISTRIBUTION_TYPE)5