[#7430] ResultQuery.fetchOne() should not fetch second record on a LIMIT 1 query
This commit is contained in:
parent
0b917a5c7e
commit
c2c125be98
@ -532,7 +532,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
|
||||
|
||||
@Override
|
||||
public final R fetchOne() {
|
||||
return Tools.fetchOne(fetchLazy());
|
||||
return Tools.fetchOne(fetchLazy(), hasLimit1());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -627,7 +627,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
|
||||
|
||||
@Override
|
||||
public final R fetchSingle() {
|
||||
return Tools.fetchSingle(fetchLazy());
|
||||
return Tools.fetchSingle(fetchLazy(), hasLimit1());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1475,4 +1475,14 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
|
||||
return fetch();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final boolean hasLimit1() {
|
||||
if (this instanceof SelectQueryImpl) {
|
||||
Limit l = ((SelectQueryImpl) this).getLimit();
|
||||
return !l.withTies() && l.limitOne();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,12 +360,23 @@ final class Limit extends AbstractQueryPart {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this limit has an offset of zero
|
||||
* Whether this limit has a limit of zero
|
||||
*/
|
||||
final boolean limitZero() {
|
||||
return numberOfRows == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this limit has a limit of one
|
||||
*/
|
||||
final boolean limitOne() {
|
||||
return !limitZero()
|
||||
&& !withTies()
|
||||
|
||||
&& numberOfRows instanceof Param
|
||||
&& Integer.valueOf(1).equals(((Param<?>) numberOfRows).getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this limit has an offset of zero
|
||||
*/
|
||||
|
||||
@ -1705,11 +1705,31 @@ final class Tools {
|
||||
* element
|
||||
*/
|
||||
static final <R extends Record> R fetchOne(Cursor<R> cursor) throws TooManyRowsException {
|
||||
return fetchOne(cursor, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the only element from a cursor or <code>null</code>, or throw an
|
||||
* exception.
|
||||
* <p>
|
||||
* [#2373] This method will always close the argument cursor, as it is
|
||||
* supposed to be completely consumed by this method.
|
||||
*
|
||||
* @param cursor The cursor
|
||||
* @param hasLimit1 Whether a LIMIT clause is present that guarantees at
|
||||
* most one row
|
||||
* @return The only element from the cursor or <code>null</code>
|
||||
* @throws TooManyRowsException Thrown if the cursor returns more than one
|
||||
* element
|
||||
*/
|
||||
static final <R extends Record> R fetchOne(Cursor<R> cursor, boolean hasLimit1) throws TooManyRowsException {
|
||||
try {
|
||||
|
||||
// [#7001] Fetching at most two rows rather than at most one row
|
||||
// (and then checking of additional rows) improves debug logs
|
||||
Result<R> result = cursor.fetchNext(2);
|
||||
// [#7430] Avoid fetching the second row (additional overhead) if
|
||||
// there is a guarantee of at most one row
|
||||
Result<R> result = cursor.fetchNext(hasLimit1 ? 1 : 2);
|
||||
int size = result.size();
|
||||
|
||||
if (size == 0)
|
||||
@ -1737,11 +1757,31 @@ final class Tools {
|
||||
* element
|
||||
*/
|
||||
static final <R extends Record> R fetchSingle(Cursor<R> cursor) throws NoDataFoundException, TooManyRowsException {
|
||||
return fetchSingle(cursor, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the only element from a cursor, or throw an exception.
|
||||
* <p>
|
||||
* [#2373] This method will always close the argument cursor, as it is
|
||||
* supposed to be completely consumed by this method.
|
||||
*
|
||||
* @param cursor The cursor
|
||||
* @param hasLimit1 Whether a LIMIT clause is present that guarantees at
|
||||
* most one row
|
||||
* @return The only element from the cursor
|
||||
* @throws NoDataFoundException Thrown if the cursor did not return any rows
|
||||
* @throws TooManyRowsException Thrown if the cursor returns more than one
|
||||
* element
|
||||
*/
|
||||
static final <R extends Record> R fetchSingle(Cursor<R> cursor, boolean hasLimit1) throws NoDataFoundException, TooManyRowsException {
|
||||
try {
|
||||
|
||||
// [#7001] Fetching at most two rows rather than at most one row
|
||||
// (and then checking of additional rows) improves debug logs
|
||||
Result<R> result = cursor.fetchNext(2);
|
||||
// [#7430] Avoid fetching the second row (additional overhead) if
|
||||
// there is a guarantee of at most one row
|
||||
Result<R> result = cursor.fetchNext(hasLimit1 ? 1 : 2);
|
||||
int size = result.size();
|
||||
|
||||
if (size == 0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user