HHH-7033 replaced all Dialect limit/offset methods with LimitHandler use

This commit is contained in:
Brett Meyer 2014-03-13 16:57:04 -04:00
parent ac648cec15
commit 83d2e46ba4
28 changed files with 706 additions and 604 deletions

View File

@ -41,9 +41,13 @@ import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.engine.jdbc.NClobImplementer;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
@ -306,11 +310,6 @@ public abstract class AbstractHANADialect extends Dialect {
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
return new SQLExceptionConversionDelegate() {
@ -430,12 +429,6 @@ public abstract class AbstractHANADialect extends Dialect {
return getForUpdateString( lockMode ) + " of " + aliases;
}
@Override
public String getLimitString(final String sql, final boolean hasOffset) {
return new StringBuilder( sql.length() + 20 ).append( sql )
.append( hasOffset ? " limit ? offset ?" : " limit ?" ).toString();
}
@Override
public String getNotExpression(final String expression) {
return "not (" + expression + ")";
@ -604,11 +597,6 @@ public abstract class AbstractHANADialect extends Dialect {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean supportsPooledSequences() {
return true;
@ -670,4 +658,26 @@ public abstract class AbstractHANADialect extends Dialect {
final String referencedTable, final String[] primaryKey, final boolean referencesPrimaryKey) {
return super.getAddForeignKeyConstraintString(constraintName, foreignKey, referencedTable, primaryKey, referencesPrimaryKey) + " on update cascade";
}
@Override
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
return new StringBuilder( sql.length() + 20 ).append( sql )
.append( hasOffset ? " limit ? offset ?" : " limit ?" ).toString();
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
};
}
}

View File

@ -46,6 +46,9 @@ import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.lock.UpdateLockingStrategy;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.TopLimitHandler;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.internal.CacheSQLExceptionConversionDelegate;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
@ -583,53 +586,9 @@ public class Cache71Dialect extends Dialect {
// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimit() {
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimitOffset() {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsVariableLimit() {
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean bindLimitParametersFirst() {
// Does the LIMIT clause come at the start of the SELECT statement, rather than at the end?
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean useMaxForLimit() {
// Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows?
return true;
}
@Override
@SuppressWarnings("deprecation")
public String getLimitString(String sql, boolean hasOffset) {
if ( hasOffset ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
// but this extension is not supported through Hibernate anyway.
final int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6;
return new StringBuilder( sql.length() + 8 )
.append( sql )
.insert( insertionPoint, " TOP ? " )
.toString();
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new TopLimitHandler(sql, selection, true, true);
}
// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -23,6 +23,11 @@
*/
package org.hibernate.dialect;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
/**
* An SQL dialect for DB2/390. This class provides support for
@ -42,35 +47,31 @@ public class DB2390Dialect extends DB2Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
if ( LimitHelper.hasFirstRow(selection) ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return sql + " fetch first ? rows only";
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public String getLimitString(String sql, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
if ( limit == 0 ) {
return sql;
}
return sql + " fetch first " + limit + " rows only ";
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
}

View File

@ -23,6 +23,11 @@
*/
package org.hibernate.dialect;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
/**
* An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries,
* also known as DB2/400.
@ -41,36 +46,32 @@ public class DB2400Dialect extends DB2Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
if ( LimitHelper.hasFirstRow(selection) ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return sql + " fetch first ? rows only";
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public String getLimitString(String sql, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
if ( limit == 0 ) {
return sql;
}
return sql + " fetch first " + limit + " rows only ";
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
@Override
public String getForUpdateString() {

View File

@ -36,6 +36,10 @@ import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
@ -249,55 +253,12 @@ public class DB2Dialect extends Dialect {
return "select seqname from sysibm.syssequences";
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimit() {
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsVariableLimit() {
return false;
}
@Override
@SuppressWarnings("deprecation")
public String getLimitString(String sql, int offset, int limit) {
if ( offset == 0 ) {
return sql + " fetch first " + limit + " rows only";
}
//nest the main query in an outer select
return "select * from ( select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from ( "
+ sql + " fetch first " + limit + " rows only ) as inner2_ ) as inner1_ where rownumber_ > "
+ offset + " order by rownumber_";
}
/**
* {@inheritDoc}
* <p/>
*
* DB2 does have a one-based offset, however this was actually already handled in the limit string building
* (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here.
*/
@Override
@SuppressWarnings("deprecation")
public int convertToFirstRowValue(int zeroBasedFirstResult) {
return zeroBasedFirstResult;
}
@Override
@SuppressWarnings("deprecation")
public String getForUpdateString() {
return " for read only with rs use and keep update locks";
}
@Override
@SuppressWarnings("deprecation")
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsOuterJoinForUpdate() {
return false;
@ -484,5 +445,36 @@ public class DB2Dialect extends Dialect {
public String getNotExpression( String expression ) {
return "not (" + expression + ")";
}
@Override
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
if ( LimitHelper.hasFirstRow(selection) ) {
//nest the main query in an outer select
return "select * from ( select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from ( "
+ sql + " fetch first ? rows only ) as inner2_ ) as inner1_ where rownumber_ > "
+ "? order by rownumber_";
}
return sql + " fetch first ? rows only";
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
}

View File

@ -29,11 +29,14 @@ import java.sql.Types;
import org.hibernate.MappingException;
import org.hibernate.dialect.function.AnsiTrimFunction;
import org.hibernate.dialect.function.DerbyConcatFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
import org.jboss.logging.Logger;
/**
@ -134,23 +137,12 @@ public abstract class DerbyDialect extends DB2Dialect {
}
}
@Override
public boolean supportsLimit() {
return isTenPointFiveReleaseOrNewer();
}
@Override
public boolean supportsCommentOn() {
//HHH-4531
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimitOffset() {
return isTenPointFiveReleaseOrNewer();
}
@Override
public String getForUpdateString() {
return " for update with rs";
@ -166,61 +158,6 @@ public abstract class DerbyDialect extends DB2Dialect {
return " for read only with rs";
}
/**
* {@inheritDoc}
* <p/>
* From Derby 10.5 Docs:
* <pre>
* Query
* [ORDER BY clause]
* [result offset clause]
* [fetch first clause]
* [FOR UPDATE clause]
* [WITH {RR|RS|CS|UR}]
* </pre>
*/
@Override
public String getLimitString(String query, final int offset, final int limit) {
final StringBuilder sb = new StringBuilder(query.length() + 50);
final String normalizedSelect = query.toLowerCase().trim();
final int forUpdateIndex = normalizedSelect.lastIndexOf( "for update") ;
if ( hasForUpdateClause( forUpdateIndex ) ) {
sb.append( query.substring( 0, forUpdateIndex-1 ) );
}
else if ( hasWithClause( normalizedSelect ) ) {
sb.append( query.substring( 0, getWithIndex( query ) - 1 ) );
}
else {
sb.append( query );
}
if ( offset == 0 ) {
sb.append( " fetch first " );
}
else {
sb.append( " offset " ).append( offset ).append( " rows fetch next " );
}
sb.append( limit ).append( " rows only" );
if ( hasForUpdateClause( forUpdateIndex ) ) {
sb.append( ' ' );
sb.append( query.substring( forUpdateIndex ) );
}
else if ( hasWithClause( normalizedSelect ) ) {
sb.append( ' ' ).append( query.substring( getWithIndex( query ) ) );
}
return sb.toString();
}
@Override
public boolean supportsVariableLimit() {
// we bind the limit and offset values directly into the sql...
return false;
}
private boolean hasForUpdateClause(int forUpdateIndex) {
return forUpdateIndex >= 0;
}
@ -242,6 +179,75 @@ public abstract class DerbyDialect extends DB2Dialect {
return null ;
}
@Override
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
/**
* {@inheritDoc}
* <p/>
* From Derby 10.5 Docs:
* <pre>
* Query
* [ORDER BY clause]
* [result offset clause]
* [fetch first clause]
* [FOR UPDATE clause]
* [WITH {RR|RS|CS|UR}]
* </pre>
*/
@Override
public String getProcessedSql() {
final StringBuilder sb = new StringBuilder(sql.length() + 50);
final String normalizedSelect = sql.toLowerCase().trim();
final int forUpdateIndex = normalizedSelect.lastIndexOf( "for update") ;
if ( hasForUpdateClause( forUpdateIndex ) ) {
sb.append( sql.substring( 0, forUpdateIndex-1 ) );
}
else if ( hasWithClause( normalizedSelect ) ) {
sb.append( sql.substring( 0, getWithIndex( sql ) - 1 ) );
}
else {
sb.append( sql );
}
if ( LimitHelper.hasFirstRow(selection) ) {
sb.append( " offset ? rows fetch next " );
}
else {
sb.append( " fetch first " );
}
sb.append( "? rows only" );
if ( hasForUpdateClause( forUpdateIndex ) ) {
sb.append( ' ' );
sb.append( sql.substring( forUpdateIndex ) );
}
else if ( hasWithClause( normalizedSelect ) ) {
sb.append( ' ' ).append( sql.substring( getWithIndex( sql ) ) );
}
return sb.toString();
}
@Override
public boolean supportsLimit() {
return isTenPointFiveReleaseOrNewer();
}
@Override
@SuppressWarnings("deprecation")
public boolean supportsLimitOffset() {
return isTenPointFiveReleaseOrNewer();
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -36,7 +36,6 @@ import org.hibernate.dialect.function.DerbyConcatFunction;
* @author Simon Johnston
* @author Scott Marlow
*/
@SuppressWarnings("deprecation")
public class DerbyTenFiveDialect extends DerbyDialect {
/**
* Constructs a DerbyTenFiveDialect
@ -51,14 +50,4 @@ public class DerbyTenFiveDialect extends DerbyDialect {
public boolean supportsSequences() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return true;
}
}

View File

@ -23,6 +23,11 @@
*/
package org.hibernate.dialect;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
/**
* An SQL dialect for Firebird.
*
@ -35,20 +40,31 @@ public class FirebirdDialect extends InterbaseDialect {
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
return new StringBuilder( sql.length() + 20 )
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
return new StringBuilder( sql.length() + 20 )
.append( sql )
.insert( 6, hasOffset ? " first ? skip ?" : " first ?" )
.toString();
}
}
@Override
public boolean bindLimitParametersFirst() {
return true;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean bindLimitParametersFirst() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
};
}
}

View File

@ -33,6 +33,10 @@ import org.hibernate.dialect.function.AvgWithArgumentCastFunction;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
@ -42,7 +46,6 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
/**
@ -232,24 +235,25 @@ public class H2Dialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean bindLimitParametersFirst() {
return false;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
};
}
@Override
public boolean supportsIfExistsAfterTableName() {

View File

@ -44,6 +44,10 @@ import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy;
import org.hibernate.dialect.lock.PessimisticReadSelectLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
@ -52,7 +56,6 @@ import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
/**
@ -67,7 +70,6 @@ import org.jboss.logging.Logger;
* @author Phillip Baird
* @author Fred Toussi
*/
@SuppressWarnings("deprecation")
public class HSQLDialect extends Dialect {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
@ -268,30 +270,36 @@ public class HSQLDialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
if ( hsqldbVersion < 20 ) {
return new StringBuilder( sql.length() + 10 )
.append( sql )
.insert(
sql.toLowerCase().indexOf( "select" ) + 6,
hasOffset ? " limit ? ?" : " top ?"
)
.toString();
}
else {
return sql + (hasOffset ? " offset ? limit ?" : " limit ?");
}
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
if ( hsqldbVersion < 20 ) {
return new StringBuilder( sql.length() + 10 )
.append( sql )
.insert(
sql.toLowerCase().indexOf( "select" ) + 6,
hasOffset ? " limit ? ?" : " top ?"
)
.toString();
}
else {
return sql + (hasOffset ? " offset ? limit ?" : " limit ?");
}
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersFirst() {
return hsqldbVersion < 20;
}
@Override
public boolean bindLimitParametersFirst() {
return hsqldbVersion < 20;
}
};
}
@Override
public boolean supportsIfExistsAfterTableName() {

View File

@ -29,6 +29,9 @@ import java.sql.Types;
import org.hibernate.MappingException;
import org.hibernate.dialect.constraint.InformixUniqueKeyExporter;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.util.JdbcExceptionHelper;
@ -190,35 +193,9 @@ public class InformixDialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
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().indexOf( "select" ) + 6, " first " + limit )
.toString();
}
@Override
public boolean supportsVariableLimit() {
return false;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new FirstLimitHandler(sql, selection);
}
@Override
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {

View File

@ -27,6 +27,10 @@ import java.sql.Types;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.type.StandardBasicTypes;
/**
@ -153,32 +157,32 @@ public class Ingres9Dialect extends IngresDialect {
// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public boolean supportsLimitOffset() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
final StringBuilder soff = new StringBuilder( " offset ?" );
final StringBuilder slim = new StringBuilder( " fetch first ? rows only" );
final StringBuilder sb = new StringBuilder( sql.length() + soff.length() + slim.length() )
.append( sql );
if ( LimitHelper.hasFirstRow(selection) ) {
sb.append( soff );
}
if ( LimitHelper.hasMaxRows(selection) ) {
sb.append( slim );
}
return sb.toString();
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return false;
}
@Override
public String getLimitString(String querySelect, int offset, int limit) {
final StringBuilder soff = new StringBuilder( " offset " + offset );
final StringBuilder slim = new StringBuilder( " fetch first " + limit + " rows only" );
final StringBuilder sb = new StringBuilder( querySelect.length() + soff.length() + slim.length() )
.append( querySelect );
if ( offset > 0 ) {
sb.append( soff );
}
if ( limit > 0 ) {
sb.append( slim );
}
return sb.toString();
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
}

View File

@ -30,6 +30,9 @@ import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.type.StandardBasicTypes;
/**
@ -56,7 +59,6 @@ import org.hibernate.type.StandardBasicTypes;
* @author Max Rydahl Andersen
* @author Raymond Fan
*/
@SuppressWarnings("deprecation")
public class IngresDialect extends Dialect {
/**
* Constructs a IngresDialect
@ -230,35 +232,9 @@ public class IngresDialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
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() + 16 )
.append( querySelect )
.insert( 6, " first " + limit )
.toString();
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public boolean useMaxForLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new FirstLimitHandler(sql, selection);
}
@Override
public boolean supportsTemporaryTables() {

View File

@ -27,6 +27,10 @@ import java.sql.Types;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.type.StandardBasicTypes;
/**
@ -34,7 +38,6 @@ import org.hibernate.type.StandardBasicTypes;
*
* @author Gavin King
*/
@SuppressWarnings("deprecation")
public class InterbaseDialect extends Dialect {
/**
@ -112,24 +115,20 @@ public class InterbaseDialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
final boolean hasOffset = LimitHelper.hasFirstRow(selection);
return hasOffset ? sql + " rows ? to ?" : sql + " rows ?";
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
return hasOffset ? sql + " rows ? to ?" : sql + " rows ?";
}
@Override
public boolean bindLimitParametersFirst() {
return false;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
};
}
@Override
public String getCurrentTimestampSelectString() {

View File

@ -33,6 +33,10 @@ import org.hibernate.NullPrecedence;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
@ -45,7 +49,6 @@ import org.hibernate.type.StandardBasicTypes;
*
* @author Gavin King
*/
@SuppressWarnings("deprecation")
public class MySQLDialect extends Dialect {
/**
@ -241,20 +244,26 @@ public class MySQLDialect extends Dialect {
);
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public String getDropForeignKeyString() {
return " drop foreign key ";
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
return sql + (hasOffset ? " limit ?, ?" : " limit ?");
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
final boolean hasOffset = LimitHelper.hasFirstRow(selection);
return sql + (hasOffset ? " limit ?, ?" : " limit ?");
}
@Override
public boolean supportsLimit() {
return true;
}
};
}
@Override
public char closeQuote() {

View File

@ -38,6 +38,10 @@ import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
@ -60,7 +64,6 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
*
* @author Steve Ebersole
*/
@SuppressWarnings("deprecation")
public class Oracle8iDialect extends Dialect {
private static final int PARAM_LIST_SIZE_LIMIT = 1000;
@ -244,35 +247,56 @@ public class Oracle8iDialect extends Dialect {
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
sql = sql.trim();
boolean isForUpdate = false;
if ( sql.toLowerCase().endsWith( " for update" ) ) {
sql = sql.substring( 0, sql.length()-11 );
isForUpdate = true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
sql = sql.trim();
boolean isForUpdate = false;
if ( sql.toLowerCase().endsWith( " for update" ) ) {
sql = sql.substring( 0, sql.length()-11 );
isForUpdate = true;
}
final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
if (hasOffset) {
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
}
else {
pagingSelect.append( "select * from ( " );
}
pagingSelect.append( sql );
if (hasOffset) {
pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
}
else {
pagingSelect.append( " ) where rownum <= ?" );
}
final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 );
if (hasOffset) {
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
}
else {
pagingSelect.append( "select * from ( " );
}
pagingSelect.append( sql );
if (hasOffset) {
pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" );
}
else {
pagingSelect.append( " ) where rownum <= ?" );
}
if ( isForUpdate ) {
pagingSelect.append( " for update" );
}
if ( isForUpdate ) {
pagingSelect.append( " for update" );
}
return pagingSelect.toString();
}
return pagingSelect.toString();
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
};
}
/**
* Allows access to the basic {@link Dialect#getSelectClauseNullString}
@ -364,11 +388,6 @@ public class Oracle8iDialect extends Dialect {
return true;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public String getForUpdateString(String aliases) {
return getForUpdateString() + " of " + aliases;
@ -379,16 +398,6 @@ public class Oracle8iDialect extends Dialect {
return getForUpdateString() + " of " + aliases + " nowait";
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean forUpdateOfColumns() {
return true;

View File

@ -26,6 +26,10 @@ package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.LockOptions;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.sql.ANSICaseFragment;
import org.hibernate.sql.CaseFragment;
@ -58,40 +62,61 @@ public class Oracle9iDialect extends Oracle8iDialect {
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
sql = sql.trim();
String forUpdateClause = null;
boolean isForUpdate = false;
final int forUpdateIndex = sql.toLowerCase().lastIndexOf( "for update") ;
if ( forUpdateIndex > -1 ) {
// save 'for update ...' and then remove it
forUpdateClause = sql.substring( forUpdateIndex );
sql = sql.substring( 0, forUpdateIndex-1 );
isForUpdate = true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
sql = sql.trim();
String forUpdateClause = null;
boolean isForUpdate = false;
final int forUpdateIndex = sql.toLowerCase().lastIndexOf( "for update") ;
if ( forUpdateIndex > -1 ) {
// save 'for update ...' and then remove it
forUpdateClause = sql.substring( forUpdateIndex );
sql = sql.substring( 0, forUpdateIndex-1 );
isForUpdate = true;
}
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
if (hasOffset) {
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
}
else {
pagingSelect.append( "select * from ( " );
}
pagingSelect.append( sql );
if (hasOffset) {
pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" );
}
else {
pagingSelect.append( " ) where rownum <= ?" );
}
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
if (hasOffset) {
pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " );
}
else {
pagingSelect.append( "select * from ( " );
}
pagingSelect.append( sql );
if (hasOffset) {
pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" );
}
else {
pagingSelect.append( " ) where rownum <= ?" );
}
if ( isForUpdate ) {
pagingSelect.append( " " );
pagingSelect.append( forUpdateClause );
}
if ( isForUpdate ) {
pagingSelect.append( " " );
pagingSelect.append( forUpdateClause );
}
return pagingSelect.toString();
}
return pagingSelect.toString();
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
};
}
@Override
public String getSelectClauseNullString(int sqlType) {

View File

@ -37,6 +37,10 @@ import org.hibernate.dialect.function.PositionSubstringFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
@ -233,19 +237,25 @@ public class PostgreSQL81Dialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
};
}
@Override
public boolean supportsIdentityColumns() {

View File

@ -37,12 +37,15 @@ import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.lock.UpdateLockingStrategy;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
/**
@ -57,7 +60,6 @@ import org.jboss.logging.Logger;
*
* @author Ploski and Hanson
*/
@SuppressWarnings("deprecation")
public class RDMSOS2200Dialect extends Dialect {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
@ -329,27 +331,33 @@ public class RDMSOS2200Dialect extends Dialect {
}
@Override
public boolean supportsLimit() {
return true;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new AbstractLimitHandler(sql, selection) {
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
if ( hasOffset ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return sql + " fetch first ? rows only ";
}
@Override
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public String getLimitString(String sql, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return sql + " fetch first " + limit + " rows only ";
}
@Override
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
};
}
@Override
public boolean supportsUnionAll() {

View File

@ -30,6 +30,9 @@ import org.hibernate.LockOptions;
import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.TopLimitHandler;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -72,23 +75,6 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
return "default values";
}
static int getAfterSelectInsertPoint(String sql) {
final int selectIndex = sql.toLowerCase().indexOf( "select" );
final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6);
}
@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( getAfterSelectInsertPoint( querySelect ), " top " + limit )
.toString();
}
/**
* Use <tt>insert table(...) values(...) select SCOPE_IDENTITY()</tt>
* <p/>
@ -98,26 +84,11 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
public String appendIdentitySelectToInsert(String insertSQL) {
return insertSQL + " select scope_identity()";
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new TopLimitHandler(sql, selection, false, false);
}
@Override
public char closeQuote() {

View File

@ -37,6 +37,9 @@ import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.lock.UpdateLockingStrategy;
import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
@ -169,35 +172,9 @@ public class TimesTenDialect extends Dialect {
}
@Override
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@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( 6, " first " + limit )
.toString();
}
public LimitHandler buildLimitHandler(String sql, RowSelection selection) {
return new FirstLimitHandler(sql, selection);
}
@Override
public boolean supportsCurrentTimestampSelection() {

View File

@ -11,7 +11,7 @@ import org.hibernate.engine.spi.RowSelection;
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
public abstract class AbstractLimitHandler implements LimitHandler {
protected final String sql;
protected String sql;
protected final RowSelection selection;
/**

View File

@ -0,0 +1,66 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.hibernate.dialect.pagination;
import org.hibernate.engine.spi.RowSelection;
/**
* @author Brett Meyer
*/
public class FirstLimitHandler extends AbstractLimitHandler {
public FirstLimitHandler(String sql, RowSelection selection) {
super(sql, selection);
}
@Override
public String getProcessedSql() {
boolean hasOffset = LimitHelper.hasFirstRow(selection);
if ( hasOffset ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuilder( sql.length() + 16 )
.append( sql )
.insert( sql.toLowerCase().indexOf( "select" ) + 6, " first ?" )
.toString();
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return false;
}
@Override
public boolean supportsVariableLimit() {
return false;
}
}

View File

@ -52,9 +52,8 @@ public class SQL2008StandardLimitHandler extends AbstractLimitHandler {
@Override
public String getProcessedSql() {
if (LimitHelper.useLimit(this, selection)) {
return sql
+ (LimitHelper.hasFirstRow(selection) ? " offset ? rows fetch next ? rows only"
: " fetch first ? rows only");
return sql + (LimitHelper.hasFirstRow(selection) ?
" offset ? rows fetch next ? rows only" : " fetch first ? rows only");
} else {
// or return unaltered SQL
return sql;

View File

@ -0,0 +1,76 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.hibernate.dialect.pagination;
import org.hibernate.engine.spi.RowSelection;
/**
* @author Brett Meyer
*/
public class TopLimitHandler extends AbstractLimitHandler {
private final boolean supportsVariableLimit;
private final boolean bindLimitParametersFirst;
public TopLimitHandler(String sql, RowSelection selection,
boolean supportsVariableLimit, boolean bindLimitParametersFirst) {
super(sql, selection);
this.supportsVariableLimit = supportsVariableLimit;
this.bindLimitParametersFirst = bindLimitParametersFirst;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return supportsVariableLimit;
}
public boolean bindLimitParametersFirst() {
return bindLimitParametersFirst;
}
@Override
public String getProcessedSql() {
if ( LimitHelper.hasFirstRow(selection) ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
final int selectIndex = sql.toLowerCase().indexOf( "select" );
final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
final int insertionPoint = selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6);
return new StringBuilder( sql.length() + 8 )
.append( sql )
.insert( insertionPoint, " TOP ? " )
.toString();
}
}

View File

@ -23,12 +23,12 @@
*/
package org.hibernate.dialect;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* Testing of patched support for Derby limit and offset queries; see HHH-3972
@ -48,9 +48,12 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
public void testInsertLimitClause() {
final int limit = 50;
final String input = "select * from tablename t where t.cat = 5";
final String expected = "select * from tablename t where t.cat = 5 fetch first " + limit + " rows only";
final String expected = "select * from tablename t where t.cat = 5 fetch first ? rows only";
final String actual = new LocalDerbyDialect().getLimitString( input, 0, limit );
RowSelection rowSelection = new RowSelection();
rowSelection.setFirstRow( 0 );
rowSelection.setMaxRows( limit );
final String actual = new LocalDerbyDialect().buildLimitHandler( input, rowSelection ).getProcessedSql();
assertEquals( expected, actual );
}
@ -59,9 +62,12 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
final int limit = 50;
final int offset = 200;
final String input = "select * from tablename t where t.cat = 5";
final String expected = "select * from tablename t where t.cat = 5 offset " + offset + " rows fetch next " + limit + " rows only";
final String expected = "select * from tablename t where t.cat = 5 offset ? rows fetch next ? rows only";
final String actual = new LocalDerbyDialect().getLimitString( input, offset, limit );
RowSelection rowSelection = new RowSelection();
rowSelection.setFirstRow( offset );
rowSelection.setMaxRows( limit );
final String actual = new LocalDerbyDialect().buildLimitHandler( input, rowSelection ).getProcessedSql();
assertEquals( expected, actual );
}
@ -70,10 +76,12 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
final int limit = 50;
final int offset = 200;
final String input = "select c11 as col1, c12 as col2, c13 as col13 from t1 for update of c11, c13";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 offset " + offset
+ " rows fetch next " + limit + " rows only for update of c11, c13";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 offset ? rows fetch next ? rows only for update of c11, c13";
final String actual = new LocalDerbyDialect().getLimitString( input, offset, limit );
RowSelection rowSelection = new RowSelection();
rowSelection.setFirstRow( offset );
rowSelection.setMaxRows( limit );
final String actual = new LocalDerbyDialect().buildLimitHandler( input, rowSelection ).getProcessedSql();
assertEquals( expected, actual );
}
@ -82,10 +90,12 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
final int limit = 50;
final int offset = 200;
final String input = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' with rr";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset " + offset
+ " rows fetch next " + limit + " rows only with rr";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset ? rows fetch next ? rows only with rr";
final String actual = new LocalDerbyDialect().getLimitString( input, offset, limit );
RowSelection rowSelection = new RowSelection();
rowSelection.setFirstRow( offset );
rowSelection.setMaxRows( limit );
final String actual = new LocalDerbyDialect().buildLimitHandler( input, rowSelection ).getProcessedSql();
assertEquals( expected, actual );
}
@ -94,10 +104,12 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
final int limit = 50;
final int offset = 200;
final String input = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' for update of c11,c13 with rr";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset " + offset
+ " rows fetch next " + limit + " rows only for update of c11,c13 with rr";
final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset ? rows fetch next ? rows only for update of c11,c13 with rr";
final String actual = new LocalDerbyDialect().getLimitString( input, offset, limit );
RowSelection rowSelection = new RowSelection();
rowSelection.setFirstRow( offset );
rowSelection.setMaxRows( limit );
final String actual = new LocalDerbyDialect().buildLimitHandler( input, rowSelection ).getProcessedSql();
assertEquals( expected, actual );
}
}

View File

@ -23,7 +23,10 @@
*/
package org.hibernate.dialect.resolver;
import java.sql.Connection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -38,7 +41,6 @@ import org.hibernate.boot.registry.selector.spi.StrategySelectionException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DB2400Dialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.DerbyTenFiveDialect;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.dialect.DerbyTenSixDialect;
@ -47,7 +49,6 @@ import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.InformixDialect;
import org.hibernate.dialect.IngresDialect;
import org.hibernate.dialect.Mocks;
import org.hibernate.dialect.MySQL5Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle10gDialect;
@ -68,16 +69,10 @@ import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfoSource;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
@ -158,7 +153,7 @@ public class DialectFactoryTest extends BaseUnitTestCase {
testDetermination( "PostgreSQL", 8, 2, PostgreSQL82Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 0, PostgreSQL9Dialect.class, resolver );
testDetermination( "EnterpriseDB", 9, 2, PostgresPlusDialect.class, resolver );
testDetermination( "Apache Derby", 10, 4, DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 10, 4, DB2Dialect.class, resolver );
testDetermination( "Apache Derby", 10, 5, DerbyTenFiveDialect.class, resolver );
testDetermination( "Apache Derby", 10, 6, DerbyTenSixDialect.class, resolver );
testDetermination( "Apache Derby", 11, 5, DerbyTenSevenDialect.class, resolver );

View File

@ -24,6 +24,7 @@
package org.hibernate.testing;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.RowSelection;
/**
* Container class for different implementation of the {@link DialectCheck} interface.
@ -106,13 +107,15 @@ abstract public class DialectChecks {
public static class SupportLimitCheck implements DialectCheck {
public boolean isMatch(Dialect dialect) {
return dialect.supportsLimit();
// TODO: Stupid -- better way?
return dialect.buildLimitHandler( "", new RowSelection() ).supportsLimit();
}
}
public static class SupportLimitAndOffsetCheck implements DialectCheck {
public boolean isMatch(Dialect dialect) {
return dialect.supportsLimit() && dialect.supportsLimitOffset();
// TODO: Stupid -- better way?
return dialect.buildLimitHandler( "", new RowSelection() ).supportsLimitOffset();
}
}