From 94951a5476c37f5bc719140e171380efe5b3e0a3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 2 Feb 2022 23:38:50 +1300 Subject: [PATCH] Yugabyte - use distinct on clause with Yugabyte (like Postgres) --- .../io/ebeaninternal/server/query/CQueryBuilder.java | 2 +- ebean-test/src/test/java/io/ebean/BaseTestCase.java | 4 ++++ .../server/expression/IsEmptyExpressionQueryTest.java | 4 ++-- .../query/TestImplicitJoinOnParentRelationship.java | 6 +++--- .../test/java/org/tests/query/TestManyWhereJoin.java | 10 +++++----- .../query/joins/TestDisjunctWhereOuterOnMany.java | 2 +- .../org/tests/query/joins/TestQueryJoinOnFormula.java | 2 +- .../tests/query/orderby/TestOrderByWithDistinct.java | 6 +++--- .../query/orderby/TestOrderByWithDistinctTake2.java | 4 ++-- .../query/other/TestQueryConversationRowCount.java | 2 +- .../tests/query/other/TestQueryRowCountWithMany.java | 2 +- ebean-test/src/test/resources/ebean.properties | 8 ++++---- 12 files changed, 28 insertions(+), 24 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 1d32ce994..7559f7283 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 @@ -757,7 +757,7 @@ final class CQueryBuilder { } boolean isPlatformDistinctOn() { - return dbPlatform.isPlatform(Platform.POSTGRES); + return dbPlatform.isPlatform(Platform.POSTGRES) || dbPlatform.isPlatform(Platform.YUGABYTE); } boolean isPlatformDistinctNoLobs() { diff --git a/ebean-test/src/test/java/io/ebean/BaseTestCase.java b/ebean-test/src/test/java/io/ebean/BaseTestCase.java index c8515188f..c1920b894 100644 --- a/ebean-test/src/test/java/io/ebean/BaseTestCase.java +++ b/ebean-test/src/test/java/io/ebean/BaseTestCase.java @@ -195,6 +195,10 @@ public abstract class BaseTestCase { return Platform.DB2 == platform(); } + public boolean platformDistinctOn() { + return isPostgresCompatible(); + } + public boolean isPostgresCompatible() { return isPostgres() || isYugabyte(); } diff --git a/ebean-test/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java b/ebean-test/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java index cf2a11e04..db93edf36 100644 --- a/ebean-test/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java +++ b/ebean-test/src/test/java/io/ebeaninternal/server/expression/IsEmptyExpressionQueryTest.java @@ -121,7 +121,7 @@ public class IsEmptyExpressionQueryTest extends BaseTestCase { .query(); query.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { 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 x where x.contact_id = u1.id)"); } else { @@ -140,7 +140,7 @@ public class IsEmptyExpressionQueryTest extends BaseTestCase { .query(); query.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { 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 x where x.contact_id = u1.id)"); } else { diff --git a/ebean-test/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java b/ebean-test/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java index fd73bdbb1..402b6dc99 100644 --- a/ebean-test/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java +++ b/ebean-test/src/test/java/org/tests/query/TestImplicitJoinOnParentRelationship.java @@ -23,7 +23,7 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase { query.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { 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 and u1.order_date is not null join o_order_detail u2 on u2.order_id = u1.id and u2.id > 0 join o_product u3 on u3.id = u2.product_id where u3.name = ?"; assertThat(sqlOf(query, 1)).contains(expectedSql); @@ -54,7 +54,7 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase { query.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { 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 and u1.order_date is not null left join o_order_detail u2 on u2.order_id = u1.id and u2.id > 0 left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ?)"; assertThat(sqlOf(query, 1)).contains(expectedSql); } else { @@ -75,7 +75,7 @@ public class TestImplicitJoinOnParentRelationship extends BaseTestCase { query.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { 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 and u1.order_date is not null left join o_order_detail u2 on u2.order_id = u1.id and u2.id > 0 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/ebean-test/src/test/java/org/tests/query/TestManyWhereJoin.java b/ebean-test/src/test/java/org/tests/query/TestManyWhereJoin.java index 4fa4d5685..b2b38c42e 100644 --- a/ebean-test/src/test/java/org/tests/query/TestManyWhereJoin.java +++ b/ebean-test/src/test/java/org/tests/query/TestManyWhereJoin.java @@ -34,7 +34,7 @@ public class TestManyWhereJoin extends BaseTestCase { // join o_order u1 on u1.kcustomer_id = t0.id // where u1.status = ? ; --bind(NEW) - if (isPostgres()) { + if (isPostgresCompatible()) { assertThat(sql).contains("select distinct on (t0.id) t0.id, "); } else { assertThat(sql).contains("select distinct t0.id"); @@ -70,7 +70,7 @@ public class TestManyWhereJoin extends BaseTestCase { // where t1.order_date is not null and u1.status = ? // order by t0.id; --bind(NEW) - if (isPostgres()) { + if (platformDistinctOn()) { 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,"); @@ -101,7 +101,7 @@ public class TestManyWhereJoin extends BaseTestCase { // where u1.product_id = ? // order by t0.cretime; --bind(1) - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(sql).contains("select distinct on (t0.cretime, t0.id) t0.id, t0.status,"); } else { assertThat(sql).contains("select distinct t0.id, t0.status,"); @@ -135,7 +135,7 @@ public class TestManyWhereJoin extends BaseTestCase { // where u1.product_id = ? // order by t0.cretime - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(sql).contains("select distinct on (t0.cretime, t0.id) t0.id, t0.status,"); } else { assertThat(sql).contains("select distinct t0.id, t0.status,"); @@ -171,7 +171,7 @@ 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) - if (isPostgres()) { + if (platformDistinctOn()) { 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,"); diff --git a/ebean-test/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java b/ebean-test/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java index c617a1a60..b6b8d394d 100644 --- a/ebean-test/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java +++ b/ebean-test/src/test/java/org/tests/query/joins/TestDisjunctWhereOuterOnMany.java @@ -56,7 +56,7 @@ public class TestDisjunctWhereOuterOnMany extends BaseTestCase { assertEquals(2, list.size()); assertEquals(2, rowCount); - if (isPostgres()) { + if (platformDistinctOn()) { String expectedSql = "select distinct on (t0.id) t0.id, t0.name, t0.description, t0.version from uuone t0 left join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ?)"; assertSql(query).contains(expectedSql); diff --git a/ebean-test/src/test/java/org/tests/query/joins/TestQueryJoinOnFormula.java b/ebean-test/src/test/java/org/tests/query/joins/TestQueryJoinOnFormula.java index baee1f9d6..d790e99c9 100644 --- a/ebean-test/src/test/java/org/tests/query/joins/TestQueryJoinOnFormula.java +++ b/ebean-test/src/test/java/org/tests/query/joins/TestQueryJoinOnFormula.java @@ -115,7 +115,7 @@ public class TestQueryJoinOnFormula extends BaseTestCase { .where().isNotNull("order.shipments.order.totalAmount").query(); shipQuery.findList(); - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(shipQuery.getGeneratedSql()).contains("select distinct on (t0.id) t0.id from or_order_ship t0"); } else { assertSql(shipQuery.getGeneratedSql()).contains("select distinct t0.id from or_order_ship t0 "); diff --git a/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java b/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java index 9d7f1780b..673aa0363 100644 --- a/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java +++ b/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinct.java @@ -49,7 +49,7 @@ public class TestOrderByWithDistinct extends BaseTestCase { query.findList(); String sql = sqlOf(query); - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(sql).contains("select distinct on (t0.user_name, t0.userid) t0.userid,"); } else if (isH2()) { assertThat(sql).contains("select distinct t0.userid, t0.user_name, t0.user_type_id from muser t0"); @@ -133,7 +133,7 @@ public class TestOrderByWithDistinct extends BaseTestCase { assertEquals(1, list.size()); assertEquals(user1, list.get(0)); String generatedSql = query.getGeneratedSql(); - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(generatedSql).contains("select distinct on (t1.name, t0.user_name, t0.userid) t0.userid"); // using distinct } else { @@ -168,7 +168,7 @@ public class TestOrderByWithDistinct extends BaseTestCase { // order by t1.name; --bind(A) generatedSql = query.getGeneratedSql(); - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(generatedSql).contains("select distinct on (t1.name, t0.userid) t0.userid"); // using distinct } else { assertThat(generatedSql).contains("select distinct t0.userid"); // using distinct diff --git a/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java b/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java index f97b20167..66832db7e 100644 --- a/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java +++ b/ebean-test/src/test/java/org/tests/query/orderby/TestOrderByWithDistinctTake2.java @@ -36,7 +36,7 @@ public class TestOrderByWithDistinctTake2 extends BaseTestCase { // where lower(u1.first_name) like ? // order by t0.name; --bind(r%) - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(generatedSql).contains("select distinct on (t0.name, t0.id) t0.id, t0.name"); } else { @@ -59,7 +59,7 @@ public class TestOrderByWithDistinctTake2 extends BaseTestCase { String generatedSql = sqlOf(query); - if (isPostgres()) { + if (platformDistinctOn()) { 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"); diff --git a/ebean-test/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java b/ebean-test/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java index 9ea1847a1..ffd7c8527 100644 --- a/ebean-test/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java +++ b/ebean-test/src/test/java/org/tests/query/other/TestQueryConversationRowCount.java @@ -42,7 +42,7 @@ 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; - if (isPostgres()) { + if (platformDistinctOn()) { assertThat(generatedSql).contains("select distinct on (t0.when_created, t0.id) t0.id, t0.title, t0.isopen"); } else { diff --git a/ebean-test/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java b/ebean-test/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java index 54740de23..bca8d203a 100644 --- a/ebean-test/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java +++ b/ebean-test/src/test/java/org/tests/query/other/TestQueryRowCountWithMany.java @@ -41,7 +41,7 @@ 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); - if (isPostgres()) { + if (platformDistinctOn()) { 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 { diff --git a/ebean-test/src/test/resources/ebean.properties b/ebean-test/src/test/resources/ebean.properties index 6dbb4633d..edd806449 100644 --- a/ebean-test/src/test/resources/ebean.properties +++ b/ebean-test/src/test/resources/ebean.properties @@ -18,12 +18,12 @@ ebean.encryptKeyManager=org.tests.basic.encrypt.BasicEncyptKeyManager #ebean.autoTune.profiling=true #ebean.autoTune.profilingUpdateFrequency=5 -ebean.ddl.generate=true -ebean.ddl.run=true +#ebean.ddl.generate=true +#ebean.ddl.run=true ebean.ddl.header=-- Generated by ebean ${version} at ${timestamp} ebean.packages=org.tests,org.etest -datasource.default=h2 -#datasource.default=yugabyte +#datasource.default=h2 +datasource.default=yugabyte #datasource.h2.capturestacktrace=true #ebean.dumpMetricsOnShutdown=true