HHH-6849 Formatting and adding actual assertions to testOffset(). This is not addressing the SQLServer issue yet.
This commit is contained in:
parent
8114e9c5ae
commit
20141cae87
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
|
@ -84,7 +85,9 @@ public class SQLServer2005Dialect extends SQLServerDialect {
|
|||
@Override
|
||||
public String getLimitString(String query, int offset, int limit) {
|
||||
// We transform the query to one with an offset and limit if we have an offset and limit to bind
|
||||
if (offset > 1 || limit > 1) return getLimitString(query, true);
|
||||
if ( offset > 1 || limit > 1 ) {
|
||||
return getLimitString( query, true );
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -101,37 +104,32 @@ public class SQLServer2005Dialect extends SQLServerDialect {
|
|||
* SELECT * FROM query WHERE __hibernate_row_nr__ BEETWIN offset AND offset + last
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param querySqlString
|
||||
* The SQL statement to base the limit query off of.
|
||||
* @param offset
|
||||
* Offset of the first row to be returned by the query (zero-based)
|
||||
* @param limit
|
||||
* Maximum number of rows to be returned by the query
|
||||
* @param querySqlString The SQL statement to base the limit query off of.
|
||||
* @param hasOffset Is the query requesting an offset?
|
||||
*
|
||||
* @return A new SQL statement with the LIMIT clause applied.
|
||||
*/
|
||||
@Override
|
||||
public String getLimitString(String querySqlString, boolean hasOffset) {
|
||||
StringBuilder sb = new StringBuilder(querySqlString.trim().toLowerCase());
|
||||
StringBuilder sb = new StringBuilder( querySqlString.trim().toLowerCase() );
|
||||
|
||||
int orderByIndex = sb.indexOf("order by");
|
||||
CharSequence orderby = orderByIndex > 0 ? sb.subSequence(orderByIndex, sb.length())
|
||||
int orderByIndex = sb.indexOf( "order by" );
|
||||
CharSequence orderby = orderByIndex > 0 ? sb.subSequence( orderByIndex, sb.length() )
|
||||
: "ORDER BY CURRENT_TIMESTAMP";
|
||||
|
||||
// Delete the order by clause at the end of the query
|
||||
if (orderByIndex > 0) {
|
||||
sb.delete(orderByIndex, orderByIndex + orderby.length());
|
||||
if ( orderByIndex > 0 ) {
|
||||
sb.delete( orderByIndex, orderByIndex + orderby.length() );
|
||||
}
|
||||
|
||||
// HHH-5715 bug fix
|
||||
replaceDistinctWithGroupBy(sb);
|
||||
replaceDistinctWithGroupBy( sb );
|
||||
|
||||
insertRowNumberFunction(sb, orderby);
|
||||
insertRowNumberFunction( sb, orderby );
|
||||
|
||||
// Wrap the query within a with statement:
|
||||
sb.insert(0, "WITH query AS (").append(") SELECT * FROM query ");
|
||||
sb.append("WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?");
|
||||
sb.insert( 0, "WITH query AS (" ).append( ") SELECT * FROM query " );
|
||||
sb.append( "WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?" );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -144,10 +142,10 @@ public class SQLServer2005Dialect extends SQLServerDialect {
|
|||
* @param sql an sql query
|
||||
*/
|
||||
protected static void replaceDistinctWithGroupBy(StringBuilder sql) {
|
||||
int distinctIndex = sql.indexOf(DISTINCT);
|
||||
if (distinctIndex > 0) {
|
||||
sql.delete(distinctIndex, distinctIndex + DISTINCT.length() + 1);
|
||||
sql.append(" group by").append(getSelectFieldsWithoutAliases(sql));
|
||||
int distinctIndex = sql.indexOf( DISTINCT );
|
||||
if ( distinctIndex > 0 ) {
|
||||
sql.delete( distinctIndex, distinctIndex + DISTINCT.length() + 1 );
|
||||
sql.append( " group by" ).append( getSelectFieldsWithoutAliases( sql ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,41 +153,39 @@ public class SQLServer2005Dialect extends SQLServerDialect {
|
|||
* This utility method searches the given sql query for the fields of the select statement and returns them without
|
||||
* the aliases. See {@link SQLServer2005DialectTestCase#testGetSelectFieldsWithoutAliases()}
|
||||
*
|
||||
* @param an
|
||||
* sql query
|
||||
* @param sql sql query
|
||||
*
|
||||
* @return the fields of the select statement without their alias
|
||||
*/
|
||||
protected static CharSequence getSelectFieldsWithoutAliases(StringBuilder sql) {
|
||||
String select = sql.substring(sql.indexOf(SELECT) + SELECT.length(), sql.indexOf(FROM));
|
||||
String select = sql.substring( sql.indexOf( SELECT ) + SELECT.length(), sql.indexOf( FROM ) );
|
||||
|
||||
// Strip the as clauses
|
||||
return stripAliases(select);
|
||||
return stripAliases( select );
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that strips the aliases. See {@link SQLServer2005DialectTestCase#testStripAliases()}
|
||||
*
|
||||
* @param a
|
||||
* string to replace the as statements
|
||||
* @param str string to replace the as statements
|
||||
*
|
||||
* @return a string without the as statements
|
||||
*/
|
||||
protected static String stripAliases(String str) {
|
||||
return str.replaceAll("\\sas[^,]+(,?)", "$1");
|
||||
return str.replaceAll( "\\sas[^,]+(,?)", "$1" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Right after the select statement of a given query we must place the row_number function
|
||||
*
|
||||
* @param sql
|
||||
* the initial sql query without the order by clause
|
||||
* @param orderby
|
||||
* the order by clause of the query
|
||||
* @param sql the initial sql query without the order by clause
|
||||
* @param orderby the order by clause of the query
|
||||
*/
|
||||
protected static void insertRowNumberFunction(StringBuilder sql, CharSequence orderby) {
|
||||
// Find the end of the select statement
|
||||
int selectEndIndex = sql.indexOf(SELECT) + SELECT.length();
|
||||
int selectEndIndex = sql.indexOf( SELECT ) + SELECT.length();
|
||||
|
||||
// Insert after the select statement the row_number() function:
|
||||
sql.insert(selectEndIndex, " ROW_NUMBER() OVER (" + orderby + ") as __hibernate_row_nr__,");
|
||||
sql.insert( selectEndIndex, " ROW_NUMBER() OVER (" + orderby + ") as __hibernate_row_nr__," );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,4 +107,40 @@ public class DataPoint {
|
|||
public void setY(BigDecimal y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DataPoint dataPoint = (DataPoint) o;
|
||||
|
||||
if ( sequence != dataPoint.sequence ) {
|
||||
return false;
|
||||
}
|
||||
if ( description != null ? !description.equals( dataPoint.description ) : dataPoint.description != null ) {
|
||||
return false;
|
||||
}
|
||||
if ( x != null ? !x.equals( dataPoint.x ) : dataPoint.x != null ) {
|
||||
return false;
|
||||
}
|
||||
if ( y != null ? !y.equals( dataPoint.y ) : dataPoint.y != null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = sequence;
|
||||
result = 31 * result + ( x != null ? x.hashCode() : 0 );
|
||||
result = 31 * result + ( y != null ? y.hashCode() : 0 );
|
||||
result = 31 * result + ( description != null ? description.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,17 +22,17 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.pagination;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.SQLQuery;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
@ -44,7 +44,7 @@ import static org.junit.Assert.assertTrue;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class PaginationTest extends BaseCoreFunctionalTestCase {
|
||||
public static final int ROWS = 100;
|
||||
public static final int NUMBER_OF_TEST_ROWS = 100;
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
|
@ -92,8 +92,9 @@ public class PaginationTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
cleanupTestData();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOffset(){
|
||||
public void testOffset() {
|
||||
prepareTestData();
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
@ -102,9 +103,16 @@ public class PaginationTest extends BaseCoreFunctionalTestCase {
|
|||
result = generateBaseHQLQuery( session )
|
||||
.setFirstResult( 3 )
|
||||
.list();
|
||||
DataPoint firstDataPointHQL = (DataPoint) result.get( 0 );
|
||||
|
||||
result = generateBaseCriteria( session )
|
||||
.setFirstResult( 3 )
|
||||
.list();
|
||||
DataPoint firstDataPointCriteria = (DataPoint) result.get( 0 );
|
||||
|
||||
assertEquals( "The first entry should be the same in HQL and Criteria", firstDataPointHQL, firstDataPointHQL );
|
||||
assertEquals( "Wrong first result", 3, firstDataPointCriteria.getSequence() );
|
||||
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
cleanupTestData();
|
||||
|
@ -128,40 +136,40 @@ public class PaginationTest extends BaseCoreFunctionalTestCase {
|
|||
.setMaxResults( 20 )
|
||||
.list();
|
||||
assertEquals( 20, result.size() );
|
||||
assertEquals( 0, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
|
||||
assertEquals( 1, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
|
||||
assertEquals( 0, ( (DataPoint) result.get( 0 ) ).getSequence() );
|
||||
assertEquals( 1, ( (DataPoint) result.get( 1 ) ).getSequence() );
|
||||
|
||||
result = generateBaseCriteria( session )
|
||||
.setFirstResult( 1 )
|
||||
.setMaxResults( 20 )
|
||||
.list();
|
||||
assertEquals( 20, result.size() );
|
||||
assertEquals( 1, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
|
||||
assertEquals( 2, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
|
||||
assertEquals( 1, ( (DataPoint) result.get( 0 ) ).getSequence() );
|
||||
assertEquals( 2, ( (DataPoint) result.get( 1 ) ).getSequence() );
|
||||
|
||||
result = generateBaseCriteria( session )
|
||||
.setFirstResult( 99 )
|
||||
.setMaxResults( Integer.MAX_VALUE - 200 )
|
||||
.list();
|
||||
assertEquals( 1, result.size() );
|
||||
assertEquals( 99, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
|
||||
assertEquals( 99, ( (DataPoint) result.get( 0 ) ).getSequence() );
|
||||
|
||||
result = session.createQuery("select distinct description from DataPoint order by description")
|
||||
result = session.createQuery( "select distinct description from DataPoint order by description" )
|
||||
.setFirstResult( 2 )
|
||||
.setMaxResults( 3 )
|
||||
.list();
|
||||
assertEquals( 3, result.size() );
|
||||
assertEquals( "Description: 2", result.get(0));
|
||||
assertEquals( "Description: 3", result.get(1));
|
||||
assertEquals( "Description: 4", result.get(2));
|
||||
assertEquals( "Description: 2", result.get( 0 ) );
|
||||
assertEquals( "Description: 3", result.get( 1 ) );
|
||||
assertEquals( "Description: 4", result.get( 2 ) );
|
||||
|
||||
result = session.createSQLQuery( "select description, xval, yval from DataPoint order by xval, yval" )
|
||||
.setFirstResult( 2 )
|
||||
.setMaxResults( 5 )
|
||||
.list();
|
||||
assertEquals( 5, result.size() );
|
||||
Object[] row = (Object[]) result.get(0);
|
||||
assertTrue( row[0] instanceof String);
|
||||
Object[] row = (Object[]) result.get( 0 );
|
||||
assertTrue( row[0] instanceof String );
|
||||
|
||||
result = session.createSQLQuery( "select * from DataPoint order by xval, yval" )
|
||||
.setFirstResult( 2 )
|
||||
|
@ -193,14 +201,14 @@ public class PaginationTest extends BaseCoreFunctionalTestCase {
|
|||
private void prepareTestData() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
for ( int i = 0; i < ROWS; i++ ) {
|
||||
for ( int i = 0; i < NUMBER_OF_TEST_ROWS; i++ ) {
|
||||
DataPoint dataPoint = new DataPoint();
|
||||
dataPoint.setSequence( i );
|
||||
dataPoint.setDescription( "data point #" + i );
|
||||
BigDecimal x = new BigDecimal( i * 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN );
|
||||
dataPoint.setX( x );
|
||||
dataPoint.setY( new BigDecimal( Math.cos( x.doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
|
||||
dataPoint.setDescription("Description: " + i%5);
|
||||
dataPoint.setDescription( "Description: " + i % 5 );
|
||||
session.save( dataPoint );
|
||||
}
|
||||
session.getTransaction().commit();
|
||||
|
|
Loading…
Reference in New Issue