From a89d558485e2c5ba3e7863a6be7390c589285264 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Sat, 2 Jul 2022 18:27:00 +0200 Subject: [PATCH] tests for right/full join syntax --- .../orm/test/join/OuterJoinTest.java | 130 ++++++++++++++++++ .../orm/junit/DialectFeatureChecks.java | 11 ++ 2 files changed, 141 insertions(+) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/join/OuterJoinTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/join/OuterJoinTest.java index 2d81b4e6ea..b2eabc30a6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/join/OuterJoinTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/join/OuterJoinTest.java @@ -247,6 +247,136 @@ public class OuterJoinTest { } ); } + @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFullJoin.class) + public void testJoinOrderWithFullJoin(EntityManagerFactoryScope scope) { + scope.inTransaction( em -> { + List resultList = em.createQuery( + "SELECT COALESCE(a.key, b.key, c.key, d.key), a.value, b.value, c.value, d.value " + + "FROM A a " + + "INNER JOIN B b ON a.key = b.key " + + "FULL JOIN C c ON a.key = c.key " + + "INNER JOIN D d ON d.key = c.key " + + "ORDER BY COALESCE(a.key, b.key, c.key, d.key) ASC", + Tuple.class + ) + .getResultList(); + + assertEquals( 3, resultList.size() ); + + assertEquals( "a", resultList.get( 0 ).get( 1 ) ); + assertEquals( "d", resultList.get( 0 ).get( 2 ) ); + assertEquals( "g", resultList.get( 0 ).get( 3 ) ); + assertEquals( "k", resultList.get( 0 ).get( 4 ) ); + + assertEquals( "b", resultList.get( 1 ).get( 1 ) ); + assertEquals( "e", resultList.get( 1 ).get( 2 ) ); + assertEquals( "h", resultList.get( 1 ).get( 3 ) ); + assertEquals( "l", resultList.get( 1 ).get( 4 ) ); + + assertNull( resultList.get( 2 ).get( 1 ) ); + assertNull( resultList.get( 2 ).get( 2 ) ); + assertEquals( "j", resultList.get( 2 ).get( 3 ) ); + assertEquals( "m", resultList.get( 2 ).get( 4 ) ); + } ); + } + + @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFullJoin.class) + public void testJoinOrderWithFullNormalJoin(EntityManagerFactoryScope scope) { + scope.inTransaction( em -> { + List resultList = em.createQuery( + "SELECT COALESCE(a.key, b.key, c.key, d.key), a.value, b.value, c.value, d.value " + + "FROM A a " + + "INNER JOIN B b ON a.key = b.key " + + "FULL JOIN a.cAssociationByKey c " + + "INNER JOIN D d ON d.key = c.key " + + "ORDER BY COALESCE(a.key, b.key, c.key, d.key) ASC", + Tuple.class + ) + .getResultList(); + + assertEquals( 3, resultList.size() ); + + assertEquals( "a", resultList.get( 0 ).get( 1 ) ); + assertEquals( "d", resultList.get( 0 ).get( 2 ) ); + assertEquals( "g", resultList.get( 0 ).get( 3 ) ); + assertEquals( "k", resultList.get( 0 ).get( 4 ) ); + + assertEquals( "b", resultList.get( 1 ).get( 1 ) ); + assertEquals( "e", resultList.get( 1 ).get( 2 ) ); + assertEquals( "h", resultList.get( 1 ).get( 3 ) ); + assertEquals( "l", resultList.get( 1 ).get( 4 ) ); + + assertNull( resultList.get( 2 ).get( 1 ) ); + assertNull( resultList.get( 2 ).get( 2 ) ); + assertEquals( "j", resultList.get( 2 ).get( 3 ) ); + assertEquals( "m", resultList.get( 2 ).get( 4 ) ); + } ); + } + + @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFullJoin.class) + public void testJoinOrderWithFullJoinWithIdDereference(EntityManagerFactoryScope scope) { + scope.inTransaction( em -> { + List resultList = em.createQuery( + "SELECT COALESCE(a.key, b.key, c.key, d.key), a.value, b.value, c.value, d.value " + + "FROM A a " + + "INNER JOIN B b ON a.key = b.key AND a.association.key = b.association.key " + + "FULL JOIN C c ON a.key = c.key AND a.association.key = c.association.key " + + "INNER JOIN D d ON d.key = c.key AND d.association.key = c.association.key " + + "ORDER BY COALESCE(a.key, b.key, c.key, d.key) ASC", + Tuple.class + ).getResultList(); + + assertEquals( 3, resultList.size() ); + + assertEquals( "a", resultList.get( 0 ).get( 1 ) ); + assertEquals( "d", resultList.get( 0 ).get( 2 ) ); + assertEquals( "g", resultList.get( 0 ).get( 3 ) ); + assertEquals( "k", resultList.get( 0 ).get( 4 ) ); + + assertEquals( "b", resultList.get( 1 ).get( 1 ) ); + assertEquals( "e", resultList.get( 1 ).get( 2 ) ); + assertEquals( "h", resultList.get( 1 ).get( 3 ) ); + assertEquals( "l", resultList.get( 1 ).get( 4 ) ); + + assertNull( resultList.get( 2 ).get( 1 ) ); + assertNull( resultList.get( 2 ).get( 2 ) ); + assertEquals( "j", resultList.get( 2 ).get( 3 ) ); + assertEquals( "m", resultList.get( 2 ).get( 4 ) ); + } ); + } + + @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFullJoin.class) + public void testJoinOrderWithFullNormalJoinWithIdDereference(EntityManagerFactoryScope scope) { + scope.inTransaction( em -> { + List resultList = em.createQuery( + "SELECT COALESCE(a.key, b.key, c.key, d.key), a.value, b.value, c.value, d.value " + + "FROM A a " + + "INNER JOIN B b ON a.key = b.key AND a.association.key = b.association.key " + + "FULL JOIN a.cAssociationByKey c ON a.key = c.key AND a.association.key = c.association.key " + + "INNER JOIN D d ON d.key = c.key AND d.association.key = c.association.key " + + "ORDER BY COALESCE(a.key, b.key, c.key, d.key) ASC", + Tuple.class + ).getResultList(); + + assertEquals( 3, resultList.size() ); + + assertEquals( "a", resultList.get( 0 ).get( 1 ) ); + assertEquals( "d", resultList.get( 0 ).get( 2 ) ); + assertEquals( "g", resultList.get( 0 ).get( 3 ) ); + assertEquals( "k", resultList.get( 0 ).get( 4 ) ); + + assertEquals( "b", resultList.get( 1 ).get( 1 ) ); + assertEquals( "e", resultList.get( 1 ).get( 2 ) ); + assertEquals( "h", resultList.get( 1 ).get( 3 ) ); + assertEquals( "l", resultList.get( 1 ).get( 4 ) ); + + assertNull( resultList.get( 2 ).get( 1 ) ); + assertNull( resultList.get( 2 ).get( 2 ) ); + assertEquals( "j", resultList.get( 2 ).get( 3 ) ); + assertEquals( "m", resultList.get( 2 ).get( 4 ) ); + } ); + } + @Test @RequiresDialectFeature(feature = DialectFeatureChecks.SupportsSubqueryInOnClause.class) public void testJoinOrderWithRightJoinWithInnerImplicitJoins(EntityManagerFactoryScope scope) { diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java index 97a3a5d985..413675a5ca 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java @@ -20,6 +20,7 @@ import org.hibernate.dialect.OracleDialect; import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SpannerDialect; +import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.TimeZoneSupport; import org.hibernate.dialect.TiDBDialect; import org.hibernate.query.sqm.FetchClauseType; @@ -455,4 +456,14 @@ abstract public class DialectFeatureChecks { return !( dialect instanceof TiDBDialect ); } } + + public static class SupportsFullJoin implements DialectFeatureCheck { + public boolean apply(Dialect dialect) { + // TiDB db does not support subqueries for ON condition + return !( dialect instanceof H2Dialect + || dialect instanceof MySQLDialect + || dialect instanceof SybaseDialect + || dialect instanceof DerbyDialect); + } + } }