HHH-6849 Formatting and adding actual assertions to testOffset(). This is not addressing the SQLServer issue yet.

This commit is contained in:
Hardy Ferentschik 2011-11-25 12:05:51 +01:00 committed by Strong Liu
parent 8114e9c5ae
commit 20141cae87
3 changed files with 92 additions and 52 deletions

View File

@ -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__," );
}
}

View File

@ -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;
}
}

View File

@ -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();