[#6282] Emulate MySQL's STRAIGHT_JOIN in Oracle using /*+LEADING*/ hint

This commit is contained in:
lukaseder 2018-12-12 17:30:53 +01:00
parent fd40b5a90c
commit f5c161c4a4
5 changed files with 81 additions and 1 deletions

View File

@ -42,6 +42,7 @@ import static org.jooq.SQLDialect.MYSQL;
// ...
// ...
// ...
// ...
import org.jooq.impl.DSL;

View File

@ -1671,6 +1671,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
*
* @see Table#straightJoin(TableLike)
*/
@ -1680,6 +1683,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -1695,6 +1701,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -1710,6 +1719,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -1726,6 +1738,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -1741,6 +1756,9 @@ public interface SelectJoinStep<R extends Record> extends SelectWhereStep<R> {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
*
* @see DSL#table(Name)
* @see Table#straightJoin(Name)

View File

@ -2043,6 +2043,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
*/
@Support({ MYSQL })
TableOnStep<Record> straightJoin(TableLike<?> table);
@ -2050,6 +2053,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -2065,6 +2071,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -2080,6 +2089,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -2096,6 +2108,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
@ -2111,6 +2126,9 @@ public interface Table<R extends Record> extends TableLike<R>, Named {
/**
* <code>STRAIGHT_JOIN</code> a table to this table.
* <p>
* MySQL natively supports this clause. Oracle can emulate it using a
* <code>+LEADING(a b)</code> hint.
*
* @see DSL#table(Name)
*/

View File

@ -67,6 +67,7 @@ import static org.jooq.JoinType.NATURAL_LEFT_OUTER_JOIN;
import static org.jooq.JoinType.NATURAL_RIGHT_OUTER_JOIN;
import static org.jooq.JoinType.OUTER_APPLY;
import static org.jooq.JoinType.RIGHT_OUTER_JOIN;
import static org.jooq.JoinType.STRAIGHT_JOIN;
// ...
// ...
// ...
@ -76,6 +77,8 @@ import static org.jooq.SQLDialect.H2;
// ...
// ...
// ...
import static org.jooq.SQLDialect.MARIADB;
import static org.jooq.SQLDialect.MYSQL;
import static org.jooq.SQLDialect.POSTGRES;
// ...
// ...
@ -141,6 +144,7 @@ implements
*/
private static final long serialVersionUID = 8377996833996498178L;
private static final Clause[] CLAUSES = { TABLE, TABLE_JOIN };
private static final EnumSet<SQLDialect> SUPPORTS_STRAIGHT_JOIN = EnumSet.of(MARIADB, MYSQL);
private static final EnumSet<SQLDialect> EMULATE_NATURAL_JOIN = EnumSet.of(CUBRID);
private static final EnumSet<SQLDialect> EMULATE_NATURAL_OUTER_JOIN = EnumSet.of(CUBRID, H2);
private static final EnumSet<SQLDialect> EMULATE_JOIN_USING = EnumSet.of(CUBRID, H2);
@ -153,7 +157,7 @@ implements
private final JoinType type;
final JoinType type;
private final ConditionProviderImpl condition;
private final QueryPartList<Field<?>> using;
@ -358,6 +362,8 @@ implements
return LEFT_OUTER_JOIN;
else if (emulateNaturalRightOuterJoin(context))
return RIGHT_OUTER_JOIN;
else if (emulateStraightJoin(context))
return JOIN;
else
return type;
}
@ -382,6 +388,10 @@ implements
return type == NATURAL_RIGHT_OUTER_JOIN && EMULATE_NATURAL_OUTER_JOIN.contains(context.family());
}
private final boolean emulateStraightJoin(Context<?> context) {
return type == STRAIGHT_JOIN && !SUPPORTS_STRAIGHT_JOIN.contains(context.family());
}
private final void toSQLJoinCondition(Context<?> context) {
if (!using.isEmpty()) {

View File

@ -1189,6 +1189,10 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
if (Tools.isNotEmpty(distinctOn))
context.visit(K_DISTINCT_ON).sql(" (").visit(distinctOn).sql(") ");
else if (distinct)
@ -1518,6 +1522,35 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
}
}
private final void toSQLOrderBy(
Context<?> ctx,
Field<?>[] originalFields, Field<?>[] alternativeFields,