From e64a4279ff03bcd661b6ee35371cc92db50aa6f1 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 10 Sep 2020 16:49:31 +0200 Subject: [PATCH] [jOOQ/jOOQ#10616] Add Settings.implicitJoinType to govern whether an INNER or LEFT JOIN is generated --- .../org/jooq/conf/RenderImplicitJoinType.java | 40 +++++++++++++++++++ .../src/main/java/org/jooq/conf/Settings.java | 39 ++++++++++++++++++ .../java/org/jooq/impl/AbstractContext.java | 28 +++++++++++-- .../resources/xsd/jooq-runtime-3.14.0.xsd | 18 +++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 jOOQ/src/main/java/org/jooq/conf/RenderImplicitJoinType.java diff --git a/jOOQ/src/main/java/org/jooq/conf/RenderImplicitJoinType.java b/jOOQ/src/main/java/org/jooq/conf/RenderImplicitJoinType.java new file mode 100644 index 0000000000..5f71ed13c0 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/conf/RenderImplicitJoinType.java @@ -0,0 +1,40 @@ + +package org.jooq.conf; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for RenderImplicitJoinType. + * + *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <simpleType name="RenderImplicitJoinType">
+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     <enumeration value="DEFAULT"/>
+ *     <enumeration value="INNER_JOIN"/>
+ *     <enumeration value="LEFT_JOIN"/>
+ *   </restriction>
+ * </simpleType>
+ * 
+ * + */ +@XmlType(name = "RenderImplicitJoinType") +@XmlEnum +public enum RenderImplicitJoinType { + + DEFAULT, + INNER_JOIN, + LEFT_JOIN; + + public String value() { + return name(); + } + + public static RenderImplicitJoinType fromValue(String v) { + return valueOf(v); + } + +} diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 631b924848..d4d66fbf7f 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -79,6 +79,9 @@ public class Settings protected RenderOptionalKeyword renderOptionalOuterKeyword = RenderOptionalKeyword.DEFAULT; @XmlElement(defaultValue = "false") protected Boolean renderScalarSubqueriesForStoredFunctions = false; + @XmlElement(defaultValue = "DEFAULT") + @XmlSchemaType(name = "string") + protected RenderImplicitJoinType renderImplicitJoinType = RenderImplicitJoinType.DEFAULT; @XmlElement(defaultValue = "true") protected Boolean renderOrderByRownumberForEmulatedPagination = true; @XmlElement(defaultValue = "true") @@ -626,6 +629,22 @@ public class Settings this.renderScalarSubqueriesForStoredFunctions = value; } + /** + * The join type to be generated by implicit joins. + * + */ + public RenderImplicitJoinType getRenderImplicitJoinType() { + return renderImplicitJoinType; + } + + /** + * The join type to be generated by implicit joins. + * + */ + public void setRenderImplicitJoinType(RenderImplicitJoinType value) { + this.renderImplicitJoinType = value; + } + /** * Whether an additional ORDER BY rn clause should be rendered on emulated paginated queries. *

@@ -2347,6 +2366,15 @@ public class Settings return this; } + /** + * The join type to be generated by implicit joins. + * + */ + public Settings withRenderImplicitJoinType(RenderImplicitJoinType value) { + setRenderImplicitJoinType(value); + return this; + } + public Settings withRenderOrderByRownumberForEmulatedPagination(Boolean value) { setRenderOrderByRownumberForEmulatedPagination(value); return this; @@ -2942,6 +2970,7 @@ public class Settings builder.append("renderOptionalInnerKeyword", renderOptionalInnerKeyword); builder.append("renderOptionalOuterKeyword", renderOptionalOuterKeyword); builder.append("renderScalarSubqueriesForStoredFunctions", renderScalarSubqueriesForStoredFunctions); + builder.append("renderImplicitJoinType", renderImplicitJoinType); builder.append("renderOrderByRownumberForEmulatedPagination", renderOrderByRownumberForEmulatedPagination); builder.append("renderOutputForSQLServerReturningClause", renderOutputForSQLServerReturningClause); builder.append("renderParenthesisAroundSetOperationQueries", renderParenthesisAroundSetOperationQueries); @@ -3190,6 +3219,15 @@ public class Settings return false; } } + if (renderImplicitJoinType == null) { + if (other.renderImplicitJoinType!= null) { + return false; + } + } else { + if (!renderImplicitJoinType.equals(other.renderImplicitJoinType)) { + return false; + } + } if (renderOrderByRownumberForEmulatedPagination == null) { if (other.renderOrderByRownumberForEmulatedPagination!= null) { return false; @@ -3880,6 +3918,7 @@ public class Settings result = ((prime*result)+((renderOptionalInnerKeyword == null)? 0 :renderOptionalInnerKeyword.hashCode())); result = ((prime*result)+((renderOptionalOuterKeyword == null)? 0 :renderOptionalOuterKeyword.hashCode())); result = ((prime*result)+((renderScalarSubqueriesForStoredFunctions == null)? 0 :renderScalarSubqueriesForStoredFunctions.hashCode())); + result = ((prime*result)+((renderImplicitJoinType == null)? 0 :renderImplicitJoinType.hashCode())); result = ((prime*result)+((renderOrderByRownumberForEmulatedPagination == null)? 0 :renderOrderByRownumberForEmulatedPagination.hashCode())); result = ((prime*result)+((renderOutputForSQLServerReturningClause == null)? 0 :renderOutputForSQLServerReturningClause.hashCode())); result = ((prime*result)+((renderParenthesisAroundSetOperationQueries == null)? 0 :renderParenthesisAroundSetOperationQueries.hashCode())); diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java index ded644ad7c..3394f714d2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java @@ -69,6 +69,7 @@ import org.jooq.Configuration; import org.jooq.Context; import org.jooq.DSLContext; import org.jooq.ForeignKey; +import org.jooq.JoinType; // ... import org.jooq.QueryPart; import org.jooq.QueryPartInternal; @@ -81,9 +82,11 @@ import org.jooq.VisitListener; import org.jooq.VisitListenerProvider; import org.jooq.conf.ParamCastMode; import org.jooq.conf.ParamType; +import org.jooq.conf.RenderImplicitJoinType; import org.jooq.conf.Settings; import org.jooq.conf.SettingsTools; import org.jooq.conf.StatementType; +import org.jooq.tools.StringUtils; /** * @author Lukas Eder @@ -774,7 +777,7 @@ abstract class AbstractContext> extends AbstractScope imple sb.append("]"); } - static class JoinNode { + class JoinNode { final Table table; final Map, JoinNode> children; @@ -786,8 +789,25 @@ abstract class AbstractContext> extends AbstractScope imple public Table joinTree() { Table result = table; - for (Entry, JoinNode> e : children.entrySet()) - result = result.join(e.getValue().joinTree(), e.getKey().nullable() ? LEFT_OUTER_JOIN : JOIN).onKey(e.getKey()); + for (Entry, JoinNode> e : children.entrySet()) { + JoinType type; + + switch (StringUtils.defaultIfNull(settings().getRenderImplicitJoinType(), + RenderImplicitJoinType.DEFAULT)) { + case INNER_JOIN: + type = JOIN; + break; + case LEFT_JOIN: + type = LEFT_OUTER_JOIN; + break; + case DEFAULT: + default: + type = e.getKey().nullable() ? LEFT_OUTER_JOIN : JOIN; + break; + } + + result = result.join(e.getValue().joinTree(), type).onKey(e.getKey()); + } return result; } @@ -798,7 +818,7 @@ abstract class AbstractContext> extends AbstractScope imple } } - static class ScopeStackElement { + class ScopeStackElement { final int scopeLevel; int[] positions; int indent; diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.14.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.14.0.xsd index d00703469b..f6bdcbe795 100644 --- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.14.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.14.0.xsd @@ -133,6 +133,10 @@ Oracle 11g (and potentially, other databases too) implements scalar subquery cac set to true, users can automatically profit from this feature in all SQL statements.]]> + + + + ORDER BY rn clause should be rendered on emulated paginated queries.

@@ -953,6 +957,20 @@ Either <input/> or <inputExpression/> must be provided]]> + + + + + + + + + + + + + +