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.TypeContributions;
|
||||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||||
import org.hibernate.community.dialect.identity.FirebirdIdentityColumnSupport;
|
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.FirebirdSequenceSupport;
|
||||||
import org.hibernate.community.dialect.sequence.InterbaseSequenceSupport;
|
import org.hibernate.community.dialect.sequence.InterbaseSequenceSupport;
|
||||||
import org.hibernate.community.dialect.sequence.SequenceInformationExtractorFirebirdDatabaseImpl;
|
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.DatabaseVersion;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.NationalizationSupport;
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
import org.hibernate.dialect.SimpleDatabaseVersion;
|
|
||||||
import org.hibernate.dialect.TimeZoneSupport;
|
import org.hibernate.dialect.TimeZoneSupport;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||||
|
@ -674,7 +673,7 @@ public class FirebirdDialect extends Dialect {
|
||||||
@Override
|
@Override
|
||||||
public LimitHandler getLimitHandler() {
|
public LimitHandler getLimitHandler() {
|
||||||
return getVersion().isBefore( 3, 0 )
|
return getVersion().isBefore( 3, 0 )
|
||||||
? SkipFirstLimitHandler.INSTANCE
|
? FirstSkipLimitHandler.INSTANCE
|
||||||
: OffsetFetchLimitHandler.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