Change such that filterMany can be included in the main query.

That is, currently a filterMany automatically marks that path as a fetchQuery path. This change turns that off and the filterMany path and predicates can then be included in the main query.

This is better for performance (to include the filterMany path in with the main query) when the query is a findEach and looking to return a large number of results.
This commit is contained in:
rbygrave
2021-04-21 18:57:03 +12:00
parent 42fc419759
commit 74c7268d2f
20 changed files with 179 additions and 61 deletions
@@ -288,7 +288,7 @@ public class DefaultServer_createOrmQueryRequestTest extends BaseTestCase {
}
@Test
public void test_removeJoinToMany_when_filterMany() {
public void test_filterMany_included() {
Query<Order> query = Ebean.find(Order.class)
.fetch("details")
@@ -301,6 +301,40 @@ public class DefaultServer_createOrmQueryRequestTest extends BaseTestCase {
OrmQueryRequest<Order> queryRequest = queryRequest(query);
OrmQueryDetail detail = queryRequest.getQuery().getDetail();
assertThat(detail.getFetchPaths()).containsExactly("details", "details.product", "customer");
}
@Test
public void test_filterMany_excludedByOrdering() {
Query<Order> query = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts")
.fetch("details")
.fetch("details.product")
.filterMany("details").eq("orderQuantity", 10)
.query();
OrmQueryRequest<Order> queryRequest = queryRequest(query);
OrmQueryDetail detail = queryRequest.getQuery().getDetail();
assertThat(detail.getFetchPaths()).containsExactly("customer", "customer.contacts");
}
@Test
public void test_filterMany_excludedExplicitly() {
Query<Order> query = Ebean.find(Order.class)
.fetchQuery("details")
.fetch("details.product")
.fetch("customer")
.fetch("customer.contacts")
.filterMany("details").eq("orderQuantity", 10)
.query();
OrmQueryRequest<Order> queryRequest = queryRequest(query);
OrmQueryDetail detail = queryRequest.getQuery().getDetail();
assertThat(detail.getFetchPaths()).containsExactly("customer", "customer.contacts");
}
@@ -172,7 +172,6 @@ public class TestQueryFilterMany extends BaseTestCase {
LoggedSqlCollector.start();
Query<Customer> query = Ebean.find(Customer.class)
.fetch("orders")
.filterMany("orders").raw("1=0")
.where().isNotEmpty("orders")
.query();
@@ -183,12 +182,10 @@ public class TestQueryFilterMany extends BaseTestCase {
}
List<String> sqlList = LoggedSqlCollector.stop();
assertEquals(2, sqlList.size());
assertThat(sqlList.get(0)).contains("where exists (select 1 from o_order x where x.kcustomer_id = t0.id)");
assertThat(sqlList.get(1)).contains("and 1=0");
assertEquals(1, sqlList.size());
assertThat(sqlList.get(0)).contains("from o_customer t0 left join o_order t1 on t1.kcustomer_id = t0.id and t1.order_date is not null left join o_customer t2 on t2.id = t1.kcustomer_id where exists (select 1 from o_order x where x.kcustomer_id = t0.id) and 1=0 order by t0.id");
}
@Test
public void test_filterMany_in_findCount() {
@@ -212,7 +209,6 @@ public class TestQueryFilterMany extends BaseTestCase {
public void test_filterMany_copy_findList() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Query<Customer> query = Ebean.find(Customer.class)
@@ -222,17 +218,35 @@ public class TestQueryFilterMany extends BaseTestCase {
query.copy().findList();
List<String> sqlList = LoggedSqlCollector.stop();
assertEquals(1, sqlList.size());
assertThat(sqlList.get(0)).contains("from o_customer t0 left join o_order t1 on t1.kcustomer_id = t0.id and t1.order_date is not null left join o_customer t2 on t2.id = t1.kcustomer_id where t1.status in (?) order by t0.id");
}
@Test
public void test_filterMany_fetchQuery() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Query<Customer> query = Ebean.find(Customer.class)
.fetchQuery("orders") // explicitly fetch orders separately
.filterMany("orders").in("status", Order.Status.NEW)
.order().asc("id");
query.findList();
List<String> sqlList = LoggedSqlCollector.stop();
assertEquals(2, sqlList.size());
assertThat(sqlList.get(0)).contains("from o_customer t0");
assertThat(sqlList.get(1)).contains("from o_order t0 join o_customer t1");
assertThat(sqlList.get(1)).contains("from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where t0.order_date is not null and (t0.kcustomer_id) in ");
assertThat(sqlList.get(1)).contains(" and t0.status in ");
}
@Test
public void testDisjunction() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Customer.class)
@@ -243,8 +257,8 @@ public class TestQueryFilterMany extends BaseTestCase {
.findList();
List<String> sql = LoggedSqlCollector.stop();
assertEquals(2, sql.size());
assertSql(sql.get(1)).contains("and (t0.status = ? or t0.order_date = ?");
assertEquals(1, sql.size());
assertSql(sql.get(0)).contains(" from o_customer t0 left join o_order t1 on t1.kcustomer_id = t0.id and t1.order_date is not null left join o_customer t2 on t2.id = t1.kcustomer_id where (t1.status = ? or t1.order_date = ?) order by t0.id");
}
@Test
@@ -259,12 +273,10 @@ public class TestQueryFilterMany extends BaseTestCase {
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(3);
assertSql(sql.get(0)).contains(" from o_customer t0; --bind()");
platformAssertIn(sql.get(1), " from contact t0 where (t0.customer_id)");
assertSql(sql.get(1)).contains(" and t0.first_name is not null");
platformAssertIn(sql.get(2), " from contact_note t0 where (t0.contact_id)");
assertSql(sql.get(2)).contains(" and lower(t0.title) like");
assertThat(sql).hasSize(2);
assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where t1.first_name is not null order by t0.id; --bind()");
platformAssertIn(sql.get(1), " from contact_note t0 where (t0.contact_id)");
assertSql(sql.get(1)).contains(" and lower(t0.title) like");
}
@Test
@@ -280,9 +292,7 @@ public class TestQueryFilterMany extends BaseTestCase {
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(2);
assertSql(sql.get(0)).contains(" from o_customer t0");
assertSql(sql.get(1)).contains("from contact t0 where ");
assertSql(sql.get(1)).contains("and (t0.first_name is not null and lower(t0.email) like ?");
assertThat(sql).hasSize(1);
assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where (t1.first_name is not null and lower(t1.email) like ? escape'|' ) order by t0.id; --bind(rob%)");
}
}