From 7733e9382cb054a98b32f53b06cea89ed4e78f2e Mon Sep 17 00:00:00 2001 From: Noemi Szemenyei Date: Tue, 25 Jan 2022 08:52:21 +0100 Subject: [PATCH 1/4] ADD: failing test with select distinct with composite key and T0.NULL (cherry picked from commit a08ba194b790c69c28b0907c87d378f22b565cca) --- ...ascadeDeleteChildrenWithCompositeKeys.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java b/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java index e637a0465..575671952 100644 --- a/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java +++ b/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java @@ -1,7 +1,9 @@ package org.tests.compositekeys; import io.ebean.BaseTestCase; +import io.ebean.CountDistinctOrder; import io.ebean.DB; +import io.ebean.Query; import io.ebean.annotation.Identity; import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.server.deploy.BeanDescriptor; @@ -16,6 +18,7 @@ import java.util.List; import java.util.Set; import static io.ebean.annotation.IdentityGenerated.BY_DEFAULT; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -82,6 +85,31 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase { beanProperty.findIdsByParentId(null, ids, null, null, true); beanProperty.findIdsByParentId(1L, null, null, null, true); } + + /** + * Test makes select and a select distinct of entities with composite keys. + */ + @Test + public void testSelectDistinctCountWithCompositeKey() { + + // first query with a simple findList + Query query1 = DB.find(UserRole.class); + query1.findList(); + + assertThat(query1.getGeneratedSql()).contains("select t0.user_id, t0.role_id, t0.user_id, t0.role_id from em_user_role t0"); + + // second query with count distinct + query1 = DB.find(UserRole.class); + query1.select(""); + query1.fetch("user", "name"); + query1.setDistinct(true).setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC).setMaxRows(20); + query1.findSingleAttributeList(); + + assertThat(query1.getGeneratedSql()).contains("select distinct r1.attribute_, count(*) from " + + "(select distinct t0.user_id, t0.role_id, t1.name as attribute_ " + + "from em_user_role t0 join em_user t1 on t1.id = t0.user_id) r1 " + + "group by r1.attribute_ order by count(*) desc, r1.attribute_ limit 20"); + } @Identity(generated = BY_DEFAULT) @Entity From dd26dc342d9bc16657548c199bb24a7b77ecce41 Mon Sep 17 00:00:00 2001 From: Noemi Szemenyei Date: Tue, 25 Jan 2022 08:53:21 +0100 Subject: [PATCH 2/4] FIX: select properties of the embedded Id (cherry picked from commit 58e952b1ec9125dfccedcb04485913fbcc67932f) --- .../io/ebeaninternal/server/query/CQueryBuilder.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index 278603f5b..45657fb9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java @@ -568,8 +568,16 @@ final class CQueryBuilder { if (countSingleAttribute) { sb.append("r1.attribute_, count(*) from (select "); if (distinct) { - sb.append("distinct t0."); - sb.append(request.descriptor().idProperty().dbColumn()).append(", "); + sb.append("distinct "); + BeanProperty idProp = request.descriptor().idProperty(); + if (idProp.isEmbedded()) { + BeanProperty[] props = ((BeanPropertyAssocOne) idProp).properties(); + for (BeanProperty prop : props) { + sb.append("t0.").append(prop.dbColumn()).append(", "); + } + } else { + sb.append("t0.").append(idProp.dbColumn()).append(", "); + } } sb.append(select.getSelectSql()).append(" as attribute_"); } else { From dcf60a3d1c73c469c5b0666f8c8bf708a90f82a4 Mon Sep 17 00:00:00 2001 From: Noemi Szemenyei Date: Wed, 26 Jan 2022 08:09:42 +0100 Subject: [PATCH 3/4] Trigger Build From 008e1849a25e7f809baaf04d3b50fe166598ec6f Mon Sep 17 00:00:00 2001 From: Noemi Szemenyei Date: Wed, 26 Jan 2022 08:25:38 +0100 Subject: [PATCH 4/4] FIX: other queries for other platforms --- ...ascadeDeleteChildrenWithCompositeKeys.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java b/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java index 575671952..bddc156bb 100644 --- a/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java +++ b/ebean-test/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java @@ -5,6 +5,7 @@ import io.ebean.CountDistinctOrder; import io.ebean.DB; import io.ebean.Query; import io.ebean.annotation.Identity; +import io.ebean.annotation.Platform; import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.deploy.BeanPropertyAssocMany; @@ -105,10 +106,23 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase { query1.setDistinct(true).setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC).setMaxRows(20); query1.findSingleAttributeList(); - assertThat(query1.getGeneratedSql()).contains("select distinct r1.attribute_, count(*) from " - + "(select distinct t0.user_id, t0.role_id, t1.name as attribute_ " - + "from em_user_role t0 join em_user t1 on t1.id = t0.user_id) r1 " - + "group by r1.attribute_ order by count(*) desc, r1.attribute_ limit 20"); + if (isH2() || isMariaDB() || isPostgres()) { + assertThat(query1.getGeneratedSql()).contains("select distinct r1.attribute_, count(*) from " + + "(select distinct t0.user_id, t0.role_id, t1.name as attribute_ " + + "from em_user_role t0 join em_user t1 on t1.id = t0.user_id) r1 " + + "group by r1.attribute_ order by count(*) desc, r1.attribute_ limit 20"); + } else if (isDb2()) { + assertThat(query1.getGeneratedSql()).contains("select distinct r1.attribute_, count(*) from " + + "(select distinct t0.user_id, t0.role_id, t1.name as attribute_ " + + "from em_user_role t0 join em_user t1 on t1.id = t0.user_id) r1 " + + "group by r1.attribute_ order by count(*) desc, r1.attribute_ fetch next 20 rows only"); + } else if (isSqlServer()) { + assertThat(query1.getGeneratedSql()).contains("select distinct top 20 r1.attribute_, count(*) " + + "from (select distinct t0.user_id, t0.role_id, t1.name as attribute_ from em_user_role t0 " + + "join em_user t1 on t1.id = t0.user_id) r1 group by r1.attribute_ order by count(*) desc, r1.attribute_"); + } else { + // no Oracle test yet + } } @Identity(generated = BY_DEFAULT)