[jOOQ/jOOQ#15755] Add Settings.renderImplicitJoinToManyType: RenderImplicitJoinType to govern the implicit to-many join style
This commit is contained in:
parent
b96378c5ac
commit
49fa0bd34c
@ -93,6 +93,9 @@ public class Settings
|
||||
@XmlElement(defaultValue = "DEFAULT")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected RenderImplicitJoinType renderImplicitJoinType = RenderImplicitJoinType.DEFAULT;
|
||||
@XmlElement(defaultValue = "DEFAULT")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected RenderImplicitJoinType renderImplicitJoinToManyType = RenderImplicitJoinType.DEFAULT;
|
||||
@XmlElement(defaultValue = "IMPLICIT_NULL")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected RenderDefaultNullability renderDefaultNullability = RenderDefaultNullability.IMPLICIT_NULL;
|
||||
@ -1027,6 +1030,32 @@ public class Settings
|
||||
this.renderImplicitJoinType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The join type to be generated by implicit joins for to-many paths in {@link org.jooq.Select} queries.
|
||||
* <p>
|
||||
* The <code>DEFAULT</code> is <code>SCALAR_SUBQUERY</code> if the join path is implicit only, i.e. absent from
|
||||
* the <code>FROM</code> clause, to prevent accidental cartesian products, or <code>LEFT_JOIN</code> if declared
|
||||
* explicitly in the <code>FROM</code> clause. In DML statements, it is always <code>SCALAR_SUBQUERY</code>,
|
||||
* unless DML joins are supported.
|
||||
*
|
||||
*/
|
||||
public RenderImplicitJoinType getRenderImplicitJoinToManyType() {
|
||||
return renderImplicitJoinToManyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The join type to be generated by implicit joins for to-many paths in {@link org.jooq.Select} queries.
|
||||
* <p>
|
||||
* The <code>DEFAULT</code> is <code>SCALAR_SUBQUERY</code> if the join path is implicit only, i.e. absent from
|
||||
* the <code>FROM</code> clause, to prevent accidental cartesian products, or <code>LEFT_JOIN</code> if declared
|
||||
* explicitly in the <code>FROM</code> clause. In DML statements, it is always <code>SCALAR_SUBQUERY</code>,
|
||||
* unless DML joins are supported.
|
||||
*
|
||||
*/
|
||||
public void setRenderImplicitJoinToManyType(RenderImplicitJoinType value) {
|
||||
this.renderImplicitJoinToManyType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.
|
||||
*
|
||||
@ -6232,6 +6261,20 @@ public class Settings
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The join type to be generated by implicit joins for to-many paths in {@link org.jooq.Select} queries.
|
||||
* <p>
|
||||
* The <code>DEFAULT</code> is <code>SCALAR_SUBQUERY</code> if the join path is implicit only, i.e. absent from
|
||||
* the <code>FROM</code> clause, to prevent accidental cartesian products, or <code>LEFT_JOIN</code> if declared
|
||||
* explicitly in the <code>FROM</code> clause. In DML statements, it is always <code>SCALAR_SUBQUERY</code>,
|
||||
* unless DML joins are supported.
|
||||
*
|
||||
*/
|
||||
public Settings withRenderImplicitJoinToManyType(RenderImplicitJoinType value) {
|
||||
setRenderImplicitJoinToManyType(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.
|
||||
*
|
||||
@ -7646,6 +7689,7 @@ public class Settings
|
||||
builder.append("renderImplicitWindowRange", renderImplicitWindowRange);
|
||||
builder.append("renderScalarSubqueriesForStoredFunctions", renderScalarSubqueriesForStoredFunctions);
|
||||
builder.append("renderImplicitJoinType", renderImplicitJoinType);
|
||||
builder.append("renderImplicitJoinToManyType", renderImplicitJoinToManyType);
|
||||
builder.append("renderDefaultNullability", renderDefaultNullability);
|
||||
builder.append("renderCoalesceToEmptyStringInConcat", renderCoalesceToEmptyStringInConcat);
|
||||
builder.append("renderOrderByRownumberForEmulatedPagination", renderOrderByRownumberForEmulatedPagination);
|
||||
@ -8065,6 +8109,15 @@ public class Settings
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (renderImplicitJoinToManyType == null) {
|
||||
if (other.renderImplicitJoinToManyType!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!renderImplicitJoinToManyType.equals(other.renderImplicitJoinToManyType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (renderDefaultNullability == null) {
|
||||
if (other.renderDefaultNullability!= null) {
|
||||
return false;
|
||||
@ -9894,6 +9947,7 @@ public class Settings
|
||||
result = ((prime*result)+((renderImplicitWindowRange == null)? 0 :renderImplicitWindowRange.hashCode()));
|
||||
result = ((prime*result)+((renderScalarSubqueriesForStoredFunctions == null)? 0 :renderScalarSubqueriesForStoredFunctions.hashCode()));
|
||||
result = ((prime*result)+((renderImplicitJoinType == null)? 0 :renderImplicitJoinType.hashCode()));
|
||||
result = ((prime*result)+((renderImplicitJoinToManyType == null)? 0 :renderImplicitJoinToManyType.hashCode()));
|
||||
result = ((prime*result)+((renderDefaultNullability == null)? 0 :renderDefaultNullability.hashCode()));
|
||||
result = ((prime*result)+((renderCoalesceToEmptyStringInConcat == null)? 0 :renderCoalesceToEmptyStringInConcat.hashCode()));
|
||||
result = ((prime*result)+((renderOrderByRownumberForEmulatedPagination == null)? 0 :renderOrderByRownumberForEmulatedPagination.hashCode()));
|
||||
|
||||
@ -1261,7 +1261,7 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
|
||||
Table<?> t = e.getValue().joinTree();
|
||||
|
||||
result = result
|
||||
.join(t, node.joinType(LEFT_OUTER_JOIN))
|
||||
.join(t, node.joinToManyType())
|
||||
.on(onKey0(e.getKey().getForeignKey(), t, result));
|
||||
}
|
||||
|
||||
@ -1298,6 +1298,15 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
|
||||
}
|
||||
}
|
||||
|
||||
private final JoinType joinToManyType() {
|
||||
switch (defaultIfNull(Tools.settings(ctx.configuration()).getRenderImplicitJoinToManyType(), RenderImplicitJoinType.DEFAULT)) {
|
||||
case INNER_JOIN:
|
||||
return JOIN;
|
||||
default:
|
||||
return LEFT_OUTER_JOIN;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean hasJoinPaths() {
|
||||
return !pathsToOne.isEmpty() || !pathsToMany.isEmpty();
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ import static java.util.stream.Collectors.joining;
|
||||
import static org.jooq.Clause.FIELD;
|
||||
import static org.jooq.Clause.FIELD_REFERENCE;
|
||||
// ...
|
||||
import static org.jooq.conf.RenderImplicitJoinType.DEFAULT;
|
||||
import static org.jooq.conf.RenderImplicitJoinType.SCALAR_SUBQUERY;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DefaultMetaProvider.meta;
|
||||
@ -69,6 +70,7 @@ import org.jooq.RowId;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.Update;
|
||||
import org.jooq.conf.RenderImplicitJoinType;
|
||||
import org.jooq.impl.QOM.UEmpty;
|
||||
import org.jooq.impl.Tools.SimpleDataKey;
|
||||
import org.jooq.tools.StringUtils;
|
||||
@ -202,7 +204,13 @@ implements
|
||||
}
|
||||
|
||||
private final boolean implicitJoinAsScalarSubquery(Context<?> ctx, TableImpl<?> t, Table<?> root) {
|
||||
return (t.childPath != null && ctx.settings().getRenderImplicitJoinType() == SCALAR_SUBQUERY)
|
||||
return
|
||||
|
||||
// [#15754] Explicit scalar subqueries can be configured for implicit to-one paths
|
||||
(t.childPath != null && ctx.settings().getRenderImplicitJoinType() == SCALAR_SUBQUERY && !ctx.inScope(t))
|
||||
|
||||
// [#15755] The default is to render scalar subqueries for implicit to-many paths
|
||||
|| (t.parentPath != null && (ctx.settings().getRenderImplicitJoinToManyType() == DEFAULT || ctx.settings().getRenderImplicitJoinToManyType() == SCALAR_SUBQUERY) && !ctx.inScope(t))
|
||||
|
||||
// [#7508] Implicit join path references inside of DML queries have to
|
||||
// be emulated differently
|
||||
|
||||
@ -168,6 +168,15 @@ The <code>DEFAULT</code> is dependent on the nullability of the foreign key (<co
|
||||
for nullable foreign keys and <code>INNER_JOIN</code> for non-nullable foreign keys). In DML statements,
|
||||
it is always <code>SCALAR_SUBQUERY</code>, unless DML joins are supported.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="renderImplicitJoinToManyType" type="jooq-runtime:RenderImplicitJoinType" minOccurs="0" maxOccurs="1" default="DEFAULT">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The join type to be generated by implicit joins for to-many paths in {@link org.jooq.Select} queries.
|
||||
<p>
|
||||
The <code>DEFAULT</code> is <code>SCALAR_SUBQUERY</code> if the join path is implicit only, i.e. absent from
|
||||
the <code>FROM</code> clause, to prevent accidental cartesian products, or <code>LEFT_JOIN</code> if declared
|
||||
explicitly in the <code>FROM</code> clause. In DML statements, it is always <code>SCALAR_SUBQUERY</code>,
|
||||
unless DML joins are supported.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="renderDefaultNullability" type="jooq-runtime:RenderDefaultNullability" minOccurs="0" maxOccurs="1" default="IMPLICIT_NULL">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user