HHH-11509 - Infomix limit handler support for offset

This commit is contained in:
marcgiffing 2017-02-21 21:51:38 +01:00 committed by Chris Cranford
parent 2c4ccbc8af
commit 20314c2193
3 changed files with 101 additions and 16 deletions

View File

@ -16,11 +16,15 @@ import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.identity.InformixIdentityColumnSupport;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.InformixLimitHandler;
import org.hibernate.dialect.pagination.LegacyFirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.dialect.unique.InformixUniqueDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
@ -179,12 +183,9 @@ public class InformixDialect extends Dialect {
@Override
public LimitHandler getLimitHandler() {
if ( isLegacyLimitHandlerBehaviorEnabled() ) {
return LegacyFirstLimitHandler.INSTANCE;
}
return FirstLimitHandler.INSTANCE;
return new InformixLimitHandler();
}
@Override
public boolean supportsLimit() {
return true;
@ -200,17 +201,6 @@ public class InformixDialect extends Dialect {
return false;
}
@Override
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuilder( querySelect.length() + 8 )
.append( querySelect )
.insert( querySelect.toLowerCase(Locale.ROOT).indexOf( "select" ) + 6, " first " + limit )
.toString();
}
@Override
public boolean supportsVariableLimit() {
return false;

View File

@ -0,0 +1,50 @@
/*
* 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.dialect.pagination;
import java.util.Locale;
import org.hibernate.engine.spi.RowSelection;
public class InformixLimitHandler extends AbstractLimitHandler {
@Override
public String processSql(String sql, RowSelection selection) {
final boolean hasOffset = LimitHelper.hasFirstRow(selection);
String sqlOffset = hasOffset ? " SKIP " + selection.getFirstRow() : "";
String sqlLimit = " FIRST " + getMaxOrLimit(selection);
String sqlOffsetLimit = sqlOffset + sqlLimit;
String result = new StringBuilder(sql.length() + 10)
.append(sql)
.insert(sql.toLowerCase(Locale.ROOT).indexOf("select") + 6, sqlOffsetLimit).toString();
return result;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersFirst() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return true;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.dialect;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class InformixLimitHandlerTestCase extends
BaseNonConfigCoreFunctionalTestCase {
private final String TEST_SQL = "SELECT field FROM table";
@Test
@TestForIssue(jiraKey = "HHH-11509")
@RequiresDialect(InformixDialect.class)
public void testCache71DialectLegacyLimitHandler() {
assertLimitHandlerEquals( "SELECT SKIP 2 FIRST 5 field FROM table" );
}
private void assertLimitHandlerEquals(String sql) {
assertEquals( sql, getDialect().getLimitHandler().processSql( TEST_SQL, toRowSelection( 3, 5 ) ) );
}
private RowSelection toRowSelection(int firstRow, int maxRows) {
RowSelection selection = new RowSelection();
selection.setFirstRow( firstRow );
selection.setMaxRows( maxRows );
return selection;
}
}