66
77import java .sql .PreparedStatement ;
88import java .sql .SQLException ;
9- import java .util .regex .Matcher ;
109import java .util .regex .Pattern ;
1110
1211import 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 )
0 commit comments