use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
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).addSymbolStatistics(ImmutableMap.of(new Symbol("A1"), new SymbolStatsEstimate(0, 100, 0, 640000, 100))).build();
PlanNodeStatsEstimate valuesB = PlanNodeStatsEstimate.builder().setOutputRowCount(10000).addSymbolStatistics(ImmutableMap.of(new Symbol("B1"), new SymbolStatsEstimate(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.symbol("A1")), p.values(new PlanNodeId("valuesB"), 2, p.symbol("B1")), ImmutableList.of(new EquiJoinClause(p.symbol("A1"), p.symbol("B1"))), ImmutableList.of(p.symbol("A1")), ImmutableList.of(p.symbol("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"), 2, p.symbol("B1")), // matches isAtMostScalar
p.values(new PlanNodeId("valuesA"), p.symbol("A1")), ImmutableList.of(new EquiJoinClause(p.symbol("B1"), p.symbol("A1"))), ImmutableList.of(p.symbol("B1")), ImmutableList.of(p.symbol("A1")), Optional.empty())).overrideStats("valuesA", valuesA).overrideStats("valuesB", valuesB).matches(expectedPlan);
}
use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class TestMergeWindows method testMergeableWindowsAllOptimizers.
/**
* There are two types of tests in here, and they answer two different
* questions about MergeWindows (MW):
* <p>
* 1) Is MW working as it's supposed to be? The tests running the minimal
* set of optimizers can tell us this.
* 2) Has some other optimizer changed the plan in such a way that MW no
* longer merges windows with identical specifications because the plan
* that MW sees cannot be optimized by MW? The test running the full set
* of optimizers answers this, though it isn't actually meaningful unless
* we know the answer to question 1 is "yes".
* <p>
* The tests that use only the minimal set of optimizers are closer to true
* "unit" tests in that they verify the behavior of MW with as few
* external dependencies as possible. Those dependencies to include the
* parser and analyzer, so the phrase "unit" tests should be taken with a
* grain of salt. Using the parser and anayzler instead of creating plan
* nodes by hand does have a couple of advantages over a true unit test:
* 1) The tests are more self-maintaining.
* 2) They're a lot easier to read.
* 3) It's a lot less typing.
* <p>
* The test that runs with all of the optimzers acts as an integration test
* and ensures that MW is effective when run with the complete set of
* optimizers.
*/
@Test
public void testMergeableWindowsAllOptimizers() {
@Language("SQL") String sql = "SELECT " + "SUM(quantity) OVER (PARTITION BY suppkey ORDER BY orderkey ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) sum_quantity_A, " + "SUM(quantity) OVER (PARTITION BY orderkey ORDER BY shipdate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) sum_quantity_B, " + "SUM(discount) OVER (PARTITION BY suppkey ORDER BY orderkey ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) sum_discount_A " + "FROM lineitem";
PlanMatchPattern pattern = anyTree(window(windowMatcherBuilder -> windowMatcherBuilder.specification(specificationA).addFunction(functionCall("sum", COMMON_FRAME, ImmutableList.of(QUANTITY_ALIAS))).addFunction(functionCall("sum", COMMON_FRAME, ImmutableList.of(DISCOUNT_ALIAS))), anyTree(window(windowMatcherBuilder -> windowMatcherBuilder.specification(specificationB).addFunction(functionCall("sum", COMMON_FRAME, ImmutableList.of(QUANTITY_ALIAS))), anyNot(WindowNode.class, // should be anyTree(LINEITEM_TABLESCAN_DOQSS) but anyTree does not handle zero nodes case correctly
LINEITEM_TABLESCAN_DOQSS)))));
assertPlan(sql, pattern);
}
use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class TestReorderWindows method testNonMergeableABAReordersToAABAllOptimizers.
@Test
public void testNonMergeableABAReordersToAABAllOptimizers() {
@Language("SQL") String sql = "select " + "sum(quantity) over(PARTITION BY suppkey ORDER BY orderkey ASC NULLS LAST) sum_quantity_A, " + "avg(discount) over(PARTITION BY partkey ORDER BY receiptdate ASC NULLS LAST) avg_discount_B, " + "min(tax) over(PARTITION BY suppkey ORDER BY shipdate ASC NULLS LAST) min_tax_A " + "from lineitem";
PlanMatchPattern pattern = anyTree(window(windowMatcherBuilder -> windowMatcherBuilder.specification(windowAp).addFunction(functionCall("min", commonFrame, ImmutableList.of(TAX_ALIAS))), project(window(windowMatcherBuilder -> windowMatcherBuilder.specification(windowA).addFunction(functionCall("sum", commonFrame, ImmutableList.of(QUANTITY_ALIAS))), project(window(windowMatcherBuilder -> windowMatcherBuilder.specification(windowB).addFunction(functionCall("avg", commonFrame, ImmutableList.of(DISCOUNT_ALIAS))), anyTree(LINEITEM_TABLESCAN_DOQPRSST)))))));
assertPlan(sql, pattern);
}
use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class TestRuleTester method testReportNoFireWithTableScan.
@Test
public void testReportNoFireWithTableScan() {
try (RuleTester tester = defaultRuleTester()) {
RuleAssert ruleAssert = tester.assertThat(rule("testReportNoFireWithTableScan rule", Pattern.typeOf(PlanNode.class), (node, captures, context) -> Result.empty())).on(p -> p.tableScan(new TableHandle(tester.getCurrentConnectorId(), new TpchTableHandle("sf1", "nation", 1.0), TestingTransactionHandle.create()), List.of(p.symbol("x")), Map.of(p.symbol("x"), new TestingColumnHandle("column"))));
PlanMatchPattern expected = values(List.of("whatever"), List.of());
assertThatThrownBy(() -> ruleAssert.matches(expected)).isInstanceOf(AssertionError.class).hasMessageMatching("testReportNoFireWithTableScan rule did not fire for:\n" + "(?s:.*)" + "\\QEstimates: {rows: 25 (225B), cpu: 225, memory: 0B, network: 0B}\\E\n" + "(?s:.*)");
}
}
use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class TestRuleTester method testReportNoFire.
@Test
public void testReportNoFire() {
try (RuleTester tester = defaultRuleTester()) {
RuleAssert ruleAssert = tester.assertThat(rule("testReportNoFire rule", Pattern.typeOf(PlanNode.class), (node, captures, context) -> Result.empty())).on(p -> p.values(List.of(p.symbol("x")), List.of(List.of(expression("1")))));
PlanMatchPattern expected = values(List.of("whatever"), List.of());
assertThatThrownBy(() -> ruleAssert.matches(expected)).isInstanceOf(AssertionError.class).hasMessageMatching("testReportNoFire rule did not fire for:(?s:.*)");
}
}
Aggregations