From c1b022c1233039c978ccc5f52cee19656d016dd7 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 1 Mar 2018 23:46:41 +0100 Subject: [PATCH] NEW: FetchCountDistinct - query can return distinct values with their counts (#1300) * NEW: FetchCountDistinct - query can return distinct values with their counts * Have to disable asserts, because of #1298 --- .../java/io/ebean/CountDistinctOrder.java | 27 ++++ src/main/java/io/ebean/CountedValue.java | 33 ++++ src/main/java/io/ebean/Query.java | 10 ++ .../java/io/ebeaninternal/api/SpiQuery.java | 6 + .../server/query/CQueryBuilder.java | 40 ++++- .../query/CQueryFetchSingleAttribute.java | 12 +- .../server/query/SqlTreeBuilder.java | 2 +- .../server/querydefn/DefaultOrmQuery.java | 21 ++- .../server/querydefn/OrmQueryPlanKey.java | 6 +- .../server/querydefn/OrmQueryPlanKeyTest.java | 146 +++++++++--------- .../query/other/TestQuerySingleAttribute.java | 109 +++++++++++++ 11 files changed, 329 insertions(+), 83 deletions(-) create mode 100644 src/main/java/io/ebean/CountDistinctOrder.java create mode 100644 src/main/java/io/ebean/CountedValue.java diff --git a/src/main/java/io/ebean/CountDistinctOrder.java b/src/main/java/io/ebean/CountDistinctOrder.java new file mode 100644 index 000000000..e23ac4fd4 --- /dev/null +++ b/src/main/java/io/ebean/CountDistinctOrder.java @@ -0,0 +1,27 @@ +package io.ebean; +/** + * Enumeration to use with {@link Query#setCountDistinct(CountDistinctOrder)}. + * @author Roland Praml, FOCONIS AG + * + */ +public enum CountDistinctOrder { + NO_ORDERING, + + /** order by attribute ascending */ + ATTR_ASC, + + /** order by attribute descending */ + ATTR_DESC, + + /** order by count ascending and attribute ascending */ + COUNT_ASC_ATTR_ASC, + + /** order by count ascending and attribute descending */ + COUNT_ASC_ATTR_DESC, + + /** order by count descending and attribute ascending */ + COUNT_DESC_ATTR_ASC, + + /** order by count descending and attribute descending */ + COUNT_DESC_ATTR_DESC, +} diff --git a/src/main/java/io/ebean/CountedValue.java b/src/main/java/io/ebean/CountedValue.java new file mode 100644 index 000000000..3752f8e51 --- /dev/null +++ b/src/main/java/io/ebean/CountedValue.java @@ -0,0 +1,33 @@ +package io.ebean; + +import java.io.Serializable; +/** + * Holds a distinct value with it's count. + * (Used with {@link Query#findSingleAttributeList()} and {@link Query#setCountDistinct(CountDistinctOrder)}.) + * @author Roland Praml, FOCONIS AG + */ +public class CountedValue implements Serializable { + private static final long serialVersionUID = -2267971668356749695L; + + private final A value; + private final long count; + + public CountedValue(A value, long count) { + this.value = value; + this.count = count; + } + + public long getCount() { + return count; + } + + public A getValue() { + return value; + } + + @Override + public String toString() { + return count + ": " + value; + } + +} diff --git a/src/main/java/io/ebean/Query.java b/src/main/java/io/ebean/Query.java index 6102926c3..b69e0c631 100644 --- a/src/main/java/io/ebean/Query.java +++ b/src/main/java/io/ebean/Query.java @@ -828,6 +828,11 @@ public interface Query { */ A findSingleAttribute(); + /** + * Return true if this is countDistinct query. + */ + boolean isCountDistinct(); + /** * Execute the query returning either a single bean or null (if no matching * bean is found). @@ -1272,6 +1277,11 @@ public interface Query { */ Query setDistinct(boolean isDistinct); + /** + * Extended version for setDistinct in conjunction with "findSingleAttributeList"; + */ + Query setCountDistinct(CountDistinctOrder orderBy); + /** * Return the first row value. */ diff --git a/src/main/java/io/ebeaninternal/api/SpiQuery.java b/src/main/java/io/ebeaninternal/api/SpiQuery.java index 1134d660f..065d3c9a5 100644 --- a/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -1,6 +1,7 @@ package io.ebeaninternal.api; import io.ebean.CacheMode; +import io.ebean.CountDistinctOrder; import io.ebean.ExpressionList; import io.ebean.OrderBy; import io.ebean.PersistenceContextScope; @@ -822,4 +823,9 @@ public interface SpiQuery extends Query, TxnProfileEventCodes { * Simplify nested expression lists where possible. */ void simplifyExpressions(); + + /** + * Returns the count distinct order setting. + */ + CountDistinctOrder getCountDistinctOrder(); } diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index 843828025..1d95f7517 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.CountDistinctOrder; import io.ebean.Query; import io.ebean.RawSql; import io.ebean.RawSqlBuilder; @@ -190,7 +191,7 @@ class CQueryBuilder { CQueryPlan queryPlan = request.getQueryPlan(); if (queryPlan != null) { predicates.prepare(false); - return new CQueryFetchSingleAttribute(request, predicates, queryPlan); + return new CQueryFetchSingleAttribute(request, predicates, queryPlan, query.isCountDistinct()); } // use RawSql or generated Sql @@ -201,7 +202,7 @@ class CQueryBuilder { queryPlan = new CQueryPlan(request, s.getSql(), sqlTree, false, s.isIncludesRowNumberColumn(), predicates.getLogWhereSql()); request.putQueryPlan(queryPlan); - return new CQueryFetchSingleAttribute(request, predicates, queryPlan); + return new CQueryFetchSingleAttribute(request, predicates, queryPlan, query.isCountDistinct()); } /** @@ -549,8 +550,13 @@ class CQueryBuilder { } } } - - sb.append(select.getSelectSql()); + if (query.isCountDistinct() && query.isSingleAttribute()) { + sb.append("r1.attribute_, count(*) from (select "); + sb.append(select.getSelectSql()); + sb.append(" as attribute_"); + } else { + 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(DbOrderByTrim.trim(dbOrderBy)); @@ -642,10 +648,15 @@ class CQueryBuilder { sb.append(" having ").append(dbHaving); } - if (dbOrderBy != null) { + if (dbOrderBy != null && !query.isCountDistinct()) { sb.append(" order by ").append(dbOrderBy); } + if (query.isCountDistinct() && query.isSingleAttribute()) { + sb.append(") r1 group by r1.attribute_"); + sb.append(toSql(query.getCountDistinctOrder())); + } + if (useSqlLimiter) { // use LIMIT/OFFSET, ROW_NUMBER() or rownum type SQL query limitation SqlLimitRequest r = new OrmQueryLimitRequest(sb.toString(), dbOrderBy, query, dbPlatform); @@ -657,6 +668,25 @@ class CQueryBuilder { } + private String toSql(CountDistinctOrder orderBy) { + switch(orderBy) { + case ATTR_ASC: + return " order by r1.attribute_"; + case ATTR_DESC: + return " order by r1.attribute_ desc"; + case COUNT_ASC_ATTR_ASC: + return " order by count(*), r1.attribute_"; + case COUNT_ASC_ATTR_DESC: + return " order by count(*), r1.attribute_ desc"; + case COUNT_DESC_ATTR_ASC: + return " order by count(*) desc, r1.attribute_"; + case COUNT_DESC_ATTR_DESC: + return " order by count(*) desc, r1.attribute_ desc"; + default: + throw new IllegalArgumentException("Illegal enum: "+ orderBy); + } + } + /** * Append where or and based on the hasWhere flag. */ diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java b/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java index 8ea69624c..b5d2d05b1 100644 --- a/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java +++ b/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.query; import io.ebean.util.JdbcClose; +import io.ebean.CountedValue; import io.ebeaninternal.api.SpiProfileTransactionEvent; import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.api.SpiTransaction; @@ -60,18 +61,21 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent { private final ScalarType scalarType; + private final boolean containsCounts; + private long profileOffset; /** * Create the Sql select based on the request. */ - CQueryFetchSingleAttribute(OrmQueryRequest request, CQueryPredicates predicates, CQueryPlan queryPlan) { + CQueryFetchSingleAttribute(OrmQueryRequest request, CQueryPredicates predicates, CQueryPlan queryPlan, boolean containsCounts) { this.request = request; this.queryPlan = queryPlan; this.query = request.getQuery(); this.sql = queryPlan.getSql(); this.desc = request.getBeanDescriptor(); this.predicates = predicates; + this.containsCounts = containsCounts; this.scalarType = queryPlan.getSingleAttributeScalarType(); query.setGeneratedSql(sql); } @@ -101,7 +105,11 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent { List result = new ArrayList<>(); while (dataReader.next()) { - result.add(scalarType.read(dataReader)); + Object value = scalarType.read(dataReader); + if (containsCounts) { + value = new CountedValue<>(value, dataReader.getLong()); + } + result.add(value); dataReader.resetColumnPosition(); rowCount++; } diff --git a/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index d5ea84855..5a26fcc5d 100644 --- a/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -110,7 +110,7 @@ public final class SqlTreeBuilder { this.query = request.getQuery(); this.temporalMode = SpiQuery.TemporalMode.of(query); this.disableLazyLoad = query.isDisableLazyLoading(); - this.subQuery = Type.SUBQUERY == query.getType() || Type.ID_LIST == query.getType(); + this.subQuery = Type.SUBQUERY == query.getType() || Type.ID_LIST == query.getType() || Type.DELETE == query.getType() || query.isCountDistinct(); this.includeJoin = query.getM2mIncludeJoin(); this.manyWhereJoins = query.getManyWhereJoins(); this.queryDetail = query.getDetail(); diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index ded44b52e..a66619796 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.querydefn; import io.ebean.CacheMode; +import io.ebean.CountDistinctOrder; import io.ebean.Expression; import io.ebean.ExpressionFactory; import io.ebean.ExpressionList; @@ -217,6 +218,8 @@ public class DefaultOrmQuery implements SpiQuery { private boolean singleAttribute; + private CountDistinctOrder countDistinctOrder; + /** * Set to true if this query has been tuned by autoTune. */ @@ -655,6 +658,11 @@ public class DefaultOrmQuery implements SpiQuery { return singleAttribute; } + @Override + public CountDistinctOrder getCountDistinctOrder() { + return countDistinctOrder; + } + /** * Return true if the Id should be included in the query. */ @@ -1021,7 +1029,7 @@ public class DefaultOrmQuery implements SpiQuery { queryPlanKey = new OrmQueryPlanKey(beanDescriptor.getDiscValue(), m2mIncludeJoin, type, detail, maxRows, firstRow, disableLazyLoading, orderBy, distinct, sqlDistinct, mapKey, id, bindParams, whereExpressions, havingExpressions, - temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties); + temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties, countDistinctOrder); } return queryPlanKey; } @@ -1484,6 +1492,17 @@ public class DefaultOrmQuery implements SpiQuery { return this; } + @Override + public DefaultOrmQuery setCountDistinct(CountDistinctOrder countDistinctOrder) { + this.countDistinctOrder = countDistinctOrder; + return this; + } + + @Override + public boolean isCountDistinct() { + return countDistinctOrder != null; + } + /** * Return true if this query uses SQL DISTINCT either explicitly by the user or internally defined * by ebean. diff --git a/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java b/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java index f8abd66b3..eb7ca79c1 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.querydefn; +import io.ebean.CountDistinctOrder; import io.ebean.OrderBy; import io.ebean.Query; import io.ebeaninternal.api.BindParams; @@ -23,7 +24,7 @@ class OrmQueryPlanKey implements CQueryPlanKey { OrmQueryPlanKey(String discValue, TableJoin m2mIncludeTable, SpiQuery.Type type, OrmQueryDetail detail, int maxRows, int firstRow, boolean disableLazyLoading, OrderBy orderBy, boolean distinct, boolean sqlDistinct, String mapKey, Object id, BindParams bindParams, SpiExpression whereExpressions, SpiExpression havingExpressions, SpiQuery.TemporalMode temporalMode, - Query.ForUpdate forUpdate, String rootTableAlias, SpiRawSql rawSql, OrmUpdateProperties updateProperties) { + Query.ForUpdate forUpdate, String rootTableAlias, SpiRawSql rawSql, OrmUpdateProperties updateProperties, CountDistinctOrder countDistinctOrder) { StringBuilder sb = new StringBuilder(300); if (type != null) { @@ -62,6 +63,9 @@ class OrmQueryPlanKey implements CQueryPlanKey { if (mapKey != null) { sb.append(",mapKey:").append(mapKey); } + if (countDistinctOrder != null) { + sb.append(",countdistinctoder:").append(countDistinctOrder.name()); + } this.maxRows = maxRows; this.firstRow = firstRow; this.rawSqlKey = (rawSql == null) ? null : rawSql.getKey(); diff --git a/src/test/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKeyTest.java b/src/test/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKeyTest.java index c204076c7..1ab27c6d0 100644 --- a/src/test/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKeyTest.java +++ b/src/test/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKeyTest.java @@ -21,8 +21,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_defaults() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @@ -30,9 +30,9 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_diffDiscValue() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey("A", null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key3 = new OrmQueryPlanKey("B", null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey("A", null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key3 = new OrmQueryPlanKey("B", null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); assertDifferent(key2, key3); } @@ -42,8 +42,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { TableJoin tableJoin = tableJoin("table", "id", "customer_id"); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -54,8 +54,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { TableJoin tableJoin1 = tableJoin("one", "id", "customer_id"); TableJoin tableJoin2 = tableJoin("two", "id", "customer_id"); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -66,8 +66,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { TableJoin tableJoin1 = tableJoin("one", "id", "customer_id"); TableJoin tableJoin2 = tableJoin("one", "id", "customer_id"); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @@ -82,8 +82,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_diffQueryType() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.LIST, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.LIST, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -91,8 +91,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_firstRowsDifferent() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 10, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 10, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -100,8 +100,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_maxRowsDifferent() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -109,8 +109,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_firstRowsMaxRowsSame() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 20, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 20, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 20, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 10, 20, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @@ -118,8 +118,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { @Test public void equals_when_diffDisableLazyLoading() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, true, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, true, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -128,8 +128,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { public void equals_when_diffOrderByNull() { OrderBy o1 = new OrderBy<>("id"); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -139,121 +139,121 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { OrderBy o1 = new OrderBy<>("id, name"); OrderBy o2 = new OrderBy<>("id, name"); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o2, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, o2, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @Test public void equals_when_diffDistinct() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_sameDistinct() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @Test public void equals_when_diffSqlDistinct() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_sameSqlDistinct() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @Test public void equals_when_diffMapKeyNull() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffMapKey() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "diff", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "diff", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_sameMapKey() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @Test public void equals_when_diffIdNull() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_idBothGiven() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 23, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, 23, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @Test public void equals_when_diffTemporalMode() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffForUpdate() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffForUpdate_NoWait() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.NOWAIT, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.NOWAIT, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffForUpdate_SkipLocked() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.SKIPLOCKED, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.BASE, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, Query.ForUpdate.SKIPLOCKED, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffRootAliasNull() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_diffRootAlias() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "diff", null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "diff", null, null, null); assertDifferent(key1, key2); } @Test public void equals_when_sameRootAlias() { - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, "rootAlias", null, null, null); assertSame(key1, key2); } @@ -280,8 +280,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpressionList list1 = list_id_eq_42(); SpiExpressionList list2 = list_id_eq_43(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list2, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list2, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @@ -292,8 +292,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpressionList where1 = list_id_eq_42(); SpiExpressionList where2 = list_id_eq_42_and_name_eq_rob(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, where1, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, where2, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, where1, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, where2, null, SpiQuery.TemporalMode.DRAFT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -302,8 +302,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpressionList list1 = list_id_eq_42(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -312,8 +312,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpressionList list1 = list_id_eq_42(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -323,8 +323,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpression having1 = list_id_eq_42().copyForPlanKey(); SpiExpression having2 = list_id_eq_42_and_name_eq_rob().copyForPlanKey(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -334,8 +334,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpression having1 = list_id_eq_42().copyForPlanKey(); SpiExpression having2 = list_id_eq_42().copyForPlanKey(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertSame(key1, key2); } @@ -344,8 +344,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpression having1 = list_id_eq_42().copyForPlanKey(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } @@ -354,8 +354,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest { SpiExpression having1 = list_id_eq_42().copyForPlanKey(); - OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null); - OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null); + OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); + OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, null, SpiQuery.Type.BEAN, null, 0, 0, false, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, null, null, null, null, null); assertDifferent(key1, key2); } diff --git a/src/test/java/org/tests/query/other/TestQuerySingleAttribute.java b/src/test/java/org/tests/query/other/TestQuerySingleAttribute.java index 27305412c..101c0326f 100644 --- a/src/test/java/org/tests/query/other/TestQuerySingleAttribute.java +++ b/src/test/java/org/tests/query/other/TestQuerySingleAttribute.java @@ -1,6 +1,8 @@ package org.tests.query.other; import io.ebean.BaseTestCase; +import io.ebean.CountDistinctOrder; +import io.ebean.CountedValue; import io.ebean.Ebean; import io.ebean.Query; import org.junit.Ignore; @@ -438,4 +440,111 @@ public class TestQuerySingleAttribute extends BaseTestCase { + "order by t1.billing_address_id desc"); } + @Test + public void distinctWithCascadedFetchCount() { + + ResetBasicData.reset(); + + + int count = Ebean.find(Contact.class).findCount(); + assertThat(count).isGreaterThanOrEqualTo(12); + + Query query = Ebean.find(Contact.class) + .select("firstName"); + + List> list1 = query + .setCountDistinct(CountDistinctOrder.ATTR_ASC) + + .findSingleAttributeList(); + assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from (" + + "select t0.first_name as attribute_ from contact t0" + + ") r1 group by r1.attribute_ order by r1.attribute_"); + assertThat(list1.get(0)).isInstanceOf(CountedValue.class); + // FIXME: These asserts will fail, because other tests will interfere. see #1298 + //assertThat(list1.toString()).isEqualTo("[3: Bugs1, 1: Fiona, 3: Fred1, 1: Jack, 3: Jim1, 1: Tracy]"); + + + query = Ebean.find(Contact.class).select("firstName"); + list1 = query + .setCountDistinct(CountDistinctOrder.ATTR_DESC) + .findSingleAttributeList(); + assertThat(list1.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list1.toString()).isEqualTo("[1: Tracy, 3: Jim1, 1: Jack, 3: Fred1, 1: Fiona, 3: Bugs1]"); + + query = Ebean.find(Contact.class).select("firstName"); + list1 = query + .setCountDistinct(CountDistinctOrder.COUNT_ASC_ATTR_DESC) + .findSingleAttributeList(); + assertThat(list1.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list1.toString()).isEqualTo("[1: Tracy, 1: Jack, 1: Fiona, 3: Jim1, 3: Fred1, 3: Bugs1]"); + + query = Ebean.find(Contact.class).fetch("customer.shippingAddress","line1");//("firstName") + List> list2 = query + .setCountDistinct(CountDistinctOrder.ATTR_ASC) + .findSingleAttributeList(); + assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from (" + + "select t2.line_1 as attribute_ " + + "from contact t0 join o_customer t1 on t1.id = t0.customer_id " + + "left join o_address t2 on t2.id = t1.shipping_address_id " + + ") r1 group by r1.attribute_ order by r1.attribute_"); + assertThat(list2.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list2.toString()).isEqualTo("[1: null, 3: 1 Banana St, 5: 12 Apple St, 3: 15 Kumera Way]"); + + + query = Ebean.find(Contact.class).select("firstName") + .where().eq("customer.shippingAddress.line1", "12 Apple St").query(); + List> list3 = query + .setCountDistinct(CountDistinctOrder.ATTR_ASC) + .findSingleAttributeList(); + assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from (" + + "select t0.first_name as attribute_ from contact t0 " + + "join o_customer t1 on t1.id = t0.customer_id " + + "left join o_address t2 on t2.id = t1.shipping_address_id where t2.line_1 = ? " + + ") r1 group by r1.attribute_ order by r1.attribute_"); + assertThat(list3.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list3.toString()).isEqualTo("[1: Bugs1, 1: Fiona, 1: Fred1, 1: Jim1, 1: Tracy]"); + + + query = Ebean.find(Contact.class).fetch("customer.billingAddress","line1") + .where().or() + .ne("customer.shippingAddress.line1", "12 Apple St") + .isNull("customer.shippingAddress.line1") + .endOr().query(); + List> list4 = query + .setCountDistinct(CountDistinctOrder.ATTR_ASC) + .findSingleAttributeList(); + assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from (" + + "select t2.line_1 as attribute_ " + + "from contact t0 join o_customer t1 on t1.id = t0.customer_id " + + "left join o_address t2 on t2.id = t1.billing_address_id " + + "left join o_address t3 on t3.id = t1.shipping_address_id " + + "where (t3.line_1 <> ? or t3.line_1 is null ) " + + ") r1 group by r1.attribute_ order by r1.attribute_"); + assertThat(list4.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list4.toString()).isEqualTo("[1: null, 3: Bos town, 3: P.O.Box 1234]"); + + + // Test Limiter for MSSQL + query = Ebean.find(Contact.class).fetch("customer.billingAddress","line1").setFirstRow(1).setMaxRows(2); + List> list5 = query + .where().isNotNull("customer.billingAddress.line1").query() + .setCountDistinct(CountDistinctOrder.ATTR_DESC) + .findSingleAttributeList(); + assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from (" + + "select t2.line_1 as attribute_ from contact t0 " + + "join o_customer t1 on t1.id = t0.customer_id " + + "left join o_address t2 on t2.id = t1.billing_address_id " + + "where t2.line_1 is not null " + + ") r1 group by r1.attribute_ order by r1.attribute_ desc "); + if (isSqlServer()) { + assertThat(sqlOf(query)).endsWith(" fetch next 2 rows only"); + } else if (isDb2()) { + assertThat(query.getGeneratedSql()).endsWith("FETCH FIRST 2 ROWS ONLY"); + } else { + assertThat(sqlOf(query)).endsWith(" limit 2 offset 1"); + } + assertThat(list5.get(0)).isInstanceOf(CountedValue.class); + //assertThat(list5.toString()).isEqualTo("[3: P.O.Box 1234, 3: Bos town]"); + } + }