use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class BaseJdbcConnectorTest method testJoinPushdown.
@Test
public void testJoinPushdown() {
PlanMatchPattern joinOverTableScans = node(JoinNode.class, anyTree(node(TableScanNode.class)), anyTree(node(TableScanNode.class)));
PlanMatchPattern broadcastJoinOverTableScans = node(JoinNode.class, node(TableScanNode.class), exchange(ExchangeNode.Scope.LOCAL, exchange(ExchangeNode.Scope.REMOTE, ExchangeNode.Type.REPLICATE, node(TableScanNode.class))));
Session session = joinPushdownEnabled(getSession());
if (!hasBehavior(SUPPORTS_JOIN_PUSHDOWN)) {
assertThat(query(session, "SELECT r.name, n.name FROM nation n JOIN region r ON n.regionkey = r.regionkey")).isNotFullyPushedDown(joinOverTableScans);
return;
}
// Disable DF here for the sake of negative test cases' expected plan. With DF enabled, some operators return in DF's FilterNode and some do not.
Session withoutDynamicFiltering = Session.builder(session).setSystemProperty("enable_dynamic_filtering", "false").build();
String notDistinctOperator = "IS NOT DISTINCT FROM";
List<String> nonEqualities = Stream.concat(Stream.of(JoinCondition.Operator.values()).filter(operator -> operator != JoinCondition.Operator.EQUAL).map(JoinCondition.Operator::getValue), Stream.of(notDistinctOperator)).collect(toImmutableList());
try (TestTable nationLowercaseTable = new TestTable(// If a connector supports Join pushdown, but does not allow CTAS, we need to make the table creation here overridable.
getQueryRunner()::execute, "nation_lowercase", "AS SELECT nationkey, lower(name) name, regionkey FROM nation")) {
// basic case
assertThat(query(session, "SELECT r.name, n.name FROM nation n JOIN region r ON n.regionkey = r.regionkey")).isFullyPushedDown();
// join over different columns
assertThat(query(session, "SELECT r.name, n.name FROM nation n JOIN region r ON n.nationkey = r.regionkey")).isFullyPushedDown();
// pushdown when using USING
assertThat(query(session, "SELECT r.name, n.name FROM nation n JOIN region r USING(regionkey)")).isFullyPushedDown();
// varchar equality predicate
assertConditionallyPushedDown(session, "SELECT n.name, n2.regionkey FROM nation n JOIN nation n2 ON n.name = n2.name", hasBehavior(SUPPORTS_JOIN_PUSHDOWN_WITH_VARCHAR_EQUALITY), joinOverTableScans);
assertConditionallyPushedDown(session, format("SELECT n.name, nl.regionkey FROM nation n JOIN %s nl ON n.name = nl.name", nationLowercaseTable.getName()), hasBehavior(SUPPORTS_JOIN_PUSHDOWN_WITH_VARCHAR_EQUALITY), joinOverTableScans);
// multiple bigint predicates
assertThat(query(session, "SELECT n.name, c.name FROM nation n JOIN customer c ON n.nationkey = c.nationkey and n.regionkey = c.custkey")).isFullyPushedDown();
// inequality
for (String operator : nonEqualities) {
// bigint inequality predicate
assertThat(query(withoutDynamicFiltering, format("SELECT r.name, n.name FROM nation n JOIN region r ON n.regionkey %s r.regionkey", operator))).isNotFullyPushedDown(broadcastJoinOverTableScans);
// varchar inequality predicate
assertThat(query(withoutDynamicFiltering, format("SELECT n.name, nl.name FROM nation n JOIN %s nl ON n.name %s nl.name", nationLowercaseTable.getName(), operator))).isNotFullyPushedDown(broadcastJoinOverTableScans);
}
// inequality along with an equality, which constitutes an equi-condition and allows filter to remain as part of the Join
for (String operator : nonEqualities) {
assertConditionallyPushedDown(session, format("SELECT n.name, c.name FROM nation n JOIN customer c ON n.nationkey = c.nationkey AND n.regionkey %s c.custkey", operator), expectJoinPushdown(operator), joinOverTableScans);
}
// varchar inequality along with an equality, which constitutes an equi-condition and allows filter to remain as part of the Join
for (String operator : nonEqualities) {
assertConditionallyPushedDown(session, format("SELECT n.name, nl.name FROM nation n JOIN %s nl ON n.regionkey = nl.regionkey AND n.name %s nl.name", nationLowercaseTable.getName(), operator), expectVarcharJoinPushdown(operator), joinOverTableScans);
}
// LEFT JOIN
assertThat(query(session, "SELECT r.name, n.name FROM nation n LEFT JOIN region r ON n.nationkey = r.regionkey")).isFullyPushedDown();
assertThat(query(session, "SELECT r.name, n.name FROM region r LEFT JOIN nation n ON n.nationkey = r.regionkey")).isFullyPushedDown();
// RIGHT JOIN
assertThat(query(session, "SELECT r.name, n.name FROM nation n RIGHT JOIN region r ON n.nationkey = r.regionkey")).isFullyPushedDown();
assertThat(query(session, "SELECT r.name, n.name FROM region r RIGHT JOIN nation n ON n.nationkey = r.regionkey")).isFullyPushedDown();
// FULL JOIN
assertConditionallyPushedDown(session, "SELECT r.name, n.name FROM nation n FULL JOIN region r ON n.nationkey = r.regionkey", hasBehavior(SUPPORTS_JOIN_PUSHDOWN_WITH_FULL_JOIN), joinOverTableScans);
// Join over a (double) predicate
assertThat(query(session, "" + "SELECT c.name, n.name " + "FROM (SELECT * FROM customer WHERE acctbal > 8000) c " + "JOIN nation n ON c.custkey = n.nationkey")).isFullyPushedDown();
// Join over a varchar equality predicate
assertConditionallyPushedDown(session, "SELECT c.name, n.name FROM (SELECT * FROM customer WHERE address = 'TcGe5gaZNgVePxU5kRrvXBfkasDTea') c " + "JOIN nation n ON c.custkey = n.nationkey", hasBehavior(SUPPORTS_PREDICATE_PUSHDOWN_WITH_VARCHAR_EQUALITY), joinOverTableScans);
// Join over a varchar inequality predicate
assertConditionallyPushedDown(session, "SELECT c.name, n.name FROM (SELECT * FROM customer WHERE address < 'TcGe5gaZNgVePxU5kRrvXBfkasDTea') c " + "JOIN nation n ON c.custkey = n.nationkey", hasBehavior(SUPPORTS_PREDICATE_PUSHDOWN_WITH_VARCHAR_INEQUALITY), joinOverTableScans);
// join over aggregation
assertConditionallyPushedDown(session, "SELECT * FROM (SELECT regionkey rk, count(nationkey) c FROM nation GROUP BY regionkey) n " + "JOIN region r ON n.rk = r.regionkey", hasBehavior(SUPPORTS_AGGREGATION_PUSHDOWN), joinOverTableScans);
// join over LIMIT
assertConditionallyPushedDown(session, "SELECT * FROM (SELECT nationkey FROM nation LIMIT 30) n " + "JOIN region r ON n.nationkey = r.regionkey", hasBehavior(SUPPORTS_LIMIT_PUSHDOWN), joinOverTableScans);
// join over TopN
assertConditionallyPushedDown(session, "SELECT * FROM (SELECT nationkey FROM nation ORDER BY regionkey LIMIT 5) n " + "JOIN region r ON n.nationkey = r.regionkey", hasBehavior(SUPPORTS_TOPN_PUSHDOWN), joinOverTableScans);
// join over join
assertThat(query(session, "SELECT * FROM nation n, region r, customer c WHERE n.regionkey = r.regionkey AND r.regionkey = c.custkey")).isFullyPushedDown();
}
}
use of io.trino.sql.planner.assertions.PlanMatchPattern in project trino by trinodb.
the class BaseJdbcConnectorTest method testCaseSensitiveTopNPushdown.
@Test
public void testCaseSensitiveTopNPushdown() {
if (!hasBehavior(SUPPORTS_TOPN_PUSHDOWN)) {
// Covered by testTopNPushdown
return;
}
// topN over varchar/char columns should only be pushed down if the remote systems's sort order matches Trino
boolean expectTopNPushdown = hasBehavior(SUPPORTS_TOPN_PUSHDOWN_WITH_VARCHAR);
PlanMatchPattern topNOverTableScan = node(TopNNode.class, anyTree(node(TableScanNode.class)));
try (TestTable testTable = new TestTable(getQueryRunner()::execute, "test_case_sensitive_topn_pushdown", "(a_string varchar(10), a_char char(10), a_bigint bigint)", List.of("'A', 'A', 1", "'B', 'B', 2", "'a', 'a', 3", "'b', 'b', 4"))) {
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_string ASC LIMIT 2", expectTopNPushdown, topNOverTableScan);
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_string DESC LIMIT 2", expectTopNPushdown, topNOverTableScan);
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_char ASC LIMIT 2", expectTopNPushdown, topNOverTableScan);
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_char DESC LIMIT 2", expectTopNPushdown, topNOverTableScan);
// multiple sort columns with at-least one case-sensitive column
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_bigint, a_char LIMIT 2", expectTopNPushdown, topNOverTableScan);
assertConditionallyOrderedPushedDown(getSession(), "SELECT a_bigint FROM " + testTable.getName() + " ORDER BY a_bigint, a_string DESC LIMIT 2", expectTopNPushdown, topNOverTableScan);
}
}
Aggregations