From d1c2effe2ee3f843a92a4dd3ae83ba061ab1894e Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 7 Feb 2024 16:42:44 +0100 Subject: [PATCH] [jOOQ/jOOQ#14307] Emulate LIMIT 0 where not supported --- jOOQ/src/main/java/org/jooq/impl/Limit.java | 16 ++++++++++++---- .../main/java/org/jooq/impl/SelectQueryImpl.java | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/Limit.java b/jOOQ/src/main/java/org/jooq/impl/Limit.java index 1a28b7cff6..af5d6e017c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Limit.java +++ b/jOOQ/src/main/java/org/jooq/impl/Limit.java @@ -319,7 +319,7 @@ final class Limit extends AbstractQueryPart implements UTransient { .sql(' ').visit(offsetOrZero) .sql(' ').visit(K_ROWS); - if (!limitZero()) { + if (!limitAbsent()) { ctx.formatSeparator() .visit(K_FETCH_NEXT).sql(' ').visit(limit); @@ -335,7 +335,7 @@ final class Limit extends AbstractQueryPart implements UTransient { private final void acceptDefault(Context ctx, CastMode castMode) { ctx.castMode(NEVER); - if (!limitZero()) + if (!limitAbsent()) ctx.formatSeparator() .visit(K_LIMIT) .sql(' ').visit(limit); @@ -381,19 +381,27 @@ final class Limit extends AbstractQueryPart implements UTransient { + + /** + * Whether the limit is absent + */ + final boolean limitAbsent() { + return limit == null; + } /** * Whether this limit has a limit of zero */ final boolean limitZero() { - return limit == null; + return !limitAbsent() + && Long.valueOf(0L).equals(getLimit()); } /** * Whether this limit has a limit of one */ final boolean limitOne() { - return !limitZero() + return !limitAbsent() && !withTies() && !percent() && Long.valueOf(1L).equals(getLimit()); diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index c0ef862777..8152e3a4f0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -378,6 +378,8 @@ final class SelectQueryImpl extends AbstractResultQuery imp static final Set NO_SUPPORT_FOR_UPDATE_OF_FIELDS = SQLDialect.supportedBy(MYSQL, POSTGRES, YUGABYTEDB); static final Set NO_SUPPORT_UNION_ORDER_BY_ALIAS = SQLDialect.supportedBy(FIREBIRD); static final Set NO_SUPPORT_WITH_READ_ONLY = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTEDB); + static final Set NO_SUPPORT_LIMIT_ZERO = SQLDialect.supportedBy(DERBY, HSQLDB); + @@ -2156,7 +2158,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp @SuppressWarnings("unchecked") private final Condition limitWindowFunctionCondition(Field limitWindowFunction) { - return getLimit().limitZero() + return getLimit().limitAbsent() ? limitWindowFunction.gt((Field) getLimit().getLowerRownum()) : limitWindowFunction .between((Field) getLimit().getLowerRownum().add(inline(1))) @@ -3469,7 +3471,8 @@ final class SelectQueryImpl extends AbstractResultQuery imp if (TRUE.equals(ctx.data(DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE))) { if (actualLimit.isApplicable()) { - ctx.visit(actualLimit); + if (!(actualLimit.limitZero() && NO_SUPPORT_LIMIT_ZERO.contains(ctx.dialect()))) + ctx.visit(actualLimit); } // [#13509] Force a LIMIT clause to prevent optimisation of "unnecessary" ORDER BY @@ -3560,6 +3563,9 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + + @@ -4382,6 +4388,9 @@ final class SelectQueryImpl extends AbstractResultQuery imp + if (NO_SUPPORT_LIMIT_ZERO.contains(ctx.dialect()) && limit.limitZero() && !isGrouping()) + result.addConditions(falseCondition()); + return result; } @@ -4517,6 +4526,9 @@ final class SelectQueryImpl extends AbstractResultQuery imp if (isGrouping() && !getOrderBy().isEmpty() && !getSeek().isEmpty() && unionOp.isEmpty()) result.addConditions(getSeekCondition(ctx)); + if (NO_SUPPORT_LIMIT_ZERO.contains(ctx.dialect()) && limit.limitZero() && isGrouping()) + result.addConditions(falseCondition()); + return result; }