diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java
index b15fdead55..950d1c5ae4 100644
--- a/jOOQ/src/main/java/org/jooq/conf/Settings.java
+++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java
@@ -82,6 +82,8 @@ public class Settings
@XmlElement(defaultValue = "true")
protected Boolean fetchTriggerValuesAfterSQLServerOutput = true;
@XmlElement(defaultValue = "false")
+ protected Boolean transformAnsiJoinToTableLists = false;
+ @XmlElement(defaultValue = "false")
protected Boolean transformTableListsToAnsiJoin = false;
@XmlElement(defaultValue = "DEFAULT")
@XmlSchemaType(name = "string")
@@ -705,6 +707,38 @@ public class Settings
this.fetchTriggerValuesAfterSQLServerOutput = value;
}
+ /**
+ * Transform ANSI join to table lists if possible
+ *
+ * Historically, prior to ANSI join syntax, joins were implemented by listing tables in
+ * the FROM clause and providing join predicates in the WHERE clause, possibly using vendor specific
+ * operators like (+) (Oracle, DB2) or *= (SQL Server) for outer join
+ * support. For backwards compatibility with older RDBMS versions, ANSI joins in jOOQ code may be
+ * converted to equivalent table lists in generated SQL using this flag.
+ *
+ * This feature is available in the commercial distribution only.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isTransformAnsiJoinToTableLists() {
+ return transformAnsiJoinToTableLists;
+ }
+
+ /**
+ * Sets the value of the transformAnsiJoinToTableLists property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setTransformAnsiJoinToTableLists(Boolean value) {
+ this.transformAnsiJoinToTableLists = value;
+ }
+
/**
* Transform table lists to ANSI join if possible
*
@@ -2123,6 +2157,11 @@ public class Settings
return this;
}
+ public Settings withTransformAnsiJoinToTableLists(Boolean value) {
+ setTransformAnsiJoinToTableLists(value);
+ return this;
+ }
+
public Settings withTransformTableListsToAnsiJoin(Boolean value) {
setTransformTableListsToAnsiJoin(value);
return this;
@@ -2661,6 +2700,7 @@ public class Settings
builder.append("renderOutputForSQLServerReturningClause", renderOutputForSQLServerReturningClause);
builder.append("renderParenthesisAroundSetOperationQueries", renderParenthesisAroundSetOperationQueries);
builder.append("fetchTriggerValuesAfterSQLServerOutput", fetchTriggerValuesAfterSQLServerOutput);
+ builder.append("transformAnsiJoinToTableLists", transformAnsiJoinToTableLists);
builder.append("transformTableListsToAnsiJoin", transformTableListsToAnsiJoin);
builder.append("backslashEscaping", backslashEscaping);
builder.append("paramType", paramType);
@@ -2916,6 +2956,15 @@ public class Settings
return false;
}
}
+ if (transformAnsiJoinToTableLists == null) {
+ if (other.transformAnsiJoinToTableLists!= null) {
+ return false;
+ }
+ } else {
+ if (!transformAnsiJoinToTableLists.equals(other.transformAnsiJoinToTableLists)) {
+ return false;
+ }
+ }
if (transformTableListsToAnsiJoin == null) {
if (other.transformTableListsToAnsiJoin!= null) {
return false;
@@ -3509,6 +3558,7 @@ public class Settings
result = ((prime*result)+((renderOutputForSQLServerReturningClause == null)? 0 :renderOutputForSQLServerReturningClause.hashCode()));
result = ((prime*result)+((renderParenthesisAroundSetOperationQueries == null)? 0 :renderParenthesisAroundSetOperationQueries.hashCode()));
result = ((prime*result)+((fetchTriggerValuesAfterSQLServerOutput == null)? 0 :fetchTriggerValuesAfterSQLServerOutput.hashCode()));
+ result = ((prime*result)+((transformAnsiJoinToTableLists == null)? 0 :transformAnsiJoinToTableLists.hashCode()));
result = ((prime*result)+((transformTableListsToAnsiJoin == null)? 0 :transformTableListsToAnsiJoin.hashCode()));
result = ((prime*result)+((backslashEscaping == null)? 0 :backslashEscaping.hashCode()));
result = ((prime*result)+((paramType == null)? 0 :paramType.hashCode()));
diff --git a/jOOQ/src/main/java/org/jooq/impl/CombinedCondition.java b/jOOQ/src/main/java/org/jooq/impl/CombinedCondition.java
index 410050775f..515e831272 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CombinedCondition.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CombinedCondition.java
@@ -66,8 +66,8 @@ final class CombinedCondition extends AbstractCondition {
private static final Clause[] CLAUSES_AND = { CONDITION, CONDITION_AND };
private static final Clause[] CLAUSES_OR = { CONDITION, CONDITION_OR };
- private final Operator operator;
- private final List conditions;
+ final Operator operator;
+ final List conditions;
static Condition of(Operator operator, Condition left, Condition right) {
if (left instanceof NoCondition)
diff --git a/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java b/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java
index 3b4ee8c066..4a126a2fbc 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java
@@ -81,14 +81,14 @@ import org.jooq.conf.ParamType;
*/
final class CompareCondition extends AbstractCondition implements LikeEscapeStep {
- private static final long serialVersionUID = -747240442279619486L;
- private static final Clause[] CLAUSES = { CONDITION, CONDITION_COMPARISON };
- private static final Set REQUIRES_CAST_ON_LIKE = SQLDialect.supportedBy(DERBY, POSTGRES);
+ private static final long serialVersionUID = -747240442279619486L;
+ private static final Clause[] CLAUSES = { CONDITION, CONDITION_COMPARISON };
+ private static final Set REQUIRES_CAST_ON_LIKE = SQLDialect.supportedBy(DERBY, POSTGRES);
- private final Field> field1;
- private final Field> field2;
- private final Comparator comparator;
- private Character escape;
+ final Field> field1;
+ final Field> field2;
+ final Comparator comparator;
+ private Character escape;
CompareCondition(Field> field1, Field> field2, Comparator comparator) {
this.field1 = field1;
diff --git a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java
index 2c3f8ce9ec..4ccdcca19a 100755
--- a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java
+++ b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java
@@ -167,9 +167,9 @@ implements
- private final JoinType type;
- private final ConditionProviderImpl condition;
- private final QueryPartList> using;
+ final JoinType type;
+ final ConditionProviderImpl condition;
+ final QueryPartList> using;
JoinTable(TableLike> lhs, TableLike> rhs, JoinType type) {
@@ -488,7 +488,7 @@ implements
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private final Condition naturalCondition() {
+ final Condition naturalCondition() {
List conditions = new ArrayList<>(using.size());
for (Field> field : lhs.fields()) {
@@ -502,7 +502,7 @@ implements
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private final Condition usingCondition() {
+ final Condition usingCondition() {
List conditions = new ArrayList<>(using.size());
for (Field> field : using)
diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java
index d673a86df7..aba70125fb 100644
--- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java
@@ -192,6 +192,8 @@ import org.jooq.WindowDefinition;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.Tools.BooleanDataKey;
import org.jooq.impl.Tools.DataKey;
+import org.jooq.impl.Transform.Transformer;
+import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
/**
@@ -207,6 +209,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp
* Generated UID
*/
private static final long serialVersionUID = 1646393178384872967L;
+ private static final JooqLogger log = JooqLogger.getLogger(SelectQueryImpl.class);
private static final Clause[] CLAUSES = { SELECT };
private static final Set EMULATE_SELECT_INTO_AS_CTAS = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE);
private static final Set NO_SUPPORT_FOR_UPDATE = SQLDialect.supportedBy(CUBRID);
@@ -911,7 +914,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp
/**
* The default LIMIT / OFFSET clause in most dialects
*/
- private void toSQLReferenceLimitDefault(Context> context) {
+ private final void toSQLReferenceLimitDefault(Context> context) {
Object data = context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE);
context.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE, true);
@@ -1355,6 +1358,9 @@ final class SelectQueryImpl extends AbstractResultQuery imp
+
+
+
context.formatSeparator()
.visit(K_FROM)
.sql(' ')
@@ -1591,6 +1597,97 @@ final class SelectQueryImpl extends AbstractResultQuery imp
}
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private final void toSQLOrderBy(
Context> ctx,
Field>[] originalFields,
diff --git a/jOOQ/src/main/java/org/jooq/impl/Transform.java b/jOOQ/src/main/java/org/jooq/impl/Transform.java
new file mode 100644
index 0000000000..197b988392
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/Transform.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq.impl;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd
index 071276a4b2..53034f97d2 100644
--- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd
+++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd
@@ -177,6 +177,21 @@ included in the OUTPUT clause.
For details, see https://github.com/jOOQ/jOOQ/issues/4498.]]>
+
+
+Historically, prior to ANSI join syntax, joins were implemented by listing tables in
+the FROM clause and providing join predicates in the WHERE clause, possibly using vendor specific
+operators like (+) (Oracle, DB2) or *= (SQL Server) for outer join
+support. For backwards compatibility with older RDBMS versions, ANSI joins in jOOQ code may be
+converted to equivalent table lists in generated SQL using this flag.
+
+This flag has a limited implementation that supports inner joins (in most cases) and outer joins
+(only for simple comparison predicates).
+
+This feature is available in the commercial distribution only.]]>
+
+
@@ -186,6 +201,8 @@ operators like (+) (Oracle, DB2) or *= (SQL Server) fo
support. Migrating such join syntax is tedious. The jOOQ parser can parse the old syntax and
this flag enables the transformation to ANSI join syntax.
+This flag has not been implemented yet!
+
This feature is available in the commercial distribution only.]]>