diff --git a/jOOQ/src/main/java/org/jooq/ParserCLI.java b/jOOQ/src/main/java/org/jooq/ParserCLI.java index 7a34f7ba6e..bae06abf60 100644 --- a/jOOQ/src/main/java/org/jooq/ParserCLI.java +++ b/jOOQ/src/main/java/org/jooq/ParserCLI.java @@ -48,6 +48,7 @@ import org.jooq.conf.RenderNameCase; import org.jooq.conf.RenderQuotedNames; import org.jooq.conf.Settings; import org.jooq.conf.TransformUnneededArithmeticExpressions; +import org.jooq.conf.Transformation; import org.jooq.impl.DSL; import org.jooq.impl.ParserException; @@ -106,10 +107,28 @@ public final class ParserCLI { settings.setTransformTableListsToAnsiJoin(true); if (a.transformUnneededArithmetic != null) settings.setTransformUnneededArithmeticExpressions(a.transformUnneededArithmetic); - if (a.transformRownum) + if (a.transformQualify != null) + settings.setTransformRownum(a.transformQualify); + if (a.transformRownum != null) settings.setTransformRownum(a.transformRownum); } + private static > E parseInteractive(Class type, E current, Args a, String arg) { + E result = current; + + try { + if (arg != null) + result = Enum.valueOf(type, arg.toUpperCase()); + + displayKeywords(a); + } + catch (IllegalArgumentException e) { + invalid(arg, type); + } + + return result; + } + private static final void interactiveMode(DSLContext ctx, Args a) { Scanner scan = new Scanner(System.in); @@ -148,48 +167,16 @@ public final class ParserCLI { displayFormatted(a); } else if ("k".equals(flag) || "keyword".equals(flag)) { - try { - if (arg != null) - a.keywords = RenderKeywordCase.valueOf(arg.toUpperCase()); - - displayKeywords(a); - } - catch (IllegalArgumentException e) { - invalid(arg, RenderKeywordCase.class); - } + a.keywords = parseInteractive(RenderKeywordCase.class, a.keywords, a, arg); } else if ("i".equals(flag) || "identifier".equals(flag)) { - try { - if (arg != null) - a.name = RenderNameCase.valueOf(arg.toUpperCase()); - - displayIdentifiers(a); - } - catch (IllegalArgumentException e) { - invalid(arg, RenderNameCase.class); - } + a.name = parseInteractive(RenderNameCase.class, a.name, a, arg); } else if ("Q".equals(flag) || "quoted".equals(flag)) { - try { - if (arg != null) - a.quoted = RenderQuotedNames.valueOf(arg.toUpperCase()); - - displayQuoted(a); - } - catch (IllegalArgumentException e) { - invalid(arg, RenderQuotedNames.class); - } + a.quoted = parseInteractive(RenderQuotedNames.class, a.quoted, a, arg); } else if ("F".equals(flag) || "from-dialect".equals(flag)) { - try { - if (arg != null) - a.fromDialect = SQLDialect.valueOf(arg.toUpperCase()); - - displayFromDialect(a); - } - catch (IllegalArgumentException e) { - invalid(arg, SQLDialect.class); - } + a.fromDialect = parseInteractive(SQLDialect.class, a.fromDialect, a, arg); } else if ("render-coalesce-to-empty-string-in-concat".equals(flag)) { if (arg != null) @@ -203,11 +190,11 @@ public final class ParserCLI { displayTransformAnsiJoinToTablesLists(a); } + else if ("transform-qualify".equals(flag)) { + a.transformQualify = parseInteractive(Transformation.class, a.transformQualify, a, arg); + } else if ("transform-rownum".equals(flag)) { - if (arg != null) - a.transformRownum = Boolean.parseBoolean(arg.toLowerCase()); - - displayTransformRownum(a); + a.transformRownum = parseInteractive(Transformation.class, a.transformRownum, a, arg); } else if ("transform-table-lists-to-ansi-join".equals(flag)) { if (arg != null) @@ -216,28 +203,12 @@ public final class ParserCLI { displayTransformTableListsToAnsiJoin(a); } else if ("transform-unneeded-arithmetic".equals(flag)) { - try { - if (arg != null) - a.transformUnneededArithmetic = TransformUnneededArithmeticExpressions.valueOf(arg.toUpperCase()); - - displayTransformUnneededArithmetic(a); - } - catch (IllegalArgumentException e) { - invalid(arg, TransformUnneededArithmeticExpressions.class); - } + a.transformUnneededArithmetic = parseInteractive(TransformUnneededArithmeticExpressions.class, a.transformUnneededArithmetic, a, arg); } // [#9144] /t maintained for backwards compatibility else if ("t".equals(flag) || "T".equals(flag) || "to-dialect".equals(flag)) { - try { - if (arg != null) - a.toDialect = SQLDialect.valueOf(arg.toUpperCase()); - - displayToDialect(a); - } - catch (IllegalArgumentException e) { - invalid(arg, SQLDialect.class); - } + a.toDialect = parseInteractive(SQLDialect.class, a.toDialect, a, arg); } } } @@ -277,6 +248,8 @@ public final class ParserCLI { displayIdentifiers(a); displayQuoted(a); displayTransformAnsiJoinToTablesLists(a); + displayTransformQualify(a); + displayTransformRownum(a); displayTransformTableListsToAnsiJoin(a); displayTransformUnneededArithmetic(a); } @@ -313,6 +286,10 @@ public final class ParserCLI { System.out.println("Transform ANSI join to table lists : " + a.transformAnsiJoinToTableLists); } + private static void displayTransformQualify(Args a) { + System.out.println("Transform QUALIFY : " + a.transformQualify); + } + private static void displayTransformRownum(Args a) { System.out.println("Transform ROWNUM : " + a.transformRownum); } @@ -354,132 +331,80 @@ public final class ParserCLI { } } - private static final Args parse(String[] args) { + private static final > E parse(Class type, String value) { + try { + return Enum.valueOf(type, value.toUpperCase()); + } + catch (IllegalArgumentException e) { + invalid(value, type); + throw e; + } + } + + @SuppressWarnings("unchecked") + private static final > Args parse(String[] args) { Args result = new Args(); - argsLoop: for (int i = 0; i < args.length; i++) { - if ("-f".equals(args[i]) || "--formatted".equals(args[i])) { - result.formatted = true; - } - else if ("-k".equals(args[i]) || "--keyword".equals(args[i])) { - try { - result.keywords = RenderKeywordCase.valueOf(args[++i].toUpperCase()); - continue argsLoop; - } - catch (IllegalArgumentException e) { - invalid(args[i], RenderKeywordCase.class); - throw e; - } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -k / --keyword requires argument"); - throw e; - } - } - else if ("-i".equals(args[i]) || "--identifier".equals(args[i])) { - try { - result.keywords = RenderKeywordCase.valueOf(args[++i].toUpperCase()); - continue argsLoop; - } - catch (IllegalArgumentException e) { - invalid(args[i], RenderKeywordCase.class); - throw e; - } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -i / --identifier requires argument"); - throw e; - } - } - else if ("-Q".equals(args[i]) || "--quoted".equals(args[i])) { - try { - result.quoted = RenderQuotedNames.valueOf(args[++i].toUpperCase()); - continue argsLoop; - } - catch (IllegalArgumentException e) { - invalid(args[i], RenderQuotedNames.class); - throw e; - } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -Q / --quoted requires argument"); - throw e; - } - } - else if ("-F".equals(args[i]) || "--from-dialect".equals(args[i])) { - try { - result.fromDialect = SQLDialect.valueOf(args[++i].toUpperCase()); - continue argsLoop; - } - catch (IllegalArgumentException e) { - invalid(args[i], SQLDialect.class); - throw e; - } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -F / --from-dialect requires argument"); - throw e; - } - } + Class> enumArgument = null; - // [#9144] -t maintained for backwards compatibility - else if ("-t".equals(args[i]) || "-T".equals(args[i]) || "--to-dialect".equals(args[i])) { - try { - result.toDialect = SQLDialect.valueOf(args[++i].toUpperCase()); - continue argsLoop; + try { + if ("-f".equals(args[i]) || "--formatted".equals(args[i])) { + result.formatted = true; } - catch (IllegalArgumentException e) { - invalid(args[i], SQLDialect.class); - throw e; + else if ("-k".equals(args[i]) || "--keyword".equals(args[i])) { + result.keywords = parse((Class) (enumArgument = RenderKeywordCase.class), args[++i]); } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -T / --to-dialect requires argument"); - throw e; + else if ("-i".equals(args[i]) || "--identifier".equals(args[i])) { + result.name = parse((Class) (enumArgument = RenderNameCase.class), args[++i]); } - } - else if ("--render-coalesce-to-empty-string-in-concat".equals(args[i])) { - result.renderCoalesceToEmptyStringInConcat = true; - } - else if ("--transform-ansi-join-to-table-lists".equals(args[i])) { - result.transformAnsiJoinToTableLists = true; - } - else if ("--transform-rownum".equals(args[i])) { - result.transformRownum = true; - } - else if ("--transform-table-lists-to-ansi-join".equals(args[i])) { - result.transformTableListsToAnsiJoin = true; - } - else if ("--transform-unneeded-arithmetic".equals(args[i])) { - try { - result.transformUnneededArithmetic = TransformUnneededArithmeticExpressions.valueOf(args[++i].toUpperCase()); - continue argsLoop; + else if ("-Q".equals(args[i]) || "--quoted".equals(args[i])) { + result.quoted = parse((Class) (enumArgument = RenderQuotedNames.class), args[++i]); } - catch (IllegalArgumentException e) { - invalid(args[i], TransformUnneededArithmeticExpressions.class); - throw e; + else if ("-F".equals(args[i]) || "--from-dialect".equals(args[i])) { + result.fromDialect = parse((Class) (enumArgument = SQLDialect.class), args[++i]); } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag --transform-unneeded-arithmetic requires argument"); - throw e; + + // [#9144] -t maintained for backwards compatibility + else if ("-t".equals(args[i]) || "-T".equals(args[i]) || "--to-dialect".equals(args[i])) { + result.toDialect = parse((Class) (enumArgument = SQLDialect.class), args[++i]); } - } - else if ("-s".equals(args[i]) || "--sql".equals(args[i])) { - try { + else if ("--render-coalesce-to-empty-string-in-concat".equals(args[i])) { + result.renderCoalesceToEmptyStringInConcat = true; + } + else if ("--transform-ansi-join-to-table-lists".equals(args[i])) { + result.transformAnsiJoinToTableLists = true; + } + else if ("--transform-qualify".equals(args[i])) { + result.transformQualify = parse((Class) (enumArgument = Transformation.class), args[++i]); + } + else if ("--transform-rownum".equals(args[i])) { + result.transformRownum = parse((Class) (enumArgument = Transformation.class), args[++i]); + } + else if ("--transform-table-lists-to-ansi-join".equals(args[i])) { + result.transformTableListsToAnsiJoin = true; + } + else if ("--transform-unneeded-arithmetic".equals(args[i])) { + result.transformUnneededArithmetic = parse((Class) (enumArgument = TransformUnneededArithmeticExpressions.class), args[++i]); + } + else if ("-s".equals(args[i]) || "--sql".equals(args[i])) { result.sql = args[++i]; - continue argsLoop; } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Flag -s / --sql requires argument"); - throw e; + else if ("-I".equals(args[i]) || "--interactive".equals(args[i])) { + result.interactive = true; + } + else if ("-h".equals(args[i]) || "--help".equals(args[i])) { + help(); + result.done = true; + } + else { + System.out.println("Unknown flag: " + args[i] + ". Use -h or --help"); + throw new RuntimeException(); } } - else if ("-I".equals(args[i]) || "--interactive".equals(args[i])) { - result.interactive = true; - } - else if ("-h".equals(args[i]) || "--help".equals(args[i])) { - help(); - result.done = true; - } - else { - System.out.println("Unknown flag: " + args[i] + ". Use -h or --help"); - throw new RuntimeException(); + catch (ArrayIndexOutOfBoundsException e) { + System.out.println("Flag " + args[i - 1] + " requires <" + (enumArgument != null ? enumArgument.getName() : "Unknown") + "> argument"); + throw e; } } @@ -508,7 +433,8 @@ public final class ParserCLI { System.out.println("Commercial distribution only features:"); System.out.println(" --render-coalesce-to-empty-string-in-concat "); System.out.println(" --transform-ansi-join-to-table-lists "); - System.out.println(" --transform-rownum "); + System.out.println(" --transform-qualify "); + System.out.println(" --transform-rownum "); System.out.println(" --transform-table-lists-to-ansi-join "); System.out.println(" --transform-unneeded-arithmetic "); System.out.println(""); @@ -530,7 +456,8 @@ public final class ParserCLI { System.out.println("Commercial distribution only features:"); System.out.println(" /render-coalesce-to-empty-string-in-concat "); System.out.println(" /transform-ansi-join-to-table-lists "); - System.out.println(" /transform-rownum "); + System.out.println(" /transform-qualify "); + System.out.println(" /transform-rownum "); System.out.println(" /transform-table-lists-to-ansi-join "); System.out.println(" /transform-unneeded-arithmetic "); System.out.println(""); @@ -551,7 +478,8 @@ public final class ParserCLI { boolean done; boolean renderCoalesceToEmptyStringInConcat; boolean transformAnsiJoinToTableLists; - boolean transformRownum; + Transformation transformQualify; + Transformation transformRownum; boolean transformTableListsToAnsiJoin; TransformUnneededArithmeticExpressions transformUnneededArithmetic = TransformUnneededArithmeticExpressions.NEVER; } diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index cb7f606eaf..f40b998c49 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -111,8 +111,9 @@ public class Settings protected Transformation transformQualify = Transformation.WHEN_NEEDED; @XmlElement(defaultValue = "false") protected Boolean transformTableListsToAnsiJoin = false; - @XmlElement(defaultValue = "false") - protected Boolean transformRownum = false; + @XmlElement(defaultValue = "NEVER") + @XmlSchemaType(name = "string") + protected Transformation transformRownum = Transformation.NEVER; @XmlElement(defaultValue = "NEVER") @XmlSchemaType(name = "string") protected TransformUnneededArithmeticExpressions transformUnneededArithmeticExpressions = TransformUnneededArithmeticExpressions.NEVER; @@ -1078,24 +1079,23 @@ public class Settings *

* This feature is available in the commercial distribution only. * - * @return - * possible object is - * {@link Boolean } - * */ - public Boolean isTransformRownum() { + public Transformation getTransformRownum() { return transformRownum; } /** - * Sets the value of the transformRownum property. + * Transform ROWNUM expressions to corresponding LIMIT clauses or ROW_NUMBER() expressions. + *

+ * In Oracle 11g and less, ROWNUM filtering was the most popular way to paginate. This pseudo + * column is not supported in other RDBMS, and should be replaced in Oracle 12c by the FETCH clause or + * ROW_NUMBER() OVER () filtering. This transformation allows for replacing such a filter by + * equivalent SQL, if possible. + *

+ * This feature is available in the commercial distribution only. * - * @param value - * allowed object is - * {@link Boolean } - * */ - public void setTransformRownum(Boolean value) { + public void setTransformRownum(Transformation value) { this.transformRownum = value; } @@ -3036,7 +3036,18 @@ public class Settings return this; } - public Settings withTransformRownum(Boolean value) { + /** + * Transform ROWNUM expressions to corresponding LIMIT clauses or ROW_NUMBER() expressions. + *

+ * In Oracle 11g and less, ROWNUM filtering was the most popular way to paginate. This pseudo + * column is not supported in other RDBMS, and should be replaced in Oracle 12c by the FETCH clause or + * ROW_NUMBER() OVER () filtering. This transformation allows for replacing such a filter by + * equivalent SQL, if possible. + *

+ * This feature is available in the commercial distribution only. + * + */ + public Settings withTransformRownum(Transformation value) { setTransformRownum(value); return this; } diff --git a/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java b/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java index dab04ed302..f24c77ab2c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java @@ -86,7 +86,7 @@ import static org.jooq.impl.Tools.castIfNeeded; import static org.jooq.impl.Tools.embeddedFields; import static org.jooq.impl.Tools.nullSafe; import static org.jooq.impl.Tools.nullableIf; -import static org.jooq.impl.Transformations.applyTransformationForInConditionSubqueryWithLimitToDerivedTable; +import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable; import static org.jooq.impl.Transformations.subqueryWithLimit; import java.util.Set; @@ -140,7 +140,7 @@ final class CompareCondition extends AbstractCondition implements LikeEscapeStep ctx.visit(row(embeddedFields(field1)).compare(comparator, embeddedFields(field2))); else if ((comparator == IN || comparator == NOT_IN) && (s = subqueryWithLimit(field2)) != null - && applyTransformationForInConditionSubqueryWithLimitToDerivedTable(ctx)) { + && transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) { diff --git a/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java b/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java index da1b4bc3de..dadfba7543 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/QuantifiedComparisonCondition.java @@ -77,12 +77,10 @@ import static org.jooq.impl.DSL.select; import static org.jooq.impl.SQLDataType.VARCHAR; import static org.jooq.impl.Tools.embeddedFields; import static org.jooq.impl.Tools.map; -import static org.jooq.impl.Transformations.applyTransformationForInConditionSubqueryWithLimitToDerivedTable; +import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable; import static org.jooq.impl.Transformations.subqueryWithLimit; import static org.jooq.tools.Convert.convert; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import org.jooq.Clause; @@ -136,7 +134,7 @@ final class QuantifiedComparisonCondition extends AbstractCondition implements L ctx.visit(row(embeddedFields(field)).compare(comparator, query)); else if ((comparator == EQUALS || comparator == NOT_EQUALS) && (s = subqueryWithLimit(query.query)) != null - && applyTransformationForInConditionSubqueryWithLimitToDerivedTable(ctx)) { + && transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) { diff --git a/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java b/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java index d9a32304ff..6327def5e6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/RowSubqueryCondition.java @@ -81,7 +81,7 @@ import static org.jooq.impl.Tools.embeddedFieldsRow; import static org.jooq.impl.Tools.fieldNames; import static org.jooq.impl.Tools.fieldsByName; import static org.jooq.impl.Tools.visitSubquery; -import static org.jooq.impl.Transformations.applyTransformationForInConditionSubqueryWithLimitToDerivedTable; +import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable; import static org.jooq.impl.Transformations.subqueryWithLimit; import java.util.Set; @@ -244,7 +244,7 @@ final class RowSubqueryCondition extends AbstractCondition { if ((comparator == IN || comparator == NOT_IN) && right != null && (s = subqueryWithLimit(right)) != null - && applyTransformationForInConditionSubqueryWithLimitToDerivedTable(ctx)) { + && transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) { @@ -252,7 +252,7 @@ final class RowSubqueryCondition extends AbstractCondition { else if ((comparator == EQUALS || comparator == NOT_EQUALS) && rightQuantified != null && (s = subqueryWithLimit(rightQuantified)) != null - && applyTransformationForInConditionSubqueryWithLimitToDerivedTable(ctx)) { + && transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) { diff --git a/jOOQ/src/main/java/org/jooq/impl/Rownum.java b/jOOQ/src/main/java/org/jooq/impl/Rownum.java index 92a67ac8bc..d55cfe01d1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Rownum.java +++ b/jOOQ/src/main/java/org/jooq/impl/Rownum.java @@ -98,15 +98,6 @@ package org.jooq.impl; - - - - - - - - - diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index a3bc161b8f..82eb5efbf4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -212,7 +212,8 @@ import static org.jooq.impl.Tools.DataKey.DATA_SELECT_ALIASES; import static org.jooq.impl.Tools.DataKey.DATA_SELECT_INTO_TABLE; import static org.jooq.impl.Tools.DataKey.DATA_TOP_LEVEL_CTE; import static org.jooq.impl.Tools.DataKey.DATA_WINDOW_DEFINITIONS; -import static org.jooq.impl.Transformations.applyTransformationForQualify; +import static org.jooq.impl.Transformations.transformQualify; +import static org.jooq.impl.Transformations.transformRownum; import java.sql.ResultSetMetaData; import java.util.ArrayDeque; @@ -345,8 +346,6 @@ final class SelectQueryImpl extends AbstractResultQuery imp - - @@ -1524,7 +1523,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp } // [#5810] Emulate the Teradata QUALIFY clause - else if (qualify.hasWhere() && applyTransformationForQualify(ctx)) { + else if (qualify.hasWhere() && transformQualify(ctx.configuration())) { @@ -1558,8 +1557,6 @@ final class SelectQueryImpl extends AbstractResultQuery imp - - diff --git a/jOOQ/src/main/java/org/jooq/impl/Transformations.java b/jOOQ/src/main/java/org/jooq/impl/Transformations.java index 6729f10f4e..e40b8bf5f5 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Transformations.java +++ b/jOOQ/src/main/java/org/jooq/impl/Transformations.java @@ -37,13 +37,21 @@ */ package org.jooq.impl; +// ... +// ... +// ... // ... // ... // ... import static org.jooq.SQLDialect.CUBRID; // ... +import static org.jooq.SQLDialect.DERBY; +// ... import static org.jooq.SQLDialect.FIREBIRD; // ... +import static org.jooq.SQLDialect.HSQLDB; +import static org.jooq.SQLDialect.IGNITE; +// ... // ... import static org.jooq.SQLDialect.MARIADB; // ... @@ -52,10 +60,12 @@ import static org.jooq.SQLDialect.MYSQL; import static org.jooq.SQLDialect.POSTGRES; // ... // ... +// ... import static org.jooq.SQLDialect.SQLITE; // ... // ... // ... +// ... import static org.jooq.conf.Transformation.WHEN_NEEDED; import static org.jooq.impl.Tools.selectQueryImpl; import static org.jooq.tools.StringUtils.defaultIfNull; @@ -63,10 +73,11 @@ import static org.jooq.tools.StringUtils.defaultIfNull; import java.util.Set; import java.util.function.Predicate; +import org.jooq.Configuration; import org.jooq.Context; import org.jooq.QueryPart; import org.jooq.SQLDialect; -import org.jooq.Select; +import org.jooq.Scope; import org.jooq.conf.Transformation; /** @@ -78,38 +89,48 @@ final class Transformations { private static final Set NO_SUPPORT_IN_LIMIT = SQLDialect.supportedBy(MARIADB, MYSQL); private static final Set EMULATE_QUALIFY = SQLDialect.supportedBy(CUBRID, FIREBIRD, MARIADB, MYSQL, POSTGRES, SQLITE); + private static final Set EMULATE_ROWNUM = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, HSQLDB, IGNITE, MARIADB, MYSQL, POSTGRES, SQLITE); static final SelectQueryImpl subqueryWithLimit(QueryPart source) { SelectQueryImpl s; return (s = selectQueryImpl(source)) != null && s.getLimit().isApplicable() ? s : null; } - static final boolean applyTransformationForInConditionSubqueryWithLimitToDerivedTable(Context ctx) { - return applyTransformation( - ctx, + static final boolean transformInConditionSubqueryWithLimitToDerivedTable(Configuration configuration) { + return transform( + configuration, "Settings.transformInConditionSubqueryWithLimitToDerivedTable", - ctx.settings().getTransformInConditionSubqueryWithLimitToDerivedTable(), + configuration.settings().getTransformInConditionSubqueryWithLimitToDerivedTable(), c -> NO_SUPPORT_IN_LIMIT.contains(c.dialect()) ); } - static final boolean applyTransformationForQualify(Context ctx) { - return applyTransformation( - ctx, + static final boolean transformQualify(Configuration configuration) { + return transform( + configuration, "Settings.transformQualify", - ctx.settings().getTransformQualify(), + configuration.settings().getTransformQualify(), c -> EMULATE_QUALIFY.contains(c.dialect()) ); } + static final boolean transformRownum(Configuration configuration) { + return transform( + configuration, + "Settings.transformRownum", + configuration.settings().getTransformRownum(), + c -> EMULATE_ROWNUM.contains(c.dialect()) + ); + } + /** * Check whether a given SQL transformation needs to be applied. */ - static final boolean applyTransformation( - Context ctx, + static final boolean transform( + Configuration configuration, String label, Transformation transformation, - Predicate> whenNeeded + Predicate whenNeeded ) { boolean result; @@ -121,12 +142,12 @@ final class Transformations { result = true; break; case WHEN_NEEDED: - result = whenNeeded.test(ctx); + result = whenNeeded.test(configuration); break; default: throw new IllegalStateException("Transformation configuration not supported: " + transformation); } - return result && ctx.configuration().requireCommercial(() -> "SQL transformation " + label + " required. SQL transformations are a commercial only feature. Please consider upgrading to the jOOQ Professional Edition or jOOQ Enterprise Edition."); + return result && configuration.requireCommercial(() -> "SQL transformation " + label + " required. SQL transformations are a commercial only feature. Please consider upgrading to the jOOQ Professional Edition or jOOQ Enterprise Edition."); } } diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd index 725039dd23..e7fd2ba3b1 100644 --- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd @@ -267,7 +267,7 @@ this flag enables the transformation to ANSI join syntax. This feature is available in the commercial distribution only.]]> - + ROWNUM expressions to corresponding LIMIT clauses or ROW_NUMBER() expressions.

In Oracle 11g and less, ROWNUM filtering was the most popular way to paginate. This pseudo