diff --git a/src/main/java/io/ebeaninternal/api/SpiQuery.java b/src/main/java/io/ebeaninternal/api/SpiQuery.java
index 3ab778f71..5dd405414 100644
--- a/src/main/java/io/ebeaninternal/api/SpiQuery.java
+++ b/src/main/java/io/ebeaninternal/api/SpiQuery.java
@@ -674,6 +674,11 @@ public interface SpiQuery extends Query {
*/
boolean isDistinctQuery();
+ /**
+ * Return true if this was internally set to sql distinct (ie. many where predicate).
+ */
+ boolean isSqlDistinct();
+
/**
* Return true if this query has been specified by a user to use DISTINCT.
*/
diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
index 45fff963c..9e1f3c1fa 100644
--- a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
+++ b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java
@@ -1,5 +1,6 @@
package io.ebeaninternal.server.query;
+import io.ebean.Platform;
import io.ebean.RawSql;
import io.ebean.RawSql.ColumnMapping;
import io.ebean.RawSql.ColumnMapping.Column;
@@ -39,8 +40,8 @@ import java.util.List;
*/
class CQueryBuilder {
- private final String tableAliasPlaceHolder;
- private final String columnAliasPrefix;
+ protected final String tableAliasPlaceHolder;
+ protected final String columnAliasPrefix;
private final SqlLimiter sqlLimiter;
@@ -110,7 +111,7 @@ class CQueryBuilder {
predicates.prepare(true);
- SqlTree sqlTree = createSqlTree(request, predicates, getHistorySupport(query), getDraftSupport(query));
+ SqlTree sqlTree = createSqlTree(request, predicates);
String sql;
if (type.equals("Delete")) {
@@ -186,7 +187,7 @@ class CQueryBuilder {
// use RawSql or generated Sql
predicates.prepare(true);
- SqlTree sqlTree = createSqlTree(request, predicates, getHistorySupport(query), getDraftSupport(query));
+ SqlTree sqlTree = createSqlTree(request, predicates);
SqlLimitResponse s = buildSql(null, request, predicates, sqlTree);
queryPlan = new CQueryPlan(request, s.getSql(), sqlTree, false, s.isIncludesRowNumberColumn(), predicates.getLogWhereSql());
@@ -206,14 +207,14 @@ class CQueryBuilder {
/**
* Return the history support if this query needs it (is a 'as of' type query).
*/
- private CQueryHistorySupport getHistorySupport(SpiQuery query) {
+ CQueryHistorySupport getHistorySupport(SpiQuery query) {
return query.getTemporalMode() != SpiQuery.TemporalMode.CURRENT ? historySupport : null;
}
/**
* Return the draft support (or null) for a 'asDraft' query.
*/
- private CQueryDraftSupport getDraftSupport(SpiQuery query) {
+ CQueryDraftSupport getDraftSupport(SpiQuery query) {
return query.getTemporalMode() == SpiQuery.TemporalMode.DRAFT ? draftSupport : null;
}
@@ -248,7 +249,7 @@ class CQueryBuilder {
predicates.prepare(true);
- SqlTree sqlTree = createSqlTree(request, predicates, getHistorySupport(query), getDraftSupport(query));
+ SqlTree sqlTree = createSqlTree(request, predicates);
if (SpiQuery.TemporalMode.CURRENT == query.getTemporalMode()) {
sqlTree.addSoftDeletePredicate(query);
}
@@ -306,7 +307,7 @@ class CQueryBuilder {
// Build the tree structure that represents the query.
SpiQuery query = request.getQuery();
- SqlTree sqlTree = createSqlTree(request, predicates, getHistorySupport(query), getDraftSupport(query));
+ SqlTree sqlTree = createSqlTree(request, predicates);
if (query.isAsOfQuery()) {
sqlTree.addAsOfTableAlias(query);
} else if (SpiQuery.TemporalMode.CURRENT == query.getTemporalMode()) {
@@ -347,7 +348,7 @@ class CQueryBuilder {
* order by clauses that are not already included for the select clause.
*
*/
- private SqlTree createSqlTree(OrmQueryRequest> request, CQueryPredicates predicates, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
+ private SqlTree createSqlTree(OrmQueryRequest> request, CQueryPredicates predicates) {
if (request.isNativeSql()) {
return createNativeSqlTree(request, predicates);
@@ -355,7 +356,7 @@ class CQueryBuilder {
if (request.isRawSql()) {
return createRawSqlSqlTree(request, predicates);
}
- return new SqlTreeBuilder(tableAliasPlaceHolder, columnAliasPrefix, request, predicates, historySupport, draftSupport).build();
+ return new SqlTreeBuilder(this, request, predicates).build();
}
/**
@@ -517,13 +518,18 @@ class CQueryBuilder {
sb.append("select ");
if (query.isDistinctQuery()) {
sb.append("distinct ");
+ String distinctOn = select.getDistinctOn();
+ if (distinctOn != null) {
+ sb.append("on (");
+ sb.append(distinctOn).append(") ");
+ }
}
}
sb.append(select.getSelectSql());
if (query.isDistinctQuery() && dbOrderBy != null && !query.isSingleAttribute()) {
// add the orderBy columns to the select clause (due to distinct)
- sb.append(", ").append(convertDbOrderByForSelect(dbOrderBy));
+ sb.append(", ").append(DbOrderByTrim.trim(dbOrderBy));
}
}
@@ -639,17 +645,11 @@ class CQueryBuilder {
return true;
}
- /**
- * Convert the dbOrderBy clause to be safe for adding to select. This is done when 'distinct' is
- * used.
- */
- private String convertDbOrderByForSelect(String dbOrderBy) {
- // just remove the ASC and DESC keywords
- return dbOrderBy.replaceAll("(?i)\\b asc\\b|\\b desc\\b", "");
- }
-
private boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
+ boolean isPlatformDistinctOn() {
+ return dbPlatform.isPlatform(Platform.POSTGRES);
+ }
}
diff --git a/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java b/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java
index 4a271255d..8f4ce4aee 100644
--- a/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java
+++ b/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java
@@ -54,12 +54,12 @@ class DefaultDbSqlContext implements DbSqlContext {
/**
* Construct for SELECT clause (with column alias settings).
*/
- DefaultDbSqlContext(SqlTreeAlias alias, String tableAliasPlaceHolder,
- String columnAliasPrefix, boolean alwaysUseColumnAlias, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
+ DefaultDbSqlContext(SqlTreeAlias alias, CQueryBuilder builder,
+ boolean alwaysUseColumnAlias, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
this.alias = alias;
- this.tableAliasPlaceHolder = tableAliasPlaceHolder;
- this.columnAliasPrefix = columnAliasPrefix;
+ this.tableAliasPlaceHolder = builder.tableAliasPlaceHolder;
+ this.columnAliasPrefix = builder.columnAliasPrefix;
this.useColumnAlias = alwaysUseColumnAlias;
this.draftSupport = draftSupport;
this.historySupport = historySupport;
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTree.java b/src/main/java/io/ebeaninternal/server/query/SqlTree.java
index a6a81459f..8e7d1a2ee 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTree.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTree.java
@@ -27,6 +27,8 @@ class SqlTree {
*/
private final String summary;
+ private final String distinctOn;
+
private final String selectSql;
private final String fromSql;
@@ -48,11 +50,12 @@ class SqlTree {
/**
* Create the SqlSelectClause.
*/
- SqlTree(String summary, SqlTreeNode rootNode, String selectSql, String fromSql, String groupBy, String inheritanceWhereSql,
+ SqlTree(String summary, SqlTreeNode rootNode, String distinctOn, String selectSql, String fromSql, String groupBy, String inheritanceWhereSql,
BeanProperty[] encryptedProps, BeanPropertyAssocMany> manyProperty, Set includes, boolean includeJoins) {
this.summary = summary;
this.rootNode = rootNode;
+ this.distinctOn = distinctOn;
this.selectSql = selectSql;
this.fromSql = fromSql;
this.groupBy = groupBy;
@@ -100,6 +103,10 @@ class SqlTree {
return includes;
}
+ String getDistinctOn() {
+ return distinctOn;
+ }
+
/**
* Return the String for the actual SQL.
*/
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java
index 864e8819b..d202f9572 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java
@@ -46,6 +46,7 @@ public class SqlTreeBuilder {
private final boolean subQuery;
+ private final boolean distinctOnPlatform;
/**
* Property if resultSet contains master and detail rows.
*/
@@ -85,6 +86,7 @@ public class SqlTreeBuilder {
this.disableLazyLoad = request.getQuery().isDisableLazyLoading();
this.query = null;
this.subQuery = false;
+ this.distinctOnPlatform = false;
this.queryDetail = queryDetail;
this.predicates = predicates;
this.temporalMode = SpiQuery.TemporalMode.CURRENT;
@@ -99,8 +101,7 @@ public class SqlTreeBuilder {
* support the where and/or order by clause. If so these extra joins are added
* to the root node.
*/
- public SqlTreeBuilder(String tableAliasPlaceHolder, String columnAliasPrefix,
- OrmQueryRequest> request, CQueryPredicates predicates, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
+ public SqlTreeBuilder(CQueryBuilder builder, OrmQueryRequest> request, CQueryPredicates predicates) {
this.rawSql = false;
this.rawNoId = false;
@@ -115,7 +116,11 @@ public class SqlTreeBuilder {
this.predicates = predicates;
this.alias = new SqlTreeAlias(request.getBaseTableAlias());
- this.ctx = new DefaultDbSqlContext(alias, tableAliasPlaceHolder, columnAliasPrefix, !subQuery, historySupport, draftSupport);
+ this.distinctOnPlatform = builder.isPlatformDistinctOn();
+
+ CQueryHistorySupport historySupport = builder.getHistorySupport(query);
+ CQueryDraftSupport draftSupport = builder.getDraftSupport(query);
+ this.ctx = new DefaultDbSqlContext(alias, builder, !subQuery, historySupport, draftSupport);
}
/**
@@ -129,6 +134,7 @@ public class SqlTreeBuilder {
buildRoot(desc);
// build the actual String
+ String distinctOn = null;
String selectSql = null;
String fromSql = null;
String inheritanceWhereSql = null;
@@ -139,12 +145,13 @@ public class SqlTreeBuilder {
fromSql = buildFromClause();
inheritanceWhereSql = buildWhereClause();
groupBy = buildGroupByClause();
+ distinctOn = buildDistinctOn();
encryptedProps = ctx.getEncryptedProps();
}
boolean includeJoins = alias != null && alias.isIncludeJoins();
- return new SqlTree(summary.toString(), rootNode, selectSql, fromSql, groupBy, inheritanceWhereSql, encryptedProps,
+ return new SqlTree(summary.toString(), rootNode, distinctOn, selectSql, fromSql, groupBy, inheritanceWhereSql, encryptedProps,
manyProperty, queryDetail.getFetchPaths(), includeJoins);
}
@@ -164,18 +171,46 @@ public class SqlTreeBuilder {
}
ctx.startGroupBy();
rootNode.appendGroupBy(ctx, subQuery);
- String groupBy = ctx.getContent();
- return trimComma(groupBy);
+ return trimComma(ctx.getContent());
+ }
+
+ private String buildDistinctOn() {
+
+ if (rawSql || !distinctOnPlatform || !query.isSqlDistinct() || Type.COUNT == query.getType()) {
+ return null;
+ }
+ ctx.startGroupBy();
+ rootNode.appendDistinctOn(ctx, subQuery);
+ String idCols = trimComma(ctx.getContent());
+ return idCols == null ? null : mergeOnDistinct(idCols, predicates.getDbOrderBy());
+ }
+
+ static String mergeOnDistinct(String idCols, String dbOrderBy) {
+ if (dbOrderBy == null) {
+ return idCols;
+ }
+ dbOrderBy = DbOrderByTrim.trim(dbOrderBy);
+ StringBuilder sb = new StringBuilder(dbOrderBy.length() + idCols.length() + 2);
+ sb.append(dbOrderBy);
+ String[] split = idCols.split(",");
+ for (String col : split) {
+ col = col.trim();
+ if (!dbOrderBy.contains(col)) {
+ sb.append(", ").append(col);
+ }
+ }
+ return sb.toString();
}
/**
* Trim the first comma.
*/
private String trimComma(String groupBy) {
- if (groupBy.length() >= SqlTreeNode.COMMA.length()) {
- groupBy = groupBy.substring(SqlTreeNode.COMMA.length());
+ if (groupBy.length() < SqlTreeNode.COMMA.length()) {
+ return null;
+ } else {
+ return groupBy.substring(SqlTreeNode.COMMA.length());
}
- return groupBy;
}
private String buildWhereClause() {
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java
index 8787caba6..27e60cbc8 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNode.java
@@ -25,8 +25,12 @@ interface SqlTreeNode {
boolean isAggregation();
/**
- * Append the required column information to the SELECT part of the sql
- * statement.
+ * Append the distinct on clause (Id properties of root and many root only).
+ */
+ void appendDistinctOn(DbSqlContext ctx, boolean subQuery);
+
+ /**
+ * Append the required column information to the select clause.
*/
void appendSelect(DbSqlContext ctx, boolean subQuery);
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java
index c2ed06810..1335f60ea 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java
@@ -33,7 +33,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
protected final BeanDescriptor> desc;
- private final IdBinder idBinder;
+ protected final IdBinder idBinder;
/**
* The children which will be other SelectBean or SelectProxyBean.
@@ -57,7 +57,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
/**
* False if report bean and has no id property.
*/
- private final boolean readId;
+ protected final boolean readId;
private final boolean disableLazyLoad;
@@ -171,10 +171,10 @@ class SqlTreeNodeBean implements SqlTreeNode {
property.buildRawSqlSelectChain(prefix, selectChain);
}
// recursively continue reading...
- for (SqlTreeNode aChildren : children) {
+ for (SqlTreeNode child : children) {
// read each child... and let them set their
// values back to this localBean
- aChildren.buildRawSqlSelectChain(selectChain);
+ child.buildRawSqlSelectChain(selectChain);
}
}
@@ -401,6 +401,15 @@ class SqlTreeNodeBean implements SqlTreeNode {
ctx.popJoin();
}
+ /**
+ * Append the property columns to the buffer.
+ */
+ public void appendDistinctOn(DbSqlContext ctx, boolean subQuery) {
+ for (SqlTreeNode child : children) {
+ child.appendDistinctOn(ctx, subQuery);
+ }
+ }
+
/**
* Append the property columns to the buffer.
*/
@@ -451,8 +460,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
}
}
- private void appendSelectId(DbSqlContext ctx, BeanProperty prop) {
-
+ protected void appendSelectId(DbSqlContext ctx, BeanProperty prop) {
if (prop != null) {
prop.appendSelect(ctx, false);
}
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java
index 1caaea1aa..71a06be0a 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java
@@ -56,6 +56,11 @@ class SqlTreeNodeExtraJoin implements SqlTreeNode {
// nothing to do here
}
+ @Override
+ public void appendDistinctOn(DbSqlContext ctx, boolean subQuery) {
+ // do nothing here ...
+ }
+
@Override
public boolean isAggregation() {
return false;
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyRoot.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyRoot.java
index 5a38ab192..0bfe6ff90 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyRoot.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyRoot.java
@@ -19,6 +19,15 @@ final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
this.manyProp = prop;
}
+ /**
+ * Append the property columns to the buffer.
+ */
+ public void appendDistinctOn(DbSqlContext ctx, boolean subQuery) {
+ ctx.pushTableAlias(prefix);
+ appendSelectId(ctx, idBinder.getBeanProperty());
+ ctx.popTableAlias();
+ }
+
@Override
public EntityBean load(DbReadContext cquery, EntityBean parentBean, EntityBean contextParent) throws SQLException {
// pass in null for parentBean because the localBean
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java
index 165aef3e9..ff09a1e85 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java
@@ -60,6 +60,11 @@ class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
return false;
}
+ @Override
+ public void appendDistinctOn(DbSqlContext ctx, boolean subQuery) {
+ // do nothing here ...
+ }
+
@Override
public void appendGroupBy(DbSqlContext ctx, boolean subQuery) {
// do nothing here
diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java
index e8e23ec8b..112cf16cf 100644
--- a/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java
+++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java
@@ -25,6 +25,18 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean {
this.includeJoin = includeJoin;
}
+ /**
+ * Append the property columns to the buffer.
+ */
+ public void appendDistinctOn(DbSqlContext ctx, boolean subQuery) {
+ if (readId) {
+ ctx.pushTableAlias(prefix);
+ appendSelectId(ctx, idBinder.getBeanProperty());
+ ctx.popTableAlias();
+ super.appendDistinctOn(ctx, subQuery);
+ }
+ }
+
/**
* Set AsOf support (at root level).
*/
diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
index 81fc58b97..7a7644226 100644
--- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
+++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
@@ -1351,6 +1351,11 @@ public class DefaultOrmQuery implements SpiQuery {
return distinct || sqlDistinct;
}
+ @Override
+ public boolean isSqlDistinct() {
+ return sqlDistinct;
+ }
+
/**
* Internally set to use SQL DISTINCT on the query but still have id property included.
*/
diff --git a/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java b/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java
index f0c22fdd6..3222af9d0 100644
--- a/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java
+++ b/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java
@@ -94,7 +94,12 @@ public class IsEmptyExpressionQueryTest extends BaseTestCase {
.query();
query.findList();
- assertThat(sqlOf(query)).contains("select distinct t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where not exists (select 1 from contact_note where contact_id = u1.id)");
+ if (isPostgres()) {
+ assertThat(sqlOf(query)).contains("select distinct on (t0.id) t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where not exists (select 1 from contact_note where contact_id = u1.id)");
+
+ } else {
+ assertThat(sqlOf(query)).contains("select distinct t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where not exists (select 1 from contact_note where contact_id = u1.id)");
+ }
}
@Test
@@ -108,7 +113,12 @@ public class IsEmptyExpressionQueryTest extends BaseTestCase {
.query();
query.findList();
- assertThat(sqlOf(query)).contains("select distinct t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where exists (select 1 from contact_note where contact_id = u1.id)");
+ if (isPostgres()) {
+ assertThat(sqlOf(query)).contains("select distinct on (t0.id) t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where exists (select 1 from contact_note where contact_id = u1.id)");
+
+ } else {
+ assertThat(sqlOf(query)).contains("select distinct t0.id from o_customer t0 join contact u1 on u1.customer_id = t0.id where exists (select 1 from contact_note where contact_id = u1.id)");
+ }
}
}
diff --git a/src/test/java/org/tests/json/TestJsonMapBasic.java b/src/test/java/org/tests/json/TestJsonMapBasic.java
index 202205dd8..2edad3554 100644
--- a/src/test/java/org/tests/json/TestJsonMapBasic.java
+++ b/src/test/java/org/tests/json/TestJsonMapBasic.java
@@ -2,17 +2,52 @@ package org.tests.json;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
+import io.ebean.Query;
import io.ebean.text.json.EJson;
import org.tests.model.json.EBasicJsonMap;
import org.junit.Test;
+import org.tests.model.json.EBasicJsonMapDetail;
import java.io.IOException;
import java.util.Map;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
public class TestJsonMapBasic extends BaseTestCase {
+ @Test
+ public void whereManyPredicate() {
+
+ if (!isPostgres()) {
+ // testing postgres specific select distinct on clause
+ return;
+ }
+
+ EBasicJsonMap bean = new EBasicJsonMap();
+ bean.setName("own1");
+ bean.getDetails().add(new EBasicJsonMapDetail("detail1"));
+ bean.getDetails().add(new EBasicJsonMapDetail("detail2"));
+
+ Ebean.save(bean);
+
+ Query query1 = Ebean.find(EBasicJsonMap.class)
+ .fetch("details")
+ .where().startsWith("details.name", "detail")
+ .query();
+
+ query1.findList();
+
+ assertThat(query1.getGeneratedSql()).contains("select distinct on (t0.id, t1.id) ");
+
+ Query query2 = Ebean.find(EBasicJsonMap.class)
+ .where().startsWith("details.name", "detail")
+ .query();
+ query2.findList();
+
+ assertThat(query2.getGeneratedSql()).contains("select distinct on (t0.id) ");
+ }
+
@Test
public void testInsertUpdateDelete() throws IOException {
diff --git a/src/test/java/org/tests/model/json/EBasicJsonMap.java b/src/test/java/org/tests/model/json/EBasicJsonMap.java
index f18408154..520016df9 100644
--- a/src/test/java/org/tests/model/json/EBasicJsonMap.java
+++ b/src/test/java/org/tests/model/json/EBasicJsonMap.java
@@ -2,9 +2,13 @@ package org.tests.model.json;
import io.ebean.annotation.DbJson;
+import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
+import javax.persistence.OneToMany;
import javax.persistence.Version;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
@Entity
@@ -21,6 +25,9 @@ public class EBasicJsonMap {
@DbJson
Map content;
+ @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
+ List details = new ArrayList<>();
+
public Long getId() {
return id;
}
@@ -37,6 +44,14 @@ public class EBasicJsonMap {
this.version = version;
}
+ public List getDetails() {
+ return details;
+ }
+
+ public void setDetails(List details) {
+ this.details = details;
+ }
+
public String getName() {
return name;
}
diff --git a/src/test/java/org/tests/model/pview/TestPview.java b/src/test/java/org/tests/model/pview/TestPview.java
index 2ef00487b..2b9f55b1f 100644
--- a/src/test/java/org/tests/model/pview/TestPview.java
+++ b/src/test/java/org/tests/model/pview/TestPview.java
@@ -3,11 +3,12 @@ package org.tests.model.pview;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
-import org.junit.Assert;
import org.junit.Test;
import java.util.UUID;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestPview extends BaseTestCase {
@Test
@@ -22,7 +23,7 @@ public class TestPview extends BaseTestCase {
query.findList();
String generatedSql = sqlOf(query, 1);
- Assert.assertTrue(generatedSql.contains("select distinct t0.amount, t1.value from paggview t0 join pp u1 on u1.id = t0.pview_id join pp_to_ww u2z_ on u2z_.pp_id = u1.id join wview u2 on u2.id = u2z_.ww_id left join pp t1 on t1.id = t0.pview_id where u2.id = ? order by t1.value"));
+ assertThat(generatedSql).contains("select distinct t0.amount, t1.value from paggview t0 join pp u1 on u1.id = t0.pview_id join pp_to_ww u2z_ on u2z_.pp_id = u1.id join wview u2 on u2.id = u2z_.ww_id left join pp t1 on t1.id = t0.pview_id where u2.id = ? order by t1.value");
}
diff --git a/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java b/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java
index 5b100d92e..92faa6f94 100644
--- a/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java
+++ b/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java
@@ -3,10 +3,11 @@ package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
+import org.junit.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
-import org.junit.Assert;
-import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
public class TestImplicitJoinOnParentRelationship extends BaseTestCase {
@@ -22,8 +23,14 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase {
query.findList();
- String expectedSql = "select distinct t0.id, t0.name 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, sqlOf(query, 1));
+ if (isPostgres()) {
+ String expectedSql = "select distinct on (t0.id) t0.id, t0.name 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 = ? ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+
+ } else {
+ String expectedSql = "select distinct t0.id, t0.name 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 = ? ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+ }
// select distinct t0.id c0, t0.name c1
// from o_customer t0
@@ -47,8 +54,13 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase {
query.findList();
- String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
- Assert.assertEquals(expectedSql, sqlOf(query, 1));
+ if (isPostgres()) {
+ String expectedSql = "select distinct on (t0.id) t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+ } else {
+ String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+ }
}
@Test
@@ -63,7 +75,13 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase {
query.findList();
- String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
- Assert.assertEquals(expectedSql, sqlOf(query, 1));
+ if (isPostgres()) {
+ String expectedSql = "select distinct on (t0.id) t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+
+ } else {
+ String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+ }
}
}
diff --git a/src/test/java/org/tests/query/TestManyWhereJoin.java b/src/test/java/org/tests/query/TestManyWhereJoin.java
index 4ee1fc62d..4060dc714 100644
--- a/src/test/java/org/tests/query/TestManyWhereJoin.java
+++ b/src/test/java/org/tests/query/TestManyWhereJoin.java
@@ -7,9 +7,10 @@ import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
-import org.junit.Assert;
import org.junit.Test;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestManyWhereJoin extends BaseTestCase {
@Test
@@ -33,10 +34,14 @@ public class TestManyWhereJoin extends BaseTestCase {
// join o_order u1 on u1.kcustomer_id = t0.id
// where u1.status = ? ; --bind(NEW)
- Assert.assertTrue(sql.contains("select distinct "));
- Assert.assertTrue(sql.contains("join o_order "));
- Assert.assertTrue(sql.contains(".status = ?"));
- Assert.assertTrue(sql.contains("select distinct t0.id, t0.status from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id where u1.status = ?"));
+ if (isPostgres()) {
+ assertThat(sql).contains("select distinct on (t0.id) t0.id, ");
+ } else {
+ assertThat(sql).contains("select distinct t0.id");
+ }
+ assertThat(sql).contains("join o_order ");
+ assertThat(sql).contains(".status = ?");
+ assertThat(sql).contains("t0.id, t0.status from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id where u1.status = ?");
}
@Test
@@ -65,10 +70,14 @@ public class TestManyWhereJoin extends BaseTestCase {
// where t1.order_date is not null and u1.status = ?
// order by t0.id; --bind(NEW)
- Assert.assertTrue(sql.contains("select distinct t0.id, t0.status, t1.id, t1.status,"));
- Assert.assertTrue(sql.contains("left join o_order t1 on "));
- Assert.assertTrue(sql.contains("join o_order u1 on "));
- Assert.assertTrue(sql.contains(" u1.status = ?"));
+ if (isPostgres()) {
+ assertThat(sql).contains("select distinct on (t0.id, t1.id) t0.id, t0.status,");
+ } else {
+ assertThat(sql).contains("select distinct t0.id, t0.status, t1.id, t1.status,");
+ }
+ assertThat(sql).contains("left join o_order t1 on ");
+ assertThat(sql).contains("join o_order u1 on ");
+ assertThat(sql).contains(" u1.status = ?");
}
@Test
@@ -92,9 +101,13 @@ public class TestManyWhereJoin extends BaseTestCase {
// where u1.product_id = ?
// order by t0.cretime; --bind(1)
- Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
- Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
- Assert.assertTrue(sql.contains(" where u1.product_id = ?"));
+ if (isPostgres()) {
+ assertThat(sql).contains("select distinct on (t0.cretime, t0.id) t0.id, t0.status,");
+ } else {
+ assertThat(sql).contains("select distinct t0.id, t0.status,");
+ }
+ assertThat(sql).contains(" join o_order_detail u1 on u1.order_id = t0.id");
+ assertThat(sql).contains(" where u1.product_id = ?");
}
/**
@@ -122,9 +135,13 @@ public class TestManyWhereJoin extends BaseTestCase {
// where u1.product_id = ?
// order by t0.cretime
- Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
- Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
- Assert.assertTrue(sql.contains(" where u1.product_id = ?"));
+ if (isPostgres()) {
+ assertThat(sql).contains("select distinct on (t0.cretime, t0.id) t0.id, t0.status,");
+ } else {
+ assertThat(sql).contains("select distinct t0.id, t0.status,");
+ }
+ assertThat(sql).contains(" join o_order_detail u1 on u1.order_id = t0.id");
+ assertThat(sql).contains(" where u1.product_id = ?");
}
/**
@@ -154,11 +171,15 @@ public class TestManyWhereJoin extends BaseTestCase {
// where t1.id > 0 and u1.product_id = ?
// order by t0.cretime, t0.id, t1.id asc, t1.order_qty asc, t1.cretime desc; --bind(1)
- Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
- Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
- Assert.assertTrue(sql.contains(" u1.product_id = ?"));
+ if (isPostgres()) {
+ assertThat(sql).contains("select distinct on (t0.cretime, t0.id, t1.id, t1.order_qty, t1.cretime) t0.id, t0.status,");
+ } else {
+ assertThat(sql).contains("select distinct t0.id, t0.status,");
+ }
+ assertThat(sql).contains(" join o_order_detail u1 on u1.order_id = t0.id");
+ assertThat(sql).contains(" u1.product_id = ?");
// additional join for fetching the many details
- Assert.assertTrue(sql.contains(" left join o_order_detail t1 on t1.order_id = t0.id"));
+ assertThat(sql).contains(" left join o_order_detail t1 on t1.order_id = t0.id");
}
}
diff --git a/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java b/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java
index 84368a490..1cdd79c0d 100644
--- a/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java
+++ b/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java
@@ -10,6 +10,8 @@ import org.junit.Test;
import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestDisjunctWhereOuterOnMany extends BaseTestCase {
@Test
@@ -55,8 +57,14 @@ public class TestDisjunctWhereOuterOnMany extends BaseTestCase {
Assert.assertEquals(2, list.size());
Assert.assertEquals(2, rowCount);
- String expectedSql = "select distinct t0.id, t0.name from uuone t0 left join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ? ) ";
- Assert.assertEquals(expectedSql, sqlOf(query, 1));
+ if (isPostgres()) {
+ String expectedSql = "select distinct on (t0.id) t0.id, t0.name from uuone t0 left join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+
+ } else {
+ String expectedSql = "select distinct t0.id, t0.name from uuone t0 left join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ? ) ";
+ assertThat(sqlOf(query, 1)).contains(expectedSql);
+ }
}
diff --git a/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java b/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java
index f0e0f0062..4b5b2292a 100644
--- a/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java
+++ b/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java
@@ -84,9 +84,14 @@ public class TestOrderByWithDistinct extends BaseTestCase {
Assert.assertEquals(1, list.size());
Assert.assertEquals(user1, list.get(0));
String generatedSql = query.getGeneratedSql();
- Assert.assertTrue(generatedSql.contains("select distinct t0.userid")); // using distinct
- Assert.assertTrue(generatedSql.contains("order by t1.name,")); // name in order by
- Assert.assertTrue(generatedSql.contains("t1.name"));// name in select
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t1.name, t0.user_name, t0.userid) t0.userid"); // using distinct
+
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.userid"); // using distinct
+ }
+ assertThat(generatedSql).contains("order by t1.name,"); // name in order by
+ assertThat(generatedSql).contains("t1.name");// name in select
// repeat with slight variation, not sure this really produces a different execution path
@@ -114,9 +119,13 @@ public class TestOrderByWithDistinct extends BaseTestCase {
// order by t1.name; --bind(A)
generatedSql = query.getGeneratedSql();
- Assert.assertTrue(generatedSql.contains("select distinct t0.userid")); // using distinct
- Assert.assertTrue(generatedSql.contains("order by t1.name")); // name in order by
- Assert.assertTrue(generatedSql.contains("t1.name"));// name in select
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t1.name, t0.userid) t0.userid"); // using distinct
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.userid"); // using distinct
+ }
+ assertThat(generatedSql).contains("order by t1.name"); // name in order by
+ assertThat(generatedSql).contains("t1.name");// name in select
}
diff --git a/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java b/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java
index 5f3cd9266..c80be3698 100644
--- a/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java
+++ b/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java
@@ -7,6 +7,8 @@ import org.tests.model.basic.Customer;
import org.junit.Assert;
import org.junit.Test;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestOrderByWithDistinctTake2 extends BaseTestCase {
@Test
@@ -23,7 +25,7 @@ public class TestOrderByWithDistinctTake2 extends BaseTestCase {
public void test() {
Query query = Ebean.find(Customer.class)
- .select("id")
+ .select("id, name")
.where().ilike("contacts.firstName", "R%")
.order("name desc");
@@ -36,10 +38,15 @@ public class TestOrderByWithDistinctTake2 extends BaseTestCase {
// where lower(u1.first_name) like ?
// order by t0.name; --bind(r%)
- Assert.assertTrue("t0.name added to the select clause", generatedSql.contains("select distinct t0.id, t0.name"));
- Assert.assertTrue(generatedSql.contains("order by t0.name desc"));
- Assert.assertTrue(generatedSql.contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id"));
- Assert.assertTrue(generatedSql.contains("where lower(u1.first_name) like ?"));
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t0.name, t0.id) t0.id, t0.name");
+
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.id, t0.name");
+ }
+ assertThat(generatedSql).contains("order by t0.name desc");
+ assertThat(generatedSql).contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id");
+ assertThat(generatedSql).contains("where lower(u1.first_name) like ?");
}
@Test
@@ -54,10 +61,14 @@ public class TestOrderByWithDistinctTake2 extends BaseTestCase {
String generatedSql = sqlOf(query);
- Assert.assertTrue("t0.name added to the select clause", generatedSql.contains("select distinct t0.id, t0.name, t0.id"));
- Assert.assertTrue(generatedSql.contains("order by t0.name, t0.id desc"));
- Assert.assertTrue(generatedSql.contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id"));
- Assert.assertTrue(generatedSql.contains("where lower(u1.first_name) like ?"));
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t0.name, t0.id) t0.id, t0.name, t0.id");
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.id, t0.name, t0.id");
+ }
+ assertThat(generatedSql).contains("order by t0.name, t0.id desc");
+ assertThat(generatedSql).contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id");
+ assertThat(generatedSql).contains("where lower(u1.first_name) like ?");
}
}
diff --git a/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java b/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java
index db4d874a7..181a58a14 100644
--- a/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java
+++ b/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java
@@ -10,6 +10,8 @@ import org.junit.Test;
import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestQueryConversationRowCount extends BaseTestCase {
@Test
@@ -40,9 +42,14 @@ public class TestQueryConversationRowCount extends BaseTestCase {
// where t0.group_id = ? and ((t0.open = ? and u1.user_id = ? ) or t0.open = ? )
// order by t0.when_created desc;
- Assert.assertTrue(generatedSql.contains("select distinct t0.id, t0.title, t0.isopen"));
- Assert.assertTrue(generatedSql.contains("left join c_participation u1 on u1.conversation_id = t0.id"));
- Assert.assertTrue(generatedSql.contains("where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )"));
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t0.when_created, t0.id) t0.id, t0.title, t0.isopen");
+
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.id, t0.title, t0.isopen");
+ }
+ assertThat(generatedSql).contains("left join c_participation u1 on u1.conversation_id = t0.id");
+ assertThat(generatedSql).contains("where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )");
LoggedSqlCollector.start();
@@ -59,7 +66,7 @@ public class TestQueryConversationRowCount extends BaseTestCase {
Assert.assertEquals(1, loggedSql.size());
String countSql = trimSql(loggedSql.get(0), 0);
- Assert.assertTrue(countSql.contains("select count(*) from ( select distinct t0.id from c_conversation t0 left join c_participation u1 on u1.conversation_id = t0.id where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )"));
+ assertThat(countSql).contains("select count(*) from ( select distinct t0.id from c_conversation t0 left join c_participation u1 on u1.conversation_id = t0.id where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )");
}
}
diff --git a/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java b/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java
index bc773a79c..0721a4d3c 100644
--- a/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java
+++ b/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java
@@ -11,6 +11,8 @@ import org.junit.Test;
import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestQueryRowCountWithMany extends BaseTestCase {
@Test
@@ -39,11 +41,16 @@ public class TestQueryRowCountWithMany extends BaseTestCase {
// order by t0.cretime, t0.id, t1.id asc, t1.order_qty asc, t1.cretime desc; --bind(1)
String generatedSql = sqlOf(query, 1);
- Assert.assertTrue(generatedSql.contains("select distinct t0.id, t0.status,")); // need the distinct
- Assert.assertTrue(generatedSql.contains("left join o_order_detail t1 on t1.order_id = t0.id")); //fetch join
- Assert.assertTrue(generatedSql.contains("join o_order_detail u1 on u1.order_id = t0.id")); //predicate join
- Assert.assertTrue(generatedSql.contains(" u1.product_id = ?")); // u1 as predicate alias
- Assert.assertTrue(generatedSql.contains(" order by t0.cretime"));
+ if (isPostgres()) {
+ assertThat(generatedSql).contains("select distinct on (t0.cretime, t0.id, t1.id, t1.order_qty, t1.cretime) t0.id, t0.status,"); // need the distinct
+
+ } else {
+ assertThat(generatedSql).contains("select distinct t0.id, t0.status,"); // need the distinct
+ }
+ assertThat(generatedSql).contains("left join o_order_detail t1 on t1.order_id = t0.id"); //fetch join
+ assertThat(generatedSql).contains("join o_order_detail u1 on u1.order_id = t0.id"); //predicate join
+ assertThat(generatedSql).contains(" u1.product_id = ?"); // u1 as predicate alias
+ assertThat(generatedSql).contains(" order by t0.cretime");
int rowCount = query.findCount();
@@ -61,8 +68,8 @@ public class TestQueryRowCountWithMany extends BaseTestCase {
Assert.assertEquals(list.size(), rowCount);
Assert.assertEquals(2, sqlLogged.size());
- Assert.assertTrue(trimSql(sqlLogged.get(1), 1).contains(
- "select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )"));
+ assertThat(trimSql(sqlLogged.get(1), 1)).contains(
+ "select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )");
}
@@ -87,7 +94,7 @@ public class TestQueryRowCountWithMany extends BaseTestCase {
List sqlLogged = LoggedSqlCollector.stop();
Assert.assertEquals(1, sqlLogged.size());
- Assert.assertTrue(trimSql(sqlLogged.get(0), 1).contains("select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )"));
+ assertThat(trimSql(sqlLogged.get(0), 1)).contains("select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )");
query.findList();
}