@Test public void testAllColumnsNeeded() { tester().assertThat(new PruneWindowColumns()) .on(p -> buildProjectedWindow(p, alwaysTrue(), alwaysTrue())) .doesNotFire(); }
@Test public void testValueExpressionRewrite() { tester().assertThat(zeroRewriter.valuesExpressionRewrite()) .on(p -> p.values( ImmutableList.<Symbol>of(p.symbol("a")), ImmutableList.of((ImmutableList.of(PlanBuilder.expression("1")))))) .matches( values(ImmutableList.of("a"), ImmutableList.of(ImmutableList.of(new LongLiteral("0"))))); }
public RuleAssert assertThat(Rule rule) { return new RuleAssert(metadata, queryRunner.getStatsCalculator(), queryRunner.getEstimatedExchangesCostCalculator(), session, rule, transactionManager, accessControl); }
public void doesNotFire() { RuleApplication ruleApplication = applyRule(); if (ruleApplication.wasRuleApplied()) { fail(String.format( "Expected %s to not fire for:\n%s", rule.getClass().getName(), inTransaction(session -> textLogicalPlan(plan, ruleApplication.types, metadata.getFunctionRegistry(), StatsAndCosts.empty(), session, 2)))); } }
@Test public void testDoNotReorderOuterJoin() { tester().assertThat(new EliminateCrossJoins()) .setSystemProperty(JOIN_REORDERING_STRATEGY, "ELIMINATE_CROSS_JOINS") .on(crossJoinAndJoin(JoinNode.Type.LEFT)) .doesNotFire(); }
@Test public void testRetainOutgoingGroupReferences() { tester().assertThat(new EliminateCrossJoins()) .setSystemProperty(JOIN_REORDERING_STRATEGY, "ELIMINATE_CROSS_JOINS") .on(crossJoinAndJoin(INNER)) .matches( node(JoinNode.class, node(JoinNode.class, node(GroupReference.class), node(GroupReference.class)), node(GroupReference.class))); }
@Test public void testRepartitionsWhenBothTablesEqual() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.symbol("B1")), TWO_ROWS), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1"), p.symbol("B1")), Optional.empty())) .overrideStats("valuesA", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .overrideStats("valuesB", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .matches(join( INNER, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(PARTITIONED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0)))); }
@Test public void testReplicatesUnrestrictedWhenRequiredBySession() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.symbol("B1")), TWO_ROWS), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1"), p.symbol("B1")), Optional.empty())) .setSystemProperty(JOIN_MAX_BROADCAST_TABLE_SIZE, "1kB") .setSystemProperty(JOIN_DISTRIBUTION_TYPE, BROADCAST.name()) .overrideStats("valuesA", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .overrideStats("valuesB", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .matches(join( INNER, ImmutableList.of(equiJoinClause("A1", "B1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0)))); }
@Test public void testDoesNotFireWithNoStats() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), p.symbol("B1")), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1")), Optional.empty())) .overrideStats("valuesA", PlanNodeStatsEstimate.unknown()) .doesNotFire(); }
private RuleApplication applyRule() { SymbolAllocator symbolAllocator = new SymbolAllocator(types.allTypes()); Memo memo = new Memo(idAllocator, plan); Lookup lookup = Lookup.from(planNode -> Stream.of(memo.resolve(planNode))); PlanNode memoRoot = memo.getNode(memo.getRootGroup()); return inTransaction(session -> applyRule(rule, memoRoot, ruleContext(statsCalculator, costCalculator, symbolAllocator, memo, lookup, session))); }
public void matches(PlanMatchPattern pattern) RuleApplication ruleApplication = applyRule(); TypeProvider types = ruleApplication.types; "%s did not fire for:\n%s", rule.getClass().getName(), formatPlan(plan, types))); "%s: rule fired but return the original plan:\n%s", rule.getClass().getName(), formatPlan(plan, types))); inTransaction(session -> { assertPlan(session, metadata, ruleApplication.statsProvider, new Plan(actual, types, StatsAndCosts.empty()), ruleApplication.lookup, pattern); return null;
private String formatPlan(PlanNode plan, TypeProvider types) { StatsProvider statsProvider = new CachingStatsProvider(statsCalculator, session, types); CostProvider costProvider = new CachingCostProvider(costCalculator, statsProvider, session, types); return inTransaction(session -> textLogicalPlan(plan, types, metadata.getFunctionRegistry(), StatsAndCosts.create(plan, statsProvider, costProvider), session, 2, false)); }
private void testReplicateNoEquiCriteria(Type joinType) { assertDetermineJoinDistributionType() .on(p -> p.join( joinType, p.values(ImmutableList.of(p.symbol("A1")), ImmutableList.of(expressions("10"), expressions("11"))), p.values(ImmutableList.of(p.symbol("B1")), ImmutableList.of(expressions("50"), expressions("11"))), ImmutableList.of(), ImmutableList.of(p.symbol("A1", BIGINT), p.symbol("B1", BIGINT)), Optional.of(expression("A1 * B1 > 100")))) .setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.PARTITIONED.name()) .matches(join( joinType, ImmutableList.of(), Optional.of("A1 * B1 > 100"), Optional.of(DistributionType.REPLICATED), values(ImmutableMap.of("A1", 0)), values(ImmutableMap.of("B1", 0)))); }
@Test public void testReplicatesAndFlipsWhenOneTableMuchSmaller() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.symbol("B1")), TWO_ROWS), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1"), p.symbol("B1")), Optional.empty())) .overrideStats("valuesA", PlanNodeStatsEstimate.builder() .setOutputRowCount(100) .addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 6400, 100))) .build()) .overrideStats("valuesB", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .matches(join( INNER, ImmutableList.of(equiJoinClause("B1", "A1")), Optional.empty(), Optional.of(REPLICATED), values(ImmutableMap.of("B1", 0)), values(ImmutableMap.of("A1", 0)))); }
@Test public void testRepartitionsWhenRequiredBySession() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.symbol("B1")), TWO_ROWS), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1"), p.symbol("B1")), Optional.empty())) .setSystemProperty(JOIN_DISTRIBUTION_TYPE, JoinDistributionType.PARTITIONED.name()) .overrideStats("valuesA", PlanNodeStatsEstimate.builder() .setOutputRowCount(100) .addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 6400, 100))) .build()) .overrideStats("valuesB", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .matches(join( INNER, ImmutableList.of(equiJoinClause("B1", "A1")), Optional.empty(), Optional.of(PARTITIONED), values(ImmutableMap.of("B1", 0)), values(ImmutableMap.of("A1", 0)))); }
@Test public void testSessionDisable() { tester().assertThat(new AddIntermediateAggregations()) .setSystemProperty(ENABLE_INTERMEDIATE_AGGREGATIONS, "false") .setSystemProperty(TASK_CONCURRENCY, "4") .on(p -> p.aggregation(af -> { af.globalGrouping() .step(AggregationNode.Step.FINAL) .addAggregation(p.symbol("c"), expression("count(b)"), ImmutableList.of(BIGINT)) .source( p.gatheringExchange( ExchangeNode.Scope.REMOTE, p.aggregation(ap -> ap.globalGrouping() .step(AggregationNode.Step.PARTIAL) .addAggregation(p.symbol("b"), expression("count(a)"), ImmutableList.of(BIGINT)) .source( p.values(p.symbol("a")))))); })) .doesNotFire(); }
@Test public void testDoesNotFireForCrossJoin() { assertReorderJoins() .on(p -> p.join( INNER, p.values(new PlanNodeId("valuesA"), ImmutableList.of(p.symbol("A1")), TWO_ROWS), p.values(new PlanNodeId("valuesB"), ImmutableList.of(p.symbol("B1")), TWO_ROWS), ImmutableList.of(), ImmutableList.of(p.symbol("A1"), p.symbol("B1")), Optional.empty())) .overrideStats("valuesA", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .overrideStats("valuesB", PlanNodeStatsEstimate.builder() .setOutputRowCount(10000) .addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))) .build()) .doesNotFire(); }
@Test public void testAllInputsReferenced() { tester().assertThat(new PruneJoinColumns()) .on(p -> buildProjectedJoin(p, Predicates.alwaysTrue())) .doesNotFire(); }
@Test public void ruleAddedTableLayoutToTableScan() { tester().assertThat(pickTableLayout.pickTableLayoutWithoutPredicate()) .on(p -> p.tableScan( nationTableHandle, ImmutableList.of(p.symbol("nationkey", BIGINT)), ImmutableMap.of(p.symbol("nationkey", BIGINT), new TpchColumnHandle("nationkey", BIGINT)))) .matches( constrainedTableScanWithTableLayout("nation", ImmutableMap.of(), ImmutableMap.of("nationkey", "nationkey"))); }
private void testDetermineDistributionType(JoinDistributionType sessionDistributedJoin, Type joinType, DistributionType expectedDistribution) { assertDetermineJoinDistributionType() .on(p -> p.join( joinType, p.values(ImmutableList.of(p.symbol("A1")), ImmutableList.of(expressions("10"), expressions("11"))), p.values(ImmutableList.of(p.symbol("B1")), ImmutableList.of(expressions("50"), expressions("11"))), ImmutableList.of(new JoinNode.EquiJoinClause(p.symbol("A1", BIGINT), p.symbol("B1", BIGINT))), ImmutableList.of(p.symbol("A1", BIGINT), p.symbol("B1", BIGINT)), Optional.empty())) .setSystemProperty(JOIN_DISTRIBUTION_TYPE, sessionDistributedJoin.name()) .matches(join( joinType, ImmutableList.of(equiJoinClause("B1", "A1")), Optional.empty(), Optional.of(expectedDistribution), values(ImmutableMap.of("B1", 0)), values(ImmutableMap.of("A1", 0)))); }