[#8415] Support PERCENT and WITH TIES in H2

This commit is contained in:
lukaseder 2019-03-14 11:13:56 +01:00
parent 6a56edf319
commit b09725df2d
6 changed files with 81 additions and 105 deletions

View File

@ -37,6 +37,7 @@
*/
package org.jooq;
import static org.jooq.SQLDialect.H2;
// ...
// ...
@ -102,14 +103,9 @@ package org.jooq;
*/
public interface SelectLimitPercentAfterOffsetStep<R extends Record> extends SelectWithTiesAfterOffsetStep<R> {
/**
* Add the <code>PERCENT</code> clause to a <code>LIMIT</code> clause.
*/
@Support({ H2 })
SelectWithTiesAfterOffsetStep<R> percent();
}

View File

@ -37,6 +37,7 @@
*/
package org.jooq;
import static org.jooq.SQLDialect.H2;
// ...
// ...
@ -102,14 +103,9 @@ package org.jooq;
*/
public interface SelectLimitPercentStep<R extends Record> extends SelectWithTiesStep<R> {
/**
* Add the <code>PERCENT</code> clause to a <code>LIMIT</code> clause.
*/
@Support({ H2 })
SelectWithTiesStep<R> percent();
}

View File

@ -859,16 +859,11 @@ public interface SelectQuery<R extends Record> extends Select<R>, ConditionProvi
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
void addLimit(Param<? extends Number> offset, Param<? extends Number> numberOfRows);
/**
* Add the <code>PERCENT</code> clause to a <code>LIMIT</code> clause.
*/
@Support({ H2 })
void setLimitPercent(boolean percent);
/**
* Add the <code>WITH TIES</code> clause to a <code>LIMIT</code> clause.

View File

@ -39,6 +39,7 @@ package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static org.jooq.RenderContext.CastMode.NEVER;
import static org.jooq.SQLDialect.H2;
// ...
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.DSL.one;
@ -89,10 +90,7 @@ final class Limit extends AbstractQueryPart {
private Field<?> offsetPlusOne = ONE;
private boolean rendersParams;
private boolean withTies;
private boolean percent;
@Override
public final void accept(Context<?> ctx) {
@ -177,32 +175,16 @@ final class Limit extends AbstractQueryPart {
case H2:
case DERBY: {
// Casts are not supported here...
ctx.castMode(NEVER);
// [#8415] For backwards compatibility reasons, we generate standard
// OFFSET .. FETCH syntax on H2 only when strictly needed
if (ctx.dialect() == H2 && !withTies() && !percent())
acceptDefault(ctx, castMode);
else
acceptStandard(ctx, castMode);
ctx.formatSeparator()
.visit(K_OFFSET)
.sql(' ').visit(offsetOrZero)
.sql(' ').visit(K_ROWS);
if (!limitZero()) {
ctx.formatSeparator()
.visit(K_FETCH_NEXT).sql(' ').visit(numberOfRows);
ctx.sql(' ').visit(withTies ? K_ROWS_WITH_TIES : K_ROWS_ONLY);
}
ctx.castMode(castMode);
break;
}
@ -293,7 +275,6 @@ final class Limit extends AbstractQueryPart {
// [#4785] OFFSET cannot be without LIMIT
case H2:
case MARIADB:
case MYSQL_5_7:
case MYSQL_8_0:
@ -329,24 +310,50 @@ final class Limit extends AbstractQueryPart {
// A default implementation is necessary for hashCode() and toString()
default: {
ctx.castMode(NEVER);
if (!limitZero())
ctx.formatSeparator()
.visit(K_LIMIT)
.sql(' ').visit(numberOfRows);
if (!offsetZero())
ctx.formatSeparator()
.visit(K_OFFSET)
.sql(' ').visit(offsetOrZero);
ctx.castMode(castMode);
acceptDefault(ctx, castMode);
break;
}
}
}
private final void acceptStandard(Context<?> ctx, CastMode castMode) {
ctx.castMode(NEVER);
if ( !offsetZero())
ctx.formatSeparator()
.visit(K_OFFSET)
.sql(' ').visit(offsetOrZero)
.sql(' ').visit(K_ROWS);
if (!limitZero()) {
ctx.formatSeparator()
.visit(K_FETCH_NEXT).sql(' ').visit(numberOfRows);
if (percent)
ctx.sql(' ').visit(K_PERCENT);
ctx.sql(' ').visit(withTies ? K_ROWS_WITH_TIES : K_ROWS_ONLY);
}
ctx.castMode(castMode);
}
private final void acceptDefault(Context<?> ctx, CastMode castMode) {
ctx.castMode(NEVER);
if (!limitZero())
ctx.formatSeparator()
.visit(K_LIMIT)
.sql(' ').visit(numberOfRows);
if (!offsetZero())
ctx.formatSeparator()
.visit(K_OFFSET)
.sql(' ').visit(offsetOrZero);
ctx.castMode(castMode);
}
@ -452,19 +459,13 @@ final class Limit extends AbstractQueryPart {
this.rendersParams |= numberOfRows.isInline();
}
final void setPercent(boolean percent) {
this.percent = percent;
}
final boolean percent() {
return percent;
}
final void setWithTies(boolean withTies) {
this.withTies = withTies;

View File

@ -1743,16 +1743,11 @@ final class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
return this;
}
@Override
public final SelectImpl percent() {
getQuery().setLimitPercent(true);
return this;
}
@Override
public final SelectImpl withTies() {

View File

@ -211,8 +211,7 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
private static final EnumSet<SQLDialect> REQUIRES_FROM_CLAUSE = EnumSet.of(CUBRID, DERBY, FIREBIRD, HSQLDB, MARIADB, MYSQL);
private static final EnumSet<SQLDialect> REQUIRES_DERIVED_TABLE_DML = EnumSet.of(MARIADB, MYSQL);
private static final EnumSet<SQLDialect> EMULATE_EMPTY_GROUP_BY_OTHER = EnumSet.of(FIREBIRD, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE);
private static final EnumSet<SQLDialect> SUPPORT_FULL_WITH_TIES = EnumSet.of(H2);
@ -672,7 +671,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
case CUBRID:
case FIREBIRD_3_0:
case H2:
case MARIADB:
case MYSQL:
case MYSQL_8_0:
@ -1930,15 +1928,10 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
getLimit().setNumberOfRows(numberOfRows);
}
@Override
public final void setLimitPercent(boolean percent) {
getLimit().setPercent(percent);
}
@Override
public final void setWithTies(boolean withTies) {