HHH-18213 Fix LimitHandler for Firebird 2.5 and older
This commit is contained in:
parent
cfc6df2e27
commit
1e70c51b56
|
@ -28,7 +28,7 @@ import org.hibernate.boot.model.FunctionContributions;
|
|||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.community.dialect.identity.FirebirdIdentityColumnSupport;
|
||||
import org.hibernate.community.dialect.pagination.SkipFirstLimitHandler;
|
||||
import org.hibernate.community.dialect.pagination.FirstSkipLimitHandler;
|
||||
import org.hibernate.community.dialect.sequence.FirebirdSequenceSupport;
|
||||
import org.hibernate.community.dialect.sequence.InterbaseSequenceSupport;
|
||||
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorFirebirdDatabaseImpl;
|
||||
|
@ -36,7 +36,6 @@ import org.hibernate.dialect.BooleanDecoder;
|
|||
import org.hibernate.dialect.DatabaseVersion;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.NationalizationSupport;
|
||||
import org.hibernate.dialect.SimpleDatabaseVersion;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
|
@ -674,7 +673,7 @@ public class FirebirdDialect extends Dialect {
|
|||
@Override
|
||||
public LimitHandler getLimitHandler() {
|
||||
return getVersion().isBefore( 3, 0 )
|
||||
? SkipFirstLimitHandler.INSTANCE
|
||||
? FirstSkipLimitHandler.INSTANCE
|
||||
: OffsetFetchLimitHandler.INSTANCE;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.community.dialect.pagination;
|
||||
|
||||
import org.hibernate.dialect.pagination.AbstractLimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.query.spi.Limit;
|
||||
|
||||
/**
|
||||
* A {@link LimitHandler} for Firebird 2.5 and older which supports the syntax
|
||||
* {@code FIRST n SKIP m}.
|
||||
*/
|
||||
public class FirstSkipLimitHandler extends AbstractLimitHandler {
|
||||
|
||||
public static final FirstSkipLimitHandler INSTANCE = new FirstSkipLimitHandler();
|
||||
|
||||
@Override
|
||||
public String processSql(String sql, Limit limit) {
|
||||
boolean hasFirstRow = hasFirstRow( limit );
|
||||
boolean hasMaxRows = hasMaxRows( limit );
|
||||
|
||||
if ( !hasFirstRow && !hasMaxRows ) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
StringBuilder skipFirst = new StringBuilder();
|
||||
|
||||
if ( hasMaxRows ) {
|
||||
skipFirst.append( " first ?" );
|
||||
}
|
||||
if ( hasFirstRow ) {
|
||||
skipFirst.append( " skip ?" );
|
||||
}
|
||||
|
||||
return insertAfterSelect( skipFirst.toString(), sql );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOffset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean bindLimitParametersFirst() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.community.dialect;
|
||||
|
||||
import org.hibernate.dialect.DatabaseVersion;
|
||||
import org.hibernate.query.spi.Limit;
|
||||
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class FirebirdDialectTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(useHeadersInDisplayName = true, value = {
|
||||
"major, minor, offset, limit, expectedSQL",
|
||||
"2, 5, 0, 10, select first ? * from tablename t where t.cat = 5",
|
||||
"2, 5, 10, 0, select skip ? * from tablename t where t.cat = 5",
|
||||
"2, 5, 5, 10, select first ? skip ? * from tablename t where t.cat = 5",
|
||||
"3, 0, 0, 10, select * from tablename t where t.cat = 5 fetch first ? rows only",
|
||||
"3, 0, 10, 0, select * from tablename t where t.cat = 5 offset ? rows",
|
||||
"3, 0, 5, 10, select * from tablename t where t.cat = 5 offset ? rows fetch next ? rows only"
|
||||
})
|
||||
@JiraKey( "HHH-18213" )
|
||||
void insertOffsetLimitClause(int major, int minor, int offset, int limit, String expectedSql) {
|
||||
String input = "select * from tablename t where t.cat = 5";
|
||||
FirebirdDialect dialect = new FirebirdDialect( DatabaseVersion.make( major, minor ) );
|
||||
String actual = dialect.getLimitHandler().processSql( input, new Limit( offset, limit ) );
|
||||
assertEquals( expectedSql, actual );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue