Skip to content

Commit 57ee220

Browse files
committed
misc cleanups to LimitHandlers
1 parent 5657347 commit 57ee220

File tree

10 files changed

+187
-156
lines changed

10 files changed

+187
-156
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractLimitHandler.java

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import java.sql.PreparedStatement;
88
import java.sql.SQLException;
9-
import java.util.regex.Matcher;
109
import java.util.regex.Pattern;
1110

1211
import org.hibernate.query.Query;
@@ -172,43 +171,59 @@ public void setMaxRows(Limit limit, PreparedStatement statement) throws SQLExcep
172171
*/
173172
protected final int bindLimitParameters(Limit limit, PreparedStatement statement, int index)
174173
throws SQLException {
175-
176-
if ( !supportsVariableLimit() ) {
177-
//never any parameters to bind
178-
return 0;
174+
if ( supportsVariableLimit() ) {
175+
final boolean hasMaxRows = hasMaxRows( limit );
176+
final boolean hasFirstRow = hasFirstRow( limit );
177+
final boolean bindLimit
178+
= hasMaxRows && supportsLimit()
179+
|| forceLimitUsage();
180+
final boolean bindOffset
181+
= hasFirstRow && supportsOffset()
182+
|| hasFirstRow && hasMaxRows && supportsLimitOffset();
183+
return bindLimitParameters( limit, statement, index, bindOffset, bindLimit );
179184
}
180-
181-
final boolean hasMaxRows = hasMaxRows( limit );
182-
final boolean hasFirstRow = hasFirstRow( limit );
183-
184-
final boolean bindLimit
185-
= hasMaxRows && supportsLimit()
186-
|| forceLimitUsage();
187-
final boolean bindOffset
188-
= hasFirstRow && supportsOffset()
189-
|| hasFirstRow && hasMaxRows && supportsLimitOffset();
190-
191-
if ( !bindLimit && !bindOffset ) {
192-
//no parameters to bind this time
185+
else {
186+
// never any parameters to bind
193187
return 0;
194188
}
189+
}
195190

196-
final boolean reverse = bindLimitParametersInReverseOrder();
191+
private int bindLimitParameters(
192+
Limit limit,
193+
PreparedStatement statement,
194+
int index,
195+
boolean bindOffset, boolean bindLimit)
196+
throws SQLException {
197+
int bound = 0;
198+
if ( bindLimitParametersInReverseOrder() ) {
199+
bound = bindLimit( limit, statement, index, bindLimit, bound );
200+
bound = bindOffset( limit, statement, index, bindOffset, bound );
201+
}
202+
else {
203+
bound = bindOffset( limit, statement, index, bindOffset, bound );
204+
bound = bindLimit( limit, statement, index, bindLimit, bound );
205+
}
206+
return bound;
207+
}
197208

209+
private int bindOffset(Limit limit, PreparedStatement statement, int index, boolean bindOffset, int bound)
210+
throws SQLException {
198211
if ( bindOffset ) {
199-
statement.setInt(
200-
index + ( reverse && bindLimit ? 1 : 0 ),
201-
getFirstRow( limit )
202-
);
212+
statement.setInt( index + bound,
213+
getFirstRow( limit ) );
214+
bound++;
203215
}
216+
return bound;
217+
}
218+
219+
private int bindLimit(Limit limit, PreparedStatement statement, int index, boolean bindLimit, int count)
220+
throws SQLException {
204221
if ( bindLimit ) {
205-
statement.setInt(
206-
index + ( reverse || !bindOffset ? 0 : 1 ),
207-
getMaxOrLimit( limit )
208-
);
222+
statement.setInt( index + count,
223+
getMaxOrLimit( limit ) );
224+
count++;
209225
}
210-
211-
return bindOffset && bindLimit ? 2 : 1;
226+
return count;
212227
}
213228

214229
/**
@@ -220,8 +235,8 @@ protected final int bindLimitParameters(Limit limit, PreparedStatement statement
220235
*/
221236
public static boolean hasMaxRows(Limit limit) {
222237
return limit != null
223-
&& limit.getMaxRows() != null
224-
&& limit.getMaxRows() > 0;
238+
&& limit.getMaxRows() != null
239+
&& limit.getMaxRows() > 0;
225240
}
226241

227242
/**
@@ -233,8 +248,8 @@ public static boolean hasMaxRows(Limit limit) {
233248
*/
234249
public static boolean hasFirstRow(Limit limit) {
235250
return limit != null
236-
&& limit.getFirstRow() != null
237-
&& limit.getFirstRow() > 0;
251+
&& limit.getFirstRow() != null
252+
&& limit.getFirstRow() > 0;
238253
}
239254

240255
/**
@@ -247,16 +262,19 @@ public static boolean hasFirstRow(Limit limit) {
247262
* @return The appropriate value to bind into the limit clause.
248263
*/
249264
protected final int getMaxOrLimit(Limit limit) {
250-
if ( limit == null || limit.getMaxRows() == null ) {
265+
if ( hasMaxRows( limit ) ) {
266+
final int firstRow = getFirstRow( limit );
267+
final int maxRows = limit.getMaxRows();
268+
final int maxOrLimit =
269+
useMaxForLimit()
270+
? maxRows + firstRow //TODO: maxRows + firstRow - 1, surely?
271+
: maxRows;
272+
// Use Integer.MAX_VALUE on overflow
273+
return maxOrLimit < 0 ? Integer.MAX_VALUE : maxOrLimit;
274+
}
275+
else {
251276
return Integer.MAX_VALUE;
252277
}
253-
final int firstRow = getFirstRow( limit );
254-
final int maxRows = limit.getMaxRows();
255-
final int maxOrLimit = useMaxForLimit()
256-
? maxRows + firstRow //TODO: maxRows + firstRow - 1, surely?
257-
: maxRows;
258-
// Use Integer.MAX_VALUE on overflow
259-
return maxOrLimit < 0 ? Integer.MAX_VALUE : maxOrLimit;
260278
}
261279

262280
/**
@@ -267,10 +285,9 @@ protected final int getMaxOrLimit(Limit limit) {
267285
* @return The first row
268286
*/
269287
protected final int getFirstRow(Limit limit) {
270-
if ( limit == null || limit.getFirstRow() == null ) {
271-
return 0;
272-
}
273-
return convertToFirstRowValue( limit.getFirstRow() );
288+
return limit == null || limit.getFirstRow() == null
289+
? 0
290+
: convertToFirstRowValue( limit.getFirstRow() );
274291
}
275292

276293
/**
@@ -279,7 +296,7 @@ protected final int getFirstRow(Limit limit) {
279296
* or {@code ALL}.
280297
*/
281298
protected static String insertAfterSelect(String limitOffsetClause, String sqlStatement) {
282-
Matcher selectMatcher = SELECT_PATTERN.matcher( sqlStatement );
299+
final var selectMatcher = SELECT_PATTERN.matcher( sqlStatement );
283300
if ( selectMatcher.find() ) {
284301
return new StringBuilder( sqlStatement )
285302
.insert( selectMatcher.end(), limitOffsetClause )
@@ -296,7 +313,7 @@ protected static String insertAfterSelect(String limitOffsetClause, String sqlSt
296313
* or {@code SELECT ALL}.
297314
*/
298315
protected static String insertAfterDistinct(String limitOffsetClause, String sqlStatement) {
299-
Matcher selectDistinctMatcher = SELECT_DISTINCT_PATTERN.matcher( sqlStatement );
316+
final var selectDistinctMatcher = SELECT_DISTINCT_PATTERN.matcher( sqlStatement );
300317
if ( selectDistinctMatcher.find() ) {
301318
return new StringBuilder( sqlStatement )
302319
.insert( selectDistinctMatcher.end(), limitOffsetClause )
@@ -312,7 +329,7 @@ protected static String insertAfterDistinct(String limitOffsetClause, String sql
312329
* end of the query.
313330
*/
314331
protected String insertAtEnd(String limitOffsetClause, String sqlStatement) {
315-
Matcher endMatcher = END_PATTERN.matcher( sqlStatement );
332+
final var endMatcher = END_PATTERN.matcher( sqlStatement );
316333
if ( endMatcher.find() ) {
317334
return new StringBuilder( sqlStatement )
318335
.insert( endMatcher.start(), limitOffsetClause )
@@ -339,7 +356,7 @@ protected Pattern getForUpdatePattern() {
339356
* of the query.
340357
*/
341358
protected String insertBeforeForUpdate(String limitOffsetClause, String sqlStatement) {
342-
Matcher forUpdateMatcher = getForUpdatePattern().matcher( sqlStatement );
359+
final var forUpdateMatcher = getForUpdatePattern().matcher( sqlStatement );
343360
if ( forUpdateMatcher.find() ) {
344361
return new StringBuilder( sqlStatement )
345362
.insert( forUpdateMatcher.start(), limitOffsetClause )

hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractNoOffsetLimitHandler.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
import org.checkerframework.checker.nullness.qual.Nullable;
88
import org.hibernate.query.spi.Limit;
99
import org.hibernate.query.spi.QueryOptions;
10-
import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard;
1110
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
1211

13-
import static java.lang.String.valueOf;
12+
import static org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard.isStandardRenderer;
1413

1514
/**
1615
* Superclass for {@link LimitHandler}s that don't support
@@ -49,18 +48,25 @@ public String processSql(String sql, Limit limit) {
4948
}
5049

5150
private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) {
52-
if ( !hasMaxRows( limit ) ) {
53-
return sql;
51+
if ( hasMaxRows( limit ) ) {
52+
final String limitClause;
53+
if ( supportsVariableLimit() ) {
54+
limitClause =
55+
isStandardRenderer( parameterMarkerStrategy )
56+
? limitClause()
57+
: limitClause( jdbcParameterCount, parameterMarkerStrategy );
58+
}
59+
else {
60+
limitClause =
61+
limitClause()
62+
.replace( "?",
63+
Integer.toString( getMaxOrLimit( limit ) ) );
64+
}
65+
return insert( limitClause, sql );
5466
}
55-
56-
String limitClause = ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy )
57-
|| !supportsVariableLimit() ? limitClause()
58-
: limitClause( jdbcParameterCount, parameterMarkerStrategy );
59-
if ( !supportsVariableLimit() ) {
60-
String limitLiteral = valueOf( getMaxOrLimit( limit ) );
61-
limitClause = limitClause.replace( "?", limitLiteral );
67+
else {
68+
return sql;
6269
}
63-
return insert( limitClause, sql );
6470
}
6571

6672
@Override

hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractSimpleLimitHandler.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
import org.checkerframework.checker.nullness.qual.Nullable;
88
import org.hibernate.query.spi.Limit;
99
import org.hibernate.query.spi.QueryOptions;
10-
import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard;
1110
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
1211

12+
import static org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard.isStandardRenderer;
13+
1314
/**
1415
* Superclass for simple {@link LimitHandler}s that don't
1516
* support specifying an offset without a limit.
@@ -43,19 +44,27 @@ public String processSql(String sql, int jdbcParameterCount, @Nullable Parameter
4344
}
4445

4546
private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) {
47+
final boolean hasMaxRows = hasMaxRows( limit );
4648
final boolean hasFirstRow = hasFirstRow( limit );
47-
if ( !hasMaxRows( limit ) ) {
49+
if ( hasMaxRows ) {
50+
final String limitClause =
51+
isStandardRenderer( parameterMarkerStrategy )
52+
? limitClause( hasFirstRow )
53+
: limitClause( hasFirstRow, jdbcParameterCount, parameterMarkerStrategy );
54+
return insert( limitClause, sql );
55+
}
56+
else if ( hasFirstRow ) {
4857
final String offsetOnlyClause =
49-
ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy )
50-
? offsetOnlyClause() : offsetOnlyClause( jdbcParameterCount, parameterMarkerStrategy );
51-
if ( offsetOnlyClause != null && hasFirstRow ) {
52-
return insert( offsetOnlyClause, sql );
53-
}
58+
isStandardRenderer( parameterMarkerStrategy )
59+
? offsetOnlyClause()
60+
: offsetOnlyClause( jdbcParameterCount, parameterMarkerStrategy );
61+
return offsetOnlyClause != null
62+
? insert( offsetOnlyClause, sql )
63+
: sql;
64+
}
65+
else {
5466
return sql;
5567
}
56-
final String limitClause = ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy )
57-
? limitClause( hasFirstRow ) : limitClause( hasFirstRow, jdbcParameterCount, parameterMarkerStrategy );
58-
return insert( limitClause, sql );
5968
}
6069

6170
protected String insert(String limitClause, String sql) {

hibernate-core/src/main/java/org/hibernate/dialect/pagination/FetchLimitHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ protected String limitClause() {
2828

2929
@Override
3030
protected String limitClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) {
31-
return " fetch first " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) + " rows only";
31+
return " fetch first "
32+
+ parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null )
33+
+ " rows only";
3234
}
3335

3436
@Override

hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitLimitHandler.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@ protected String limitClause(boolean hasFirstRow) {
3030

3131
@Override
3232
protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) {
33-
final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
34-
if ( hasFirstRow ) {
35-
return " limit " + firstParameter + "," + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null );
36-
}
37-
else {
38-
return " limit " + firstParameter;
39-
}
33+
final String limit = " limit " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
34+
return hasFirstRow
35+
? limit + "," + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null )
36+
: limit;
4037
}
4138

4239
@Override
@@ -46,7 +43,10 @@ protected String offsetOnlyClause() {
4643

4744
@Override
4845
protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) {
49-
return " limit " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) +"," + Integer.MAX_VALUE;
46+
return " limit "
47+
+ parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null )
48+
+ ","
49+
+ Integer.MAX_VALUE;
5050
}
5151

5252
private static final Pattern FOR_UPDATE_PATTERN =

hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitOffsetLimitHandler.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@ protected String limitClause(boolean hasFirstRow) {
3333

3434
@Override
3535
protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) {
36-
final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
37-
if ( hasFirstRow ) {
38-
return " limit " + firstParameter + " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null );
39-
}
40-
else {
41-
return " limit " + firstParameter;
42-
}
36+
final String limit = " limit " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
37+
return hasFirstRow
38+
? limit + " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null )
39+
: limit;
4340
}
4441

4542
@Override
@@ -49,7 +46,10 @@ protected String offsetOnlyClause() {
4946

5047
@Override
5148
protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) {
52-
return " limit " + Integer.MAX_VALUE + " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
49+
return " limit "
50+
+ Integer.MAX_VALUE
51+
+ " offset "
52+
+ parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null );
5353
}
5454

5555
@Override

hibernate-core/src/main/java/org/hibernate/dialect/pagination/NoopLimitHandler.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,13 @@ public int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statem
3636

3737
@Override
3838
public void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException {
39-
if ( limit != null && limit.getMaxRows() != null && limit.getMaxRows() > 0 ) {
40-
final int maxRows = limit.getMaxRows() + convertToFirstRowValue(
41-
limit.getFirstRow() == null ? 0 : limit.getFirstRow()
42-
);
39+
if ( hasMaxRows( limit ) ) {
40+
final Integer firstRow = limit.getFirstRow();
41+
final int convertedMaxRows =
42+
limit.getMaxRows()
43+
+ convertToFirstRowValue( firstRow == null ? 0 : firstRow );
4344
// Use Integer.MAX_VALUE on overflow
44-
if ( maxRows < 0 ) {
45-
statement.setMaxRows( Integer.MAX_VALUE );
46-
}
47-
else {
48-
statement.setMaxRows( maxRows );
49-
}
45+
statement.setMaxRows( convertedMaxRows < 0 ? Integer.MAX_VALUE : convertedMaxRows );
5046
}
5147
}
5248

0 commit comments

Comments
 (0)