From ba1820d09f4a8ea64769ae3982ed5cbe9ee9034d Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 8 Nov 2023 14:54:21 +0100 Subject: [PATCH] [jOOQ/jOOQ#15807] Added QOM API implementation --- jOOQ/src/main/java/org/jooq/Table.java | 16 ++++++++- .../java/org/jooq/TableOuterJoinStep.java | 17 +++++++-- .../java/org/jooq/impl/AbstractJoinTable.java | 10 +++++- .../java/org/jooq/impl/AbstractTable.java | 27 +++++++++----- .../main/java/org/jooq/impl/CrossApply.java | 6 ++-- .../main/java/org/jooq/impl/CrossJoin.java | 6 ++-- .../src/main/java/org/jooq/impl/FullJoin.java | 16 +++++---- jOOQ/src/main/java/org/jooq/impl/Join.java | 10 +++--- .../main/java/org/jooq/impl/JoinTable.java | 35 +++++++++++++------ .../main/java/org/jooq/impl/LeftAntiJoin.java | 6 ++-- .../src/main/java/org/jooq/impl/LeftJoin.java | 16 +++++---- .../main/java/org/jooq/impl/LeftSemiJoin.java | 6 ++-- .../java/org/jooq/impl/NaturalFullJoin.java | 14 ++++---- .../main/java/org/jooq/impl/NaturalJoin.java | 10 +++--- .../java/org/jooq/impl/NaturalLeftJoin.java | 14 ++++---- .../java/org/jooq/impl/NaturalRightJoin.java | 14 ++++---- .../main/java/org/jooq/impl/OuterApply.java | 6 ++-- .../org/jooq/impl/PartitionJoinTable.java | 7 ++++ jOOQ/src/main/java/org/jooq/impl/QOM.java | 21 +++++++++++ .../main/java/org/jooq/impl/RightJoin.java | 16 +++++---- .../main/java/org/jooq/impl/StraightJoin.java | 10 +++--- .../main/java/org/jooq/impl/TableImpl.java | 11 ++++-- 22 files changed, 205 insertions(+), 89 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/Table.java b/jOOQ/src/main/java/org/jooq/Table.java index 580d70be8a..31e52aa6fa 100644 --- a/jOOQ/src/main/java/org/jooq/Table.java +++ b/jOOQ/src/main/java/org/jooq/Table.java @@ -90,6 +90,7 @@ import java.util.function.Function; import org.jooq.TableOptions.TableType; import org.jooq.conf.Settings; import org.jooq.impl.DSL; +import org.jooq.impl.QOM.JoinHint; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1008,7 +1009,7 @@ extends // ------------------------------------------------------------------------- /** - * Join a table to this table using a {@link JoinType} + * Join a table to this table using a {@link JoinType}. *

* Depending on the JoinType, a subsequent * {@link TableOnStep#on(Condition)} or @@ -1020,6 +1021,19 @@ extends @Support TableOptionalOnStep join(TableLike table, JoinType type); + /** + * Join a table to this table using a {@link JoinType} and {@link JoinHint}. + *

+ * Depending on the JoinType, a subsequent + * {@link TableOnStep#on(Condition)} or + * {@link TableOnStep#using(Field...)} clause is required. If it is required + * but omitted, a {@link DSL#trueCondition()}, i.e. 1 = 1 + * condition will be rendered + */ + @NotNull + @Support + TableOptionalOnStep join(TableLike table, JoinType type, JoinHint hint); + /** * INNER JOIN a table to this table. *

diff --git a/jOOQ/src/main/java/org/jooq/TableOuterJoinStep.java b/jOOQ/src/main/java/org/jooq/TableOuterJoinStep.java index 5baae37182..21bca1b0e7 100644 --- a/jOOQ/src/main/java/org/jooq/TableOuterJoinStep.java +++ b/jOOQ/src/main/java/org/jooq/TableOuterJoinStep.java @@ -37,12 +37,12 @@ */ package org.jooq; -import org.jetbrains.annotations.*; - -// ... // ... import org.jooq.impl.DSL; +import org.jooq.impl.QOM.JoinHint; + +import org.jetbrains.annotations.NotNull; /** * An intermediate type for the construction of a partitioned @@ -689,6 +689,17 @@ public interface TableOuterJoinStep { + + + + + + + + + + + diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractJoinTable.java b/jOOQ/src/main/java/org/jooq/impl/AbstractJoinTable.java index fe007c41bb..dad0ebf0ae 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractJoinTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractJoinTable.java @@ -52,13 +52,13 @@ import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.SQL; import org.jooq.Select; -import org.jooq.Table; import org.jooq.TableLike; import org.jooq.TableOnConditionStep; import org.jooq.TableOptionalOnStep; import org.jooq.TableOptions; import org.jooq.TableOuterJoinStep; import org.jooq.TablePartitionByStep; +import org.jooq.impl.QOM.JoinHint; /** * A base implementation for actual join tables and dummy join tables. @@ -249,4 +249,12 @@ implements return (J) super.join(table, type); } + // [#14906] Re-declare internal-type-returning method here, to prevent J + // from leaking into client code. + @SuppressWarnings("unchecked") + @Override + public final J join(TableLike table, JoinType type, JoinHint hint) { + return (J) super.join(table, type, hint); + } + } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java index 420e21c4f0..a23c5abb55 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java @@ -124,6 +124,7 @@ import org.jooq.UniqueKey; // ... import org.jooq.impl.QOM.Aliasable; import org.jooq.impl.QOM.GenerationLocation; +import org.jooq.impl.QOM.JoinHint; import org.jooq.tools.JooqLogger; @@ -1359,6 +1360,14 @@ implements // this only internally, to prevent leaking JoinTable into client code @Override public /* non-final */ TableOptionalOnStep join(TableLike table, JoinType type) { + return join(table, type, null); + } + + // [#14906] Declare public API return type, allowing for JoinTable to override + // this only internally, to prevent leaking JoinTable into client code + @Override + public /* non-final */ TableOptionalOnStep join(TableLike table, JoinType type, JoinHint hint) { + if (this instanceof NoTable) return new NoTableJoin(table.asTable()); else if (this instanceof NoTableJoin n) @@ -1374,29 +1383,29 @@ implements case CROSS_JOIN: return new CrossJoin(this, table); case FULL_OUTER_JOIN: - return new FullJoin(this, table); + return new FullJoin(this, table, hint); case JOIN: - return new Join(this, table); + return new Join(this, table, hint); case LEFT_ANTI_JOIN: return new LeftAntiJoin(this, table); case LEFT_OUTER_JOIN: - return new LeftJoin(this, table); + return new LeftJoin(this, table, hint); case LEFT_SEMI_JOIN: return new LeftSemiJoin(this, table); case NATURAL_FULL_OUTER_JOIN: - return new NaturalFullJoin(this, table); + return new NaturalFullJoin(this, table, hint); case NATURAL_JOIN: - return new NaturalJoin(this, table); + return new NaturalJoin(this, table, hint); case NATURAL_LEFT_OUTER_JOIN: - return new NaturalLeftJoin(this, table); + return new NaturalLeftJoin(this, table, hint); case NATURAL_RIGHT_OUTER_JOIN: - return new NaturalRightJoin(this, table); + return new NaturalRightJoin(this, table, hint); case OUTER_APPLY: return new OuterApply(this, table); case RIGHT_OUTER_JOIN: - return new RightJoin(this, table); + return new RightJoin(this, table, hint); case STRAIGHT_JOIN: - return new StraightJoin(this, table); + return new StraightJoin(this, table, hint); default: throw new IllegalArgumentException("Unsupported join type: " + type); } diff --git a/jOOQ/src/main/java/org/jooq/impl/CrossApply.java b/jOOQ/src/main/java/org/jooq/impl/CrossApply.java index 3663b5e6e3..4d82805199 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CrossApply.java +++ b/jOOQ/src/main/java/org/jooq/impl/CrossApply.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -57,7 +58,7 @@ implements { CrossApply(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.CROSS_APPLY); + super(lhs, rhs, JoinType.CROSS_APPLY, null); } // ------------------------------------------------------------------------- @@ -71,7 +72,8 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return new CrossApply(table1, table2); } diff --git a/jOOQ/src/main/java/org/jooq/impl/CrossJoin.java b/jOOQ/src/main/java/org/jooq/impl/CrossJoin.java index 950f017c1e..912df59245 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CrossJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/CrossJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -57,7 +58,7 @@ implements { CrossJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.CROSS_JOIN); + super(lhs, rhs, JoinType.CROSS_JOIN, null); } // ------------------------------------------------------------------------- @@ -71,7 +72,8 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return new CrossJoin(table1, table2); } diff --git a/jOOQ/src/main/java/org/jooq/impl/FullJoin.java b/jOOQ/src/main/java/org/jooq/impl/FullJoin.java index e63d3fdc41..292f185695 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FullJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/FullJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,12 +57,12 @@ implements QOM.FullJoin { - FullJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.FULL_OUTER_JOIN); + FullJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.FULL_OUTER_JOIN, hint); } - FullJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.FULL_OUTER_JOIN, lhsPartitionBy); + FullJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.FULL_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -75,10 +76,11 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return o != null - ? new FullJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).on(o) - : new FullJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).using(u); + ? new FullJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).on(o) + : new FullJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).using(u); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Join.java b/jOOQ/src/main/java/org/jooq/impl/Join.java index 2f2fab8cca..50738f78fe 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Join.java +++ b/jOOQ/src/main/java/org/jooq/impl/Join.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,8 +57,8 @@ implements QOM.Join { - Join(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.JOIN); + Join(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.JOIN, hint); } // ------------------------------------------------------------------------- @@ -71,8 +72,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return o != null ? new Join(table1, table2).on(o) : new Join(table1, table2).using(u); + return o != null ? new Join(table1, table2, h).on(o) : new Join(table1, table2, h).using(u); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java index e850d40de6..036f13f384 100755 --- a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java @@ -140,6 +140,7 @@ import org.jooq.TableOptions; // ... import org.jooq.conf.RenderOptionalKeyword; import org.jooq.exception.DataAccessException; +import org.jooq.impl.QOM.JoinHint; import org.jooq.impl.QOM.Lateral; import org.jooq.impl.QOM.UnmodifiableList; @@ -168,14 +169,15 @@ abstract class JoinTable> extends AbstractJoinTable { final QueryPartList> rhsPartitionBy; final JoinType type; + final JoinHint hint; final ConditionProviderImpl condition; final QueryPartList> using; - JoinTable(TableLike lhs, TableLike rhs, JoinType type) { - this(lhs, rhs, type, emptyList()); + JoinTable(TableLike lhs, TableLike rhs, JoinType type, JoinHint hint) { + this(lhs, rhs, type, hint, emptyList()); } - JoinTable(TableLike lhs, TableLike rhs, JoinType type, Collection> lhsPartitionBy) { + JoinTable(TableLike lhs, TableLike rhs, JoinType type, JoinHint hint, Collection> lhsPartitionBy) { super(TableOptions.expression(), N_JOIN); this.lhs = lhs.asTable(); @@ -183,6 +185,7 @@ abstract class JoinTable> extends AbstractJoinTable { this.lhsPartitionBy = new QueryPartList<>(lhsPartitionBy); this.rhsPartitionBy = new QueryPartList<>(); this.type = type; + this.hint = hint; this.condition = new ConditionProviderImpl(); this.using = new QueryPartList<>(); } @@ -198,7 +201,7 @@ abstract class JoinTable> extends AbstractJoinTable { if (lhs == newLhs && rhs == newRhs && condition == newCondition) return (J) this; - return construct(newLhs, lhsPartitionBy, rhsPartitionBy, newRhs, newCondition, using); + return construct(newLhs, lhsPartitionBy, rhsPartitionBy, newRhs, newCondition, using, hint); } // ------------------------------------------------------------------------ @@ -823,7 +826,8 @@ abstract class JoinTable> extends AbstractJoinTable { Collection> partitionBy2, Table table2, Condition on, - Collection> using + Collection> using, + JoinHint hint ); public final Table $table1() { @@ -831,7 +835,7 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $table1(Table t1) { - return construct(t1, $partitionBy1(), $partitionBy2(), $table2(), $on(), $using()); + return construct(t1, $partitionBy1(), $partitionBy2(), $table2(), $on(), $using(), $hint()); } public final UnmodifiableList> $partitionBy1() { @@ -839,7 +843,7 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $partitionBy1(Collection> p1) { - return construct($table1(), p1, $partitionBy2(), $table2(), $on(), $using()); + return construct($table1(), p1, $partitionBy2(), $table2(), $on(), $using(), $hint()); } public final UnmodifiableList> $partitionBy2() { @@ -847,7 +851,7 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $partitionBy2(Collection> p2) { - return construct($table1(), $partitionBy1(), p2, $table2(), $on(), $using()); + return construct($table1(), $partitionBy1(), p2, $table2(), $on(), $using(), $hint()); } public final Table $table2() { @@ -855,7 +859,15 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $table2(Table t2) { - return construct($table1(), $partitionBy1(), $partitionBy2(), t2, $on(), $using()); + return construct($table1(), $partitionBy1(), $partitionBy2(), t2, $on(), $using(), $hint()); + } + + public final JoinHint $hint() { + return hint; + } + + public final J $hint(JoinHint newHint) { + return construct($table1(), $partitionBy1(), $partitionBy2(), $table2(), $on(), $using(), newHint); } public final Condition $on() { @@ -863,7 +875,7 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $on(Condition o) { - return construct($table1(), $partitionBy1(), $partitionBy2(), $table2(), o, emptyList()); + return construct($table1(), $partitionBy1(), $partitionBy2(), $table2(), o, emptyList(), $hint()); } public final UnmodifiableList> $using() { @@ -871,7 +883,7 @@ abstract class JoinTable> extends AbstractJoinTable { } public final J $using(Collection> u) { - return construct($table1(), $partitionBy1(), $partitionBy2(), $table2(), null, u); + return construct($table1(), $partitionBy1(), $partitionBy2(), $table2(), null, u, $hint()); } @@ -903,6 +915,7 @@ abstract class JoinTable> extends AbstractJoinTable { + } diff --git a/jOOQ/src/main/java/org/jooq/impl/LeftAntiJoin.java b/jOOQ/src/main/java/org/jooq/impl/LeftAntiJoin.java index 653419a081..52ccb7d51d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LeftAntiJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/LeftAntiJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -57,7 +58,7 @@ implements { LeftAntiJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.LEFT_ANTI_JOIN); + super(lhs, rhs, JoinType.LEFT_ANTI_JOIN, null); } // ------------------------------------------------------------------------- @@ -71,7 +72,8 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return o != null ? new LeftAntiJoin(table1, table2).on(o) : new LeftAntiJoin(table1, table2).using(u); } diff --git a/jOOQ/src/main/java/org/jooq/impl/LeftJoin.java b/jOOQ/src/main/java/org/jooq/impl/LeftJoin.java index 19989b647e..fab1aa3e43 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LeftJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/LeftJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,12 +57,12 @@ implements QOM.LeftJoin { - LeftJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.LEFT_OUTER_JOIN); + LeftJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.LEFT_OUTER_JOIN, hint); } - LeftJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.LEFT_OUTER_JOIN, lhsPartitionBy); + LeftJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.LEFT_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -75,10 +76,11 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return o != null - ? new LeftJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).on(o) - : new LeftJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).using(u); + ? new LeftJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).on(o) + : new LeftJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).using(u); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/LeftSemiJoin.java b/jOOQ/src/main/java/org/jooq/impl/LeftSemiJoin.java index 5c4e272e17..c99e2a35af 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LeftSemiJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/LeftSemiJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -57,7 +58,7 @@ implements { LeftSemiJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.LEFT_SEMI_JOIN); + super(lhs, rhs, JoinType.LEFT_SEMI_JOIN, null); } // ------------------------------------------------------------------------- @@ -71,7 +72,8 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return o != null ? new LeftSemiJoin(table1, table2).on(o) : new LeftSemiJoin(table1, table2).using(u); } diff --git a/jOOQ/src/main/java/org/jooq/impl/NaturalFullJoin.java b/jOOQ/src/main/java/org/jooq/impl/NaturalFullJoin.java index 349b2829fa..28314c58df 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NaturalFullJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/NaturalFullJoin.java @@ -47,6 +47,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -58,12 +59,12 @@ implements QOM.NaturalFullJoin { - NaturalFullJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.NATURAL_FULL_OUTER_JOIN, emptyList()); + NaturalFullJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.NATURAL_FULL_OUTER_JOIN, hint, emptyList()); } - NaturalFullJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.NATURAL_FULL_OUTER_JOIN, lhsPartitionBy); + NaturalFullJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.NATURAL_FULL_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -77,8 +78,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return new NaturalFullJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2); + return new NaturalFullJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/NaturalJoin.java b/jOOQ/src/main/java/org/jooq/impl/NaturalJoin.java index b0b8282fbc..1accd2bd59 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NaturalJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/NaturalJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,8 +57,8 @@ implements QOM.NaturalJoin { - NaturalJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.NATURAL_JOIN); + NaturalJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.NATURAL_JOIN, hint); } // ------------------------------------------------------------------------- @@ -71,8 +72,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return new NaturalJoin(table1, table2); + return new NaturalJoin(table1, table2, h); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/NaturalLeftJoin.java b/jOOQ/src/main/java/org/jooq/impl/NaturalLeftJoin.java index 0645b9efe7..da911080a0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NaturalLeftJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/NaturalLeftJoin.java @@ -47,6 +47,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -58,12 +59,12 @@ implements QOM.NaturalLeftJoin { - NaturalLeftJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.NATURAL_LEFT_OUTER_JOIN, emptyList()); + NaturalLeftJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.NATURAL_LEFT_OUTER_JOIN, hint, emptyList()); } - NaturalLeftJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.NATURAL_LEFT_OUTER_JOIN, lhsPartitionBy); + NaturalLeftJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.NATURAL_LEFT_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -77,8 +78,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return new NaturalLeftJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2); + return new NaturalLeftJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/NaturalRightJoin.java b/jOOQ/src/main/java/org/jooq/impl/NaturalRightJoin.java index 421b0eb837..be64371c19 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NaturalRightJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/NaturalRightJoin.java @@ -47,6 +47,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -58,12 +59,12 @@ implements QOM.NaturalRightJoin { - NaturalRightJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.NATURAL_RIGHT_OUTER_JOIN, emptyList()); + NaturalRightJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.NATURAL_RIGHT_OUTER_JOIN, hint, emptyList()); } - NaturalRightJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.NATURAL_RIGHT_OUTER_JOIN, lhsPartitionBy); + NaturalRightJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.NATURAL_RIGHT_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -77,8 +78,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return new NaturalRightJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2); + return new NaturalRightJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/OuterApply.java b/jOOQ/src/main/java/org/jooq/impl/OuterApply.java index 7fb3db0f35..44907e4dd0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/OuterApply.java +++ b/jOOQ/src/main/java/org/jooq/impl/OuterApply.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -57,7 +58,7 @@ implements { OuterApply(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.OUTER_APPLY); + super(lhs, rhs, JoinType.OUTER_APPLY, null); } // ------------------------------------------------------------------------- @@ -71,7 +72,8 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return new OuterApply(table1, table2); } diff --git a/jOOQ/src/main/java/org/jooq/impl/PartitionJoinTable.java b/jOOQ/src/main/java/org/jooq/impl/PartitionJoinTable.java index 3d43eec706..9faf3efd80 100644 --- a/jOOQ/src/main/java/org/jooq/impl/PartitionJoinTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/PartitionJoinTable.java @@ -55,6 +55,7 @@ import org.jooq.Table; import org.jooq.TableLike; import org.jooq.TableOuterJoinStep; import org.jooq.TablePartitionByStep; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -305,6 +306,12 @@ final class PartitionJoinTable implements TableOuterJoinStep { + + + + + + diff --git a/jOOQ/src/main/java/org/jooq/impl/QOM.java b/jOOQ/src/main/java/org/jooq/impl/QOM.java index 1e406c5824..9307837916 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QOM.java +++ b/jOOQ/src/main/java/org/jooq/impl/QOM.java @@ -1041,8 +1041,10 @@ public final class QOM { { @NotNull Table $table1(); @NotNull Table $table2(); + @Nullable JoinHint $hint(); @NotNull J $table1(Table table1); @NotNull J $table2(Table table2); + @NotNull J $hint(JoinHint hint); } public sealed interface CrossJoin @@ -6063,6 +6065,7 @@ public final class QOM { /** * The data type to try to cast the value to */ + @Override @NotNull default DataType $dataType() { return $arg2(); } /** @@ -8586,6 +8589,24 @@ public final class QOM { } } + /** + * The JoinHint type. + *

+ * A hint for join algorithms. + */ + public enum JoinHint { + HASH(keyword("hash")), + LOOP(keyword("loop")), + MERGE(keyword("merge")), + ; + + final Keyword keyword; + + private JoinHint(Keyword keyword) { + this.keyword = keyword; + } + } + // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/RightJoin.java b/jOOQ/src/main/java/org/jooq/impl/RightJoin.java index c9cc1cf92c..6fb5540779 100644 --- a/jOOQ/src/main/java/org/jooq/impl/RightJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/RightJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,12 +57,12 @@ implements QOM.RightJoin { - RightJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.RIGHT_OUTER_JOIN); + RightJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.RIGHT_OUTER_JOIN, hint); } - RightJoin(TableLike lhs, TableLike rhs, Collection> lhsPartitionBy) { - super(lhs, rhs, JoinType.RIGHT_OUTER_JOIN, lhsPartitionBy); + RightJoin(TableLike lhs, TableLike rhs, JoinHint hint, Collection> lhsPartitionBy) { + super(lhs, rhs, JoinType.RIGHT_OUTER_JOIN, hint, lhsPartitionBy); } // ------------------------------------------------------------------------- @@ -75,10 +76,11 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { return o != null - ? new RightJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).on(o) - : new RightJoin(table1, table2, partitionBy1).partitionBy0(partitionBy2).using(u); + ? new RightJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).on(o) + : new RightJoin(table1, table2, h, partitionBy1).partitionBy0(partitionBy2).using(u); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/StraightJoin.java b/jOOQ/src/main/java/org/jooq/impl/StraightJoin.java index 3a91165763..e397f5e8e4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/StraightJoin.java +++ b/jOOQ/src/main/java/org/jooq/impl/StraightJoin.java @@ -45,6 +45,7 @@ import org.jooq.JoinType; import org.jooq.Record; import org.jooq.Table; import org.jooq.TableLike; +import org.jooq.impl.QOM.JoinHint; /** * @author Lukas Eder @@ -56,8 +57,8 @@ implements QOM.StraightJoin { - StraightJoin(TableLike lhs, TableLike rhs) { - super(lhs, rhs, JoinType.STRAIGHT_JOIN); + StraightJoin(TableLike lhs, TableLike rhs, JoinHint hint) { + super(lhs, rhs, JoinType.STRAIGHT_JOIN, hint); } // ------------------------------------------------------------------------- @@ -71,8 +72,9 @@ implements Collection> partitionBy2, Table table2, Condition o, - Collection> u + Collection> u, + JoinHint h ) { - return o != null ? new StraightJoin(table1, table2).on(o) : new StraightJoin(table1, table2).using(u); + return o != null ? new StraightJoin(table1, table2, h).on(o) : new StraightJoin(table1, table2, h).using(u); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java index feeebfbd9b..101456f847 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java @@ -78,7 +78,6 @@ import org.jooq.ForeignKey; import org.jooq.InverseForeignKey; import org.jooq.JoinType; import org.jooq.Name; -import org.jooq.Path; // ... import org.jooq.Record; import org.jooq.Row; @@ -89,6 +88,7 @@ import org.jooq.Table; import org.jooq.TableLike; import org.jooq.TableOptionalOnStep; import org.jooq.TableOptions; +import org.jooq.impl.QOM.JoinHint; import org.jooq.impl.QOM.UEmpty; import org.jooq.tools.StringUtils; @@ -327,9 +327,9 @@ implements final Condition pathCondition() { if (childPath != null) - return wrapForImplicitJoin(new Join(path, this).onKey(childPath).condition.getWhere()); + return wrapForImplicitJoin(new Join(path, this, null).onKey(childPath).condition.getWhere()); else if (parentPath != null) - return wrapForImplicitJoin(new Join(this, path).onKey(parentPath.getForeignKey()).condition.getWhere()); + return wrapForImplicitJoin(new Join(this, path, null).onKey(parentPath.getForeignKey()).condition.getWhere()); else return noCondition(); } @@ -570,6 +570,11 @@ implements return super.join(table, type); } + @Override + public final TableOptionalOnStep join(TableLike table, JoinType type, JoinHint hint) { + return super.join(table, type, hint); + } + // ------------------------------------------------------------------------- // XXX: FieldsTrait "undeprecations" for generated code // -------------------------------------------------------------------------