Fix for #37 - disjunction expression should not produce inner join - left outer join instead

This commit is contained in:
Rob Bygrave
2014-05-18 21:17:19 +12:00
parent 5b98d82f58
commit 08602afcff
45 changed files with 956 additions and 331 deletions
@@ -24,13 +24,14 @@ public class TestOrderTotalAmountFormula extends BaseTestCase {
.findList();
for (Customer c0 : l0) {
System.out.println("customer: " + c0.getId());
c0.getId();
List<Order> orders = c0.getOrders();
for (Order order : orders) {
System.out.println("... order:" + order);
order.getId();
}
}
}
}
@@ -7,6 +7,9 @@ import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.FetchConfig;
import com.avaje.ebean.Query;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
@@ -14,23 +17,93 @@ import com.avaje.tests.model.basic.ResetBasicData;
public class TestSecondaryQueries extends BaseTestCase {
@Test
public void testQueries() {
public void testSecQueryOneToMany() {
ResetBasicData.reset();
Order testOrder = ResetBasicData.createOrderCustAndOrder("testSecQry10");
Integer custId = testOrder.getCustomer().getId();
Customer cust = Ebean.find(Customer.class).select("name").fetch("contacts", "+query")
.setId(custId).findUnique();
Query<Customer> query = Ebean.find(Customer.class)
.select("name")
.fetch("contacts", "+query")
.setId(custId);
SpiQuery<?> spiQuery = (SpiQuery<?>)query;
spiQuery.setLogSecondaryQuery(true);
Customer cust = query.findUnique();
Assert.assertNotNull(cust);
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("from o_customer t0 where t0.id = ?"));
List<SpiQuery<?>> loggedSecondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertEquals(1, loggedSecondaryQueries.size());
SpiQuery<?> secondaryQuery = loggedSecondaryQueries.get(0);
String secondarySql = secondaryQuery.getGeneratedSql();
Assert.assertTrue(secondarySql.contains("from contact t0 where (t0.customer_id) in (?)"));
}
@Test
public void testManyToOneWithManyPlusOneToMany() {
List<Order> list = Ebean.find(Order.class).select("status").fetch("details", "+query(10)")
.fetch("customer", "+query name, status").fetch("customer.contacts").where()
.eq("status", Order.Status.NEW).findList();
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.select("status")
.fetch("customer", "name, status", new FetchConfig().query())
.fetch("customer.contacts")
.fetch("details", new FetchConfig().query())
.where().eq("status", Order.Status.NEW)
.query();
// .fetch("customer", "+query name, status")
// .fetch("details", "+query(10)")
SpiQuery<?> spiQuery = (SpiQuery<?>)query;
spiQuery.setLogSecondaryQuery(true);
List<Order> list = query.findList();
Assert.assertTrue(list.size() > 0);
for (Order order : list) {
order.getCustomer().getStatus();
}
String generatedSql = spiQuery.getGeneratedSql();
//select t0.id c0, t0.status c1, t0.kcustomer_id c2 from o_order t0 where t0.status = ? ; --bind(NEW)
Assert.assertEquals("select t0.id c0, t0.status c1, t0.kcustomer_id c2 from o_order t0 where t0.status = ? ", generatedSql);
List<SpiQuery<?>> secondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertEquals(2, secondaryQueries.size());
SpiQuery<?> custSecondaryQuery = secondaryQueries.get(0);
String custSecondarySql = custSecondaryQuery.getGeneratedSql();
// select t0.id c0, t0.name c1, t0.status c2,
// t1.id c3, t1.first_name c4, t1.last_name c5, t1.phone c6, t1.mobile c7, t1.email c8, t1.cretime c9, t1.updtime c10, t1.customer_id c11, t1.group_id c12
// from o_customer t0
// left outer join contact t1 on t1.customer_id = t0.id
// where t0.id = ? order by t0.id; --bind(1)
Assert.assertTrue(custSecondarySql.contains("from o_customer t0 "));
Assert.assertTrue(custSecondarySql.contains("left outer join contact t1 on t1.customer_id = t0.id "));
Assert.assertTrue(custSecondarySql.contains("where t0.id "));
SpiQuery<?> orderDetailsSecondaryQuery = secondaryQueries.get(1);
String ordSecondarySql = orderDetailsSecondaryQuery.getGeneratedSql();
// select ...
// from o_order_detail t0
// where (t0.order_id) in (?,?,?,?,?) ; --bind(1,4,1,1,1)
Assert.assertTrue(ordSecondarySql.contains(" from o_order_detail t0 where (t0.order_id) in (?"));
}
}
@@ -28,7 +28,7 @@ public class Contact {
String mobile;
String email;
@ManyToOne
@ManyToOne(optional=false)
Customer customer;
@ManyToOne(optional=true)
@@ -1,7 +1,7 @@
package com.avaje.tests.query;
import junit.framework.Assert;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
@@ -18,18 +18,18 @@ public class TestIContains extends BaseTestCase {
ResetBasicData.reset();
// case insensitive
Query<Customer> q0 = Ebean.find(Customer.class).where().icontains("name", "Rob").query();
Query<Customer> query = Ebean.find(Customer.class).where().icontains("name", "Rob").query();
q0.findList();
String generatedSql = q0.getGeneratedSql();
query.findList();
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("lower(t0.name)"));
// not case insensitive
q0 = Ebean.find(Customer.class).where().contains("name", "Rob").query();
query = Ebean.find(Customer.class).where().contains("name", "Rob").query();
q0.findList();
generatedSql = q0.getGeneratedSql();
query.findList();
generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains(" t0.name "));
@@ -0,0 +1,63 @@
package com.avaje.tests.query;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestImplicitJoinOnParentRelatonship extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.select("id, name")
.where().eq("orders.details.product.name", "Desk")
.query();
query.findList();
String expectedSql = "select distinct t0.id c0, t0.name c1 from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id join o_order_detail u2 on u2.order_id = u1.id join o_product u3 on u3.id = u2.product_id where u3.name = ? ";
Assert.assertEquals(expectedSql, query.getGeneratedSql());
// select distinct t0.id c0, t0.name c1
// from o_customer t0
// join o_order u1 on u1.kcustomer_id = t0.id
// join o_order_detail u2 on u2.order_id = u1.id
// join o_product u3 on u3.id = u2.product_id
// where u3.name = ?
}
@Test
public void testWithDisjunction() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.select("id, name")
.where().disjunction().eq("orders.details.product.name", "Desk").eq("id", 4).endJunction()
.query();
query.findList();
String expectedSql = "select distinct t0.id c0, t0.name c1 from o_customer t0 left outer join o_order u1 on u1.kcustomer_id = t0.id left outer join o_order_detail u2 on u2.order_id = u1.id left outer join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
Assert.assertEquals(expectedSql, query.getGeneratedSql());
// select distinct t0.id c0, t0.name c1
// from o_customer t0 select distinct t0.id c0, t0.name c1 from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id join o_order_detail u2 on u2.order_id = u1.id join o_product u3 on u3.id = u2.product_id where u3.name = ?
// left outer join o_order u1 on u1.kcustomer_id = t0.id
// left outer join o_order_detail u2 on u2.order_id = u1.id
// left outer join o_product u3 on u3.id = u2.product_id
// where (u3.name = ? or t0.id = ? ) ; --bind(Desk,4)
}
}
@@ -1,38 +0,0 @@
package com.avaje.tests.query;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.OrderShipment;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestJoinQuery extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<Customer> query = Ebean.find(Customer.class).setAutofetch(false).fetch("orders")
.fetch("orders.details");
List<Customer> list = query.findList();
Assert.assertTrue("has rows", list.size() > 0);
// test that join to order.details is not included
Query<OrderShipment> shipQuery = Ebean.find(OrderShipment.class).setAutofetch(false)
.fetch("order").fetch("order.details");
List<OrderShipment> shipList = shipQuery.findList();
Assert.assertTrue("has rows", shipList.size() > 0);
}
}
@@ -1,48 +0,0 @@
package com.avaje.tests.query;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.PagingList;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestPagingListLoop extends BaseTestCase {
@Test
public void test() throws InterruptedException, ExecutionException {
// boolean autoRunTest = false;
// if (!autoRunTest){
// // we only want to run this test manually.
// return;
// }
try {
ResetBasicData.reset();
for (int i = 0; i < 50; i++) {
PagingList<Customer> pagingList = Ebean.find(Customer.class).findPagingList(10);
pagingList.getFutureRowCount();// .get();
// createLeak();
Thread.sleep(10);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// private void createLeak() {
//
// // create a transaction we never close ...
// // ... a connection pool leak
// Ebean.getServer(null).createTransaction();
// }
}
@@ -0,0 +1,162 @@
package com.avaje.tests.query;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.tests.model.basic.Contact;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.OrderShipment;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestQueryFetchManyTwoDeep extends BaseTestCase {
@Test
public void testFetchOneToManyWithChildOneToMany() {
ResetBasicData.reset();
// test that join to order.details is not included in the initial query (included in query join)
Query<Customer> query = Ebean.find(Customer.class)
.setAutofetch(false)
.fetch("orders")
.fetch("orders.details");
SpiQuery<?> spiQuery = (SpiQuery<?>)query;
spiQuery.setLogSecondaryQuery(true);
List<Customer> list = query.findList();
Assert.assertTrue("has rows", list.size() > 0);
Assert.assertTrue(query.getGeneratedSql().contains("from o_customer t0 "));
Assert.assertTrue(query.getGeneratedSql().contains("left outer join o_order t1 on t1.kcustomer_id = t0.id"));
Assert.assertTrue(query.getGeneratedSql().contains("left outer join o_customer t2 on t2.id = t1.kcustomer_id"));
Assert.assertFalse(query.getGeneratedSql().contains("join or_order_ship"));
//select t0.id c0, t0.status c1, t0.name c2, t0.smallnote c3, t0.anniversary c4, t0.cretime c5, t0.updtime c6, t0.billing_address_id c7, t0.shipping_address_id c8, t1.id c9, t1.status c10, t1.order_date c11, t1.ship_date c12,
// t2.name c13, t1.cretime c14, t1.updtime c15, t1.kcustomer_id c16
// from o_customer t0
// left outer join o_order t1 on t1.kcustomer_id = t0.id
// left outer join o_customer t2 on t2.id = t1.kcustomer_id
// where t1.order_date is not null order by t0.id; --bind()
List<SpiQuery<?>> secondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertNotNull(secondaryQueries);
Assert.assertEquals(1, secondaryQueries.size());
SpiQuery<?> secondaryQuery = secondaryQueries.get(0);
String secondarySql = secondaryQuery.getGeneratedSql();
Assert.assertTrue(secondarySql.contains("from o_order_detail t0 where (t0.order_id) in"));
// select t0.order_id c0, t0.id c1, t0.order_qty c2, t0.ship_qty c3, t0.unit_price c4, t0.cretime c5, t0.updtime c6, t0.order_id c7, t0.product_id c8
// from o_order_detail t0
// where (t0.order_id) in (?,?,?,?,?)
}
@Test
public void testFetchOptionalManyToOneThenDownToMany() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<OrderShipment> shipQuery = Ebean.find(OrderShipment.class)
.setAutofetch(false)
.fetch("order")
.fetch("order.details");
List<OrderShipment> shipList = shipQuery.findList();
Assert.assertTrue("has rows", shipList.size() > 0);
String generatedSql = shipQuery.getGeneratedSql();
// select ...
// from or_order_ship t0
// left outer join o_order t1 on t1.id = t0.order_id
// left outer join o_customer t3 on t3.id = t1.kcustomer_id
// left outer join o_order_detail t2 on t2.order_id = t1.id
// where t2.id > 0 ; --bind()
Assert.assertTrue(generatedSql.contains("from or_order_ship t0"));
// Relationship from OrderShipment to Order is optional so outer join here
Assert.assertTrue(generatedSql.contains("left outer join o_order t1 on t1.id = t0.order_id"));
Assert.assertTrue(generatedSql.contains("left outer join o_customer t3 on t3.id = t1.kcustomer_id"));
Assert.assertTrue(generatedSql.contains("left outer join o_order_detail t2 on t2.order_id = t1.id"));
// If OrderShipment to Order is not optional you get inner joins up to o_order_detail (which is a many)
// select ...
// from or_order_ship t0
// join o_order t1 on t1.id = t0.order_id
// join o_customer t3 on t3.id = t1.kcustomer_id
// left outer join o_order_detail t2 on t2.order_id = t1.id
// where t2.id > 0 ; --bind()
}
@Test
public void testFetchMandatoryManyToOneThenDownToMany() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<Contact> query = Ebean.find(Contact.class)
.setAutofetch(false)
.fetch("customer")
.fetch("customer.orders");
List<Contact> shipList = query.findList();
Assert.assertTrue("has rows", shipList.size() > 0);
String generatedSql = query.getGeneratedSql();
// select ...
// from contact t0
// join o_customer t1 on t1.id = t0.customer_id
// left outer join o_order t2 on t2.kcustomer_id = t1.id
// left outer join o_customer t3 on t3.id = t2.kcustomer_id
// where t2.order_date is not null ; --bind()
Assert.assertTrue(generatedSql.contains("from contact t0 "));
// Relationship from Contact to Customer is mandatory so inner join here
Assert.assertTrue(generatedSql.contains("join o_customer t1 on t1.id = t0.customer_id"));
// outer join on many relationship 'orders'
Assert.assertTrue(generatedSql.contains("left outer join o_order t2 on t2.kcustomer_id = t1.id"));
}
@Test
public void testFetchMandatoryManyToOneWithPredicate() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<Contact> query = Ebean.find(Contact.class)
.setAutofetch(false)
.fetch("customer")
.where().ilike("customer.name", "Rob%")
.query();
List<Contact> list = query.findList();
Assert.assertTrue("has rows", list.size() > 0);
String generatedSql = query.getGeneratedSql();
// select ...
// from contact t0
// join o_customer t1 on t1.id = t0.customer_id
// where lower(t1.name) like ? ; --bind(rob%)
Assert.assertTrue(generatedSql.contains("from contact t0 "));
Assert.assertTrue(generatedSql.contains("join o_customer t1 on t1.id = t0.customer_id"));
Assert.assertTrue(generatedSql.contains("where lower(t1.name) like ?"));
}
}
@@ -6,7 +6,6 @@ import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.FetchConfig;
import com.avaje.ebean.Query;
import com.avaje.ebean.QueryIterator;
import com.avaje.tests.model.basic.Customer;
@@ -2,8 +2,7 @@ package com.avaje.tests.query;
import java.util.List;
import junit.framework.Assert;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
@@ -1,4 +1,4 @@
package com.avaje.tests.query;
package com.avaje.tests.query.joins;
import java.util.List;
@@ -0,0 +1,61 @@
package com.avaje.tests.query.joins;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.UUOne;
import com.avaje.tests.model.basic.UUTwo;
public class TestDisjunctWhereOuterOnMany extends BaseTestCase {
@Test
public void test() {
// setup
UUOne master1 = new UUOne();
master1.setName("testDisjOuter_1_name");
UUTwo detail1 = new UUTwo();
detail1.setMaster(master1);
detail1.setName("testDisjOuter_CHILD_1");
UUOne master2 = new UUOne();
master2.setName("testDisjOuter_2_name");
Ebean.save(master1);
Ebean.save(detail1);
Ebean.save(master2);
// Have outer join so that "testDisjOuter_2_name" is found
Query<UUOne> query = Ebean.find(UUOne.class)
.where().disjunction()
.eq("name", "testDisjOuter_2_name")
.eq("comments.name", "testDisjOuter_CHILD_1")
.endJunction()
.query();
List<UUOne> list = query.findList();
int rowCount = query.findRowCount();
// select distinct t0.id c0, t0.name c1
// from uuone t0
// join uutwo u1 on u1.master_id = t0.id
// left outer join uutwo t1 on t1.master_id = t0.id
// where (t0.name = ? or u1.name = ? ) ;
// --bind(testDisjOuter_2_name,testDisjOuter_CHILD_1)
Assert.assertEquals(2, list.size());
Assert.assertEquals(2, rowCount);
String expectedSql = "select distinct t0.id c0, t0.name c1 from uuone t0 left outer join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ? ) ";
Assert.assertEquals(expectedSql, query.getGeneratedSql());
}
}
@@ -1,4 +1,4 @@
package com.avaje.tests.query;
package com.avaje.tests.query.joins;
import java.util.List;
@@ -30,7 +30,15 @@ public class TestQueryJoinManyNonRoot extends BaseTestCase {
Assert.assertTrue(list.size() > 0);
Assert.assertTrue(sql.contains("join o_customer t1 on t1.id "));
Assert.assertTrue(sql.contains("left outer join contact t2 on"));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6,
// t1.id c7, t1.status c8, t1.name c9, t1.smallnote c10, t1.anniversary c11, t1.cretime c12, t1.updtime c13, t1.billing_address_id c14, t1.shipping_address_id c15,
// t2.id c16, t2.first_name c17, t2.last_name c18, t2.phone c19, t2.mobile c20, t2.email c21, t2.cretime c22, t2.updtime c23, t2.customer_id c24, t2.group_id c25
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// left outer join contact t2 on t2.customer_id = t1.id
// where t0.id > ? ; --bind(0)
}
@Test
@@ -1,4 +1,4 @@
package com.avaje.tests.query;
package com.avaje.tests.query.joins;
import java.util.List;
@@ -28,7 +28,8 @@ public class TestQueryJoinQueryNonRoot extends BaseTestCase {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class).fetch("customer")
List<Order> list = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts", "firstName", new FetchConfig().query().lazy(10))
.fetch("customer.contacts.group")
.where().lt("id", 3).findList();
@@ -52,4 +53,6 @@ public class TestQueryJoinQueryNonRoot extends BaseTestCase {
// Assert.assertTrue(list2.size() > 0);
}
}
@@ -0,0 +1,94 @@
package com.avaje.tests.query.joins;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestQueryManyToOneWhereClauseJoin extends BaseTestCase {
/**
* Testing 'where join' created for a ManyToOne relationship.
*/
@Test
public void testJoin() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where().ilike("customer.name", "rob%")
.query();
query.findList();
//select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
String expectedSql = "from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where lower(t1.name) like ? ";
Assert.assertTrue(query.getGeneratedSql().contains(expectedSql));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// where lower(t1.name) like ? ; --bind(rob%)
}
/**
* Although this is a disjunction it is on a ManyToOne so the 'default' join type is still fine.
*/
@Test
public void testDisjunctionOnManyToOneJoin() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where().disjunction().ilike("customer.name", "rob%").gt("id", 1).endJunction()
.query();
query.findList();
//select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
String expectedSql = "from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where (lower(t1.name) like ? or t0.id > ? ) ";
Assert.assertTrue(query.getGeneratedSql().contains(expectedSql));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// where (lower(t1.name) like ? or t0.id > ? ) ; --bind(rob%,1)
}
/**
* Testing ManyToOne relationship with predicate and fetch.
*/
@Test
public void testWhereAndFetch() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts")
.where().ilike("customer.name", "rob%")
.query();
query.findList();
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id"));
Assert.assertTrue(generatedSql.contains("left outer join contact t2 on t2.customer_id = t1.id"));
Assert.assertTrue(generatedSql.contains("where lower(t1.name) like ?"));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6,
// t1.id c7, t1.status c8, t1.name c9, t1.smallnote c10, t1.anniversary c11, t1.cretime c12, t1.updtime c13, t1.billing_address_id c14, t1.shipping_address_id c15,
// t2.id c16, t2.first_name c17, t2.last_name c18, t2.phone c19, t2.mobile c20, t2.email c21, t2.cretime c22, t2.updtime c23, t2.customer_id c24, t2.group_id c25
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// left outer join contact t2 on t2.customer_id = t1.id
// where lower(t1.name) like ? ; --bind(rob%)
}
}