[#8414] Don't emulate empty ORDER BY clause in H2's ROW_NUMBER() function

This commit is contained in:
lukaseder 2019-03-14 10:14:37 +01:00
parent fde977abd9
commit 16df2e309d
3 changed files with 35 additions and 5 deletions

View File

@ -89,6 +89,7 @@ import static org.jooq.impl.Term.MODE;
import static org.jooq.impl.Term.PRODUCT;
import static org.jooq.impl.Term.ROW_NUMBER;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_RANKING_FUNCTION;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_ROWNUMBER_FUNCTION;
import static org.jooq.impl.Tools.DataKey.DATA_WINDOW_DEFINITIONS;
import java.math.BigDecimal;
@ -424,10 +425,17 @@ class Function<T> extends AbstractField<T> implements
return;
Boolean ranking = false;
Boolean previous = null;
Boolean rowNumber = false;
Boolean previousRanking = null;
Boolean previousRowNumber = null;
if (term != null) {
switch (term) {
case ROW_NUMBER:
rowNumber = true;
ranking = true;
break;
case CUME_DIST:
case DENSE_RANK:
case FIRST_VALUE:
@ -438,7 +446,6 @@ class Function<T> extends AbstractField<T> implements
case NTILE:
case PERCENT_RANK:
case RANK:
case ROW_NUMBER:
ranking = true;
break;
}
@ -448,14 +455,20 @@ class Function<T> extends AbstractField<T> implements
.visit(K_OVER)
.sql(' ');
previous = (Boolean) ctx.data(DATA_RANKING_FUNCTION, ranking);
previousRanking = (Boolean) ctx.data(DATA_RANKING_FUNCTION, ranking);
previousRowNumber = (Boolean) ctx.data(DATA_ROWNUMBER_FUNCTION, rowNumber);
ctx.visit(window);
if (TRUE.equals(previous))
ctx.data(DATA_RANKING_FUNCTION, previous);
if (TRUE.equals(previousRanking))
ctx.data(DATA_RANKING_FUNCTION, previousRanking);
else
ctx.data().remove(DATA_RANKING_FUNCTION);
if (TRUE.equals(previousRowNumber))
ctx.data(DATA_ROWNUMBER_FUNCTION, previousRowNumber);
else
ctx.data().remove(DATA_ROWNUMBER_FUNCTION);
}
@SuppressWarnings("unchecked")

View File

@ -452,6 +452,11 @@ final class Tools {
*/
DATA_EMULATE_BULK_INSERT_RETURNING,
/**
* [#8414] We're currently generating the window specification of a row_number function.
*/
DATA_ROWNUMBER_FUNCTION,
/**
* [#1535] We're currently generating the window specification of a ranking function.
*/

View File

@ -62,6 +62,7 @@ import static org.jooq.impl.Keywords.K_PRECEDING;
import static org.jooq.impl.Keywords.K_UNBOUNDED_FOLLOWING;
import static org.jooq.impl.Keywords.K_UNBOUNDED_PRECEDING;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_RANKING_FUNCTION;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_ROWNUMBER_FUNCTION;
import static org.jooq.impl.WindowSpecificationImpl.Exclude.CURRENT_ROW;
import static org.jooq.impl.WindowSpecificationImpl.Exclude.GROUP;
import static org.jooq.impl.WindowSpecificationImpl.Exclude.NO_OTHERS;
@ -162,6 +163,17 @@ final class WindowSpecificationImpl extends AbstractQueryPart implements
glue = " ";
}
else if (TRUE.equals(ctx.data(DATA_ROWNUMBER_FUNCTION)) && REQUIRES_ORDER_BY_IN_RANKING.contains(ctx.family())) {
// [#8414] H2 requires ORDER BY in all other ranking functions than ROW_NUMBER()
if (ctx.family() != H2) {
ctx.sql(glue)
.visit(K_ORDER_BY).sql(' ')
.visit(field(select(one())));
glue = " ";
}
}
else if (TRUE.equals(ctx.data(DATA_RANKING_FUNCTION)) && REQUIRES_ORDER_BY_IN_RANKING.contains(ctx.family())) {
ctx.sql(glue)
.visit(K_ORDER_BY).sql(' ')