diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java index 4022f470ac..afab1a90b2 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java @@ -5985,18 +5985,71 @@ public abstract class jOOQAbstractTest< "Ex Libris", "Orell Füssli", "Orell Füssli", "Buchhandlung im Volkshaus", "Ex Libris", "Orell Füssli"), result4.getValues(1)); - // Test inverse join relationship [#671] TODO - // ------------------------------ -// Result result5 = -// create().select(TBook_TITLE(), TBookStore_NAME()) -// .from(TBook()) -// .join(TBookToBookStore() -// .join(TBookStore()).onKey()) -// .onKey() -// .orderBy(TBook_ID(), TBookStore_NAME()) -// .fetch(); -// -// assertEquals(result4, result5); + // [#671] Test inverse join relationship + // ------------------------------------- + Result result5 = + create().select(TBook_ID(), TBookStore_NAME()) + .from(TBook()) + .join(TBookToBookStore() + .join(TBookStore()).onKey()) + .onKey() + .orderBy(TBook_ID(), TBookStore_NAME()) + .fetch(); + + assertEquals(result4, result5); + } + + @Test + public void testInverseAndNestedJoin() throws Exception { + + // Testing joining of nested joins + // ------------------------------- + Result result1 = create() + .select( + TAuthor_ID(), + TBook_ID(), + TBookStore_NAME()) + .from(TAuthor() + .join(TBook()) + .on(TAuthor_ID().equal(TBook_AUTHOR_ID()))) + .join(TBookToBookStore() + .join(TBookStore()) + .on(TBookToBookStore_BOOK_STORE_NAME().equal(TBookStore_NAME()))) + .on(TBook_ID().equal(TBookToBookStore_BOOK_ID())) + .orderBy(TBook_ID(), TBookStore_NAME()) + .fetch(); + + assertEquals(6, result1.size()); + assertEquals(asList(1, 1, 1, 2, 2, 2), result1.getValues(0)); + assertEquals(asList(1, 1, 2, 3, 3, 3), result1.getValues(1)); + assertEquals(asList( + "Ex Libris", "Orell Füssli", "Orell Füssli", + "Buchhandlung im Volkshaus", "Ex Libris", "Orell Füssli"), result1.getValues(2)); + + // Testing joining of cross products + Result result2 = create() + .select( + TAuthor_ID(), + TBook_ID(), + TBookStore_NAME()) + .from(TAuthor() + .join(TBook()) + .on(TAuthor_ID().equal(TBook_AUTHOR_ID())), + TBookToBookStore() + .join(TBookStore()) + .on(TBookToBookStore_BOOK_STORE_NAME().equal(TBookStore_NAME()))) + .where(TBook_ID().equal(TBookToBookStore_BOOK_ID())) + .orderBy(TBook_ID(), TBookStore_NAME()) + .fetch(); + + assertEquals(6, result2.size()); + assertEquals(asList(1, 1, 1, 2, 2, 2), result2.getValues(0)); + assertEquals(asList(1, 1, 2, 3, 3, 3), result2.getValues(1)); + assertEquals(asList( + "Ex Libris", "Orell Füssli", "Orell Füssli", + "Buchhandlung im Volkshaus", "Ex Libris", "Orell Füssli"), result2.getValues(2)); + + assertEquals(result1, result2); } @Test diff --git a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java index 68f55403b3..68a2e74387 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java @@ -114,7 +114,12 @@ class JoinTable extends AbstractTable implements TableOnStep, TableOnCon .sql(" ") .sql(getType(context).toSQL()) .sql(" ") - .sql(rhs); + + // [#671] Some databases formally require nested JOINS to be + // wrapped in parentheses (e.g. MySQL) + .sql(rhs instanceof JoinTable ? "(" : "") + .sql(rhs) + .sql(rhs instanceof JoinTable ? ")" : ""); switch (getType(context)) { @@ -129,7 +134,7 @@ class JoinTable extends AbstractTable implements TableOnStep, TableOnCon // Regular JOINs default: { - toSQL0(context); + toSQLJoinCondition(context); break; } } @@ -144,7 +149,7 @@ class JoinTable extends AbstractTable implements TableOnStep, TableOnCon } } - private void toSQL0(RenderContext context) { + private void toSQLJoinCondition(RenderContext context) { if (!using.isEmpty()) { context.sql(" using ("); Util.toSQLNames(context, using); @@ -169,7 +174,7 @@ class JoinTable extends AbstractTable implements TableOnStep, TableOnCon @Override public final Table as(String alias) { - return new TableAlias(this, alias); + return new TableAlias(this, alias, true); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Pivot.java b/jOOQ/src/main/java/org/jooq/impl/Pivot.java index 67f71cd08f..8fcfb4f647 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Pivot.java +++ b/jOOQ/src/main/java/org/jooq/impl/Pivot.java @@ -301,7 +301,7 @@ implements @Override public final Table as(String alias) { - return new TableAlias(this, alias); + return new TableAlias(this, alias, true); } @Override