[hibernate-commits] Hibernate SVN: r15897 - in core/branches/Branch_3_2/src/org/hibernate: loader and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Feb 4 18:14:05 EST 2009


Author: steve.ebersole at jboss.com
Date: 2009-02-04 18:14:05 -0500 (Wed, 04 Feb 2009)
New Revision: 15897

Modified:
   core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
   core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java
   core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
Log:
HHH-3750 : dialect first-result handling

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -32,9 +32,9 @@
 import org.hibernate.util.StringHelper;
 
 /**
- * Cach&eacute; 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Caché SQL.<br>
+ * Cach&eacute; 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
  * <br>
- * Compatible with Caché 2007.1.
+ * Compatible with Cach� 2007.1.
  * <br>
  * <head>
  * <title>Cach&eacute; and Hibernate</title>
@@ -189,8 +189,8 @@
 public class Cache71Dialect extends Dialect {
 
 	/**
-	 * Creates new <code>Caché71Dialect</code> instance. Sets up the JDBC /
-	 * Caché type mappings.
+	 * Creates new <code>Cach�71Dialect</code> instance. Sets up the JDBC /
+	 * Cach� type mappings.
 	 */
 	public Cache71Dialect() {
 		super();
@@ -575,7 +575,7 @@
 
 	public String getLimitString(String sql, boolean hasOffset) {
 		if ( hasOffset ) {
-			throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
+			throw new UnsupportedOperationException( "query result offset is not supported" );
 		}
 
 		// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -25,15 +25,6 @@
 		return false;
 	}
 
-	public String getLimitString(String sql, int offset, int limit) {
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
-	}
-
 	public boolean useMaxForLimit() {
 		return true;
 	}
@@ -42,4 +33,16 @@
 		return false;
 	}
 
+	public String getLimitString(String sql, int offset, int limit) {
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "query result offset is not supported" );
+		}
+		return new StringBuffer( sql.length() + 40 )
+				.append( sql )
+				.append( " fetch first " )
+				.append( limit )
+				.append( " rows only " )
+				.toString();
+	}
+
 }
\ No newline at end of file

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -1,11 +1,11 @@
 package org.hibernate.dialect;
 
 /**
-* An SQL dialect for DB2/400
-* @author Peter DeGregorio (pdegregorio)
-* This class provides support for DB2 Universal Database for iSeries,
-* also known as DB2/400.
-*/
+ * An SQL dialect for DB2/400.  This class provides support for DB2 Universal Database for iSeries,
+ * also known as DB2/400.
+ *
+ * @author Peter DeGregorio (pdegregorio)
+ */
 public class DB2400Dialect extends DB2Dialect {
 
 	public boolean supportsSequences() {
@@ -24,15 +24,6 @@
 		return false;
 	}
 
-	public String getLimitString(String sql, int offset, int limit) {
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
-	}
-
 	public boolean useMaxForLimit() {
 		return true;
 	}
@@ -41,4 +32,16 @@
 		return false;
 	}
 
+	public String getLimitString(String sql, int offset, int limit) {
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "query result offset is not supported" );
+		}
+		return new StringBuffer( sql.length() + 40 )
+				.append( sql )
+				.append( " fetch first " )
+				.append( limit )
+				.append( " rows only " )
+				.toString();
+	}
+
 }
\ No newline at end of file

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -220,21 +220,20 @@
 	}
 
 	public String getLimitString(String sql, boolean hasOffset) {
-
 		int startOfSelect = sql.toLowerCase().indexOf("select");
 
 		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
-					.append( sql.substring(0, startOfSelect) ) //add the comment
-					.append("select * from ( select ") //nest the main query in an outer select
-					.append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
+				.append( sql.substring(0, startOfSelect) )	// add the comment
+				.append("select * from ( select ") 			// nest the main query in an outer select
+				.append( getRowNumber(sql) ); 				// add the rownnumber bit into the outer query select list
 
 		if ( hasDistinct(sql) ) {
-			pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
-				.append( sql.substring(startOfSelect) ) //add the main query
-				.append(" ) as row_"); //close off the inner nested select
+			pagingSelect.append(" row_.* from ( ")			// add another (inner) nested select
+					.append( sql.substring(startOfSelect) ) // add the main query
+					.append(" ) as row_"); 					// close off the inner nested select
 		}
 		else {
-			pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
+			pagingSelect.append( sql.substring( startOfSelect + 6 ) ); // add the main query
 		}
 
 		pagingSelect.append(" ) as temp_ where rownumber_ ");
@@ -250,6 +249,18 @@
 		return pagingSelect.toString();
 	}
 
+	/**
+	 * DB2 does have a one-based offset, however this was actually already handled in the limiot string building
+	 * (the '?+1' bit).  To not mess up inheritors, I'll leave that part alone and not touch the offset here.
+	 *
+	 * @param zeroBasedFirstResult The user-supplied, zero-based offset
+	 *
+	 * @return zeroBasedFirstResult
+	 */
+	public int convertToFirstRowValue(int zeroBasedFirstResult) {
+		return zeroBasedFirstResult;
+	}
+
 	private static boolean hasDistinct(String sql) {
 		return sql.toLowerCase().indexOf("select distinct")>=0;
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -872,7 +872,26 @@
 		throw new UnsupportedOperationException( "paged queries not supported" );
 	}
 
+	/**
+	 * Hibernate APIs explcitly state that setFirstResult() should be a zero-based offset. Here we allow the
+	 * Dialect a chance to convert that value based on what the underlying db or driver will expect.
+	 * <p/>
+	 * NOTE: what gets passed into {@link #getLimitString(String,int,int)} is the zero-based offset.  Dialects which
+	 * do not {@link #supportsVariableLimit} should take care to perform any needed {@link #convertToFirstRowValue}
+	 * calls prior to injecting the limit values into the SQL string.
+	 *
+	 * @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
+	 *
+	 * @return The corresponding db/dialect specific offset.
+	 *
+	 * @see org.hibernate.Query#setFirstResult
+	 * @see org.hibernate.Criteria#setFirstResult
+	 */
+	public int convertToFirstRowValue(int zeroBasedFirstResult) {
+		return zeroBasedFirstResult;
+	}
 
+
 	// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	/**

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -3,6 +3,7 @@
 
 /**
  * An SQL dialect for Firebird.
+ *
  * @author Reha CENANI
  */
 public class FirebirdDialect extends InterbaseDialect {
@@ -12,10 +13,10 @@
 	}
 
 	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.insert(6, hasOffset ? " first ? skip ?" : " first ?")
-			.toString();
+		return new StringBuffer( sql.length() + 20 )
+				.append( sql )
+				.insert( 6, hasOffset ? " first ? skip ?" : " first ?" )
+				.toString();
 	}
 
 	public boolean bindLimitParametersFirst() {

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -84,28 +84,27 @@
 	 * @return String
 	 */
 	public String getAddForeignKeyConstraintString(
-			String constraintName, 
-			String[] foreignKey, 
-			String referencedTable, 
-			String[] primaryKey, boolean referencesPrimaryKey
-	) {
-		StringBuffer result = new StringBuffer(30);
-		
-		result.append(" add constraint ")
-			.append(" foreign key (")
-			.append( StringHelper.join(", ", foreignKey) )
-			.append(") references ")
-			.append(referencedTable);
-		
-		if(!referencesPrimaryKey) {
-			result.append(" (")
-			   .append( StringHelper.join(", ", primaryKey) )
-			   .append(')');
+			String constraintName,
+			String[] foreignKey,
+			String referencedTable,
+			String[] primaryKey,
+			boolean referencesPrimaryKey) {
+		StringBuffer result = new StringBuffer( 30 )
+				.append( " add constraint " )
+				.append( " foreign key (" )
+				.append( StringHelper.join( ", ", foreignKey ) )
+				.append( ") references " )
+				.append( referencedTable );
+
+		if ( !referencesPrimaryKey ) {
+			result.append( " (" )
+					.append( StringHelper.join( ", ", primaryKey ) )
+					.append( ')' );
 		}
 
-		result.append(" constraint ").append(constraintName);
-			
-			return result.toString();
+		result.append( " constraint " ).append( constraintName );
+
+		return result.toString();
 	}
 
 	/**
@@ -149,11 +148,13 @@
 	}
 
 	public String getLimitString(String querySelect, int offset, int limit) {
-		if (offset>0) throw new UnsupportedOperationException("informix has no offset");
-		return new StringBuffer( querySelect.length()+8 )
-			.append(querySelect)
-			.insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
-			.toString();
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "query result offset is not supported" );
+		}
+		return new StringBuffer( querySelect.length() + 8 )
+				.append( querySelect )
+				.insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
+				.toString();
 	}
 
 	public boolean supportsVariableLimit() {

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -234,7 +234,7 @@
 	 */
 	public String getLimitString(String querySelect, int offset, int limit) {
 		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "offset not supported" );
+			throw new UnsupportedOperationException( "query result offset is not supported" );
 		}
 		return new StringBuffer( querySelect.length() + 16 )
 				.append( querySelect )

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -213,38 +213,12 @@
 	}
 
 	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.append( hasOffset ? " limit ?, ?" : " limit ?")
-			.toString();
+		return new StringBuffer( sql.length() + 20 )
+				.append( sql )
+				.append( hasOffset ? " limit ?, ?" : " limit ?" )
+				.toString();
 	}
 
-	/*
-	 * Temporary, until MySQL fix Connector/J bug
-	 */
-	/*public String getLimitString(String sql, int offset, int limit) {
-		StringBuffer buf = new StringBuffer( sql.length()+20 )
-			.append(sql);
-		if (offset>0) {
-			buf.append(" limit ")
-				.append(offset)
-				.append(", ")
-				.append(limit);
-		}
-		else {
-			buf.append(" limit ")
-				.append(limit);
-		}
-		return buf.toString();
-	}*/
-
-	/*
-	 * Temporary, until MySQL fix Connector/J bug
-	 */
-	/*public boolean supportsVariableLimit() {
-		return false;
-	}*/
-
 	public char closeQuote() {
 		return '`';
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -154,9 +154,9 @@
 
 	public String getLimitString(String sql, boolean hasOffset) {
 		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.append(hasOffset ? " limit ? offset ?" : " limit ?")
-			.toString();
+				.append( sql )
+				.append( hasOffset ? " limit ? offset ?" : " limit ?" )
+				.toString();
 	}
 
 	public boolean bindLimitParametersInReverseOrder() {

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -292,13 +292,15 @@
 	}
 
     public String getLimitString(String sql, int offset, int limit) {
-        if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "query result offset is not supported" );
+		}
+		return new StringBuffer( sql.length() + 40 )
+				.append( sql )
+				.append( " fetch first " )
+				.append( limit )
+				.append( " rows only " )
+				.toString();
 	}
 
 	public boolean supportsVariableLimit() {

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -42,12 +42,12 @@
 
 	public String getLimitString(String querySelect, int offset, int limit) {
 		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "sql server has no offset" );
+			throw new UnsupportedOperationException( "query result offset is not supported" );
 		}
-		return new StringBuffer( querySelect.length()+8 )
-			.append(querySelect)
-			.insert( getAfterSelectInsertPoint(querySelect), " top " + limit )
-			.toString();
+		return new StringBuffer( querySelect.length() + 8 )
+				.append( querySelect )
+				.insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )
+				.toString();
 	}
 
 	/**

Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -150,12 +150,12 @@
 
 	public String getLimitString(String querySelect, int offset, int limit) {
 		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "TimesTen does not support offset" );
+			throw new UnsupportedOperationException( "query result offset is not supported" );
 		}
-		return new StringBuffer( querySelect.length()+8 )
-			.append(querySelect)
-			.insert( 6, " first " + limit )
-			.toString();
+		return new StringBuffer( querySelect.length() + 8 )
+				.append( querySelect )
+				.insert( 6, " first " + limit )
+				.toString();
 	}
 
 	public boolean supportsCurrentTimestampSelection() {

Modified: core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java	2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java	2009-02-04 23:14:05 UTC (rev 15897)
@@ -1497,6 +1497,10 @@
 		}
 	}
 
+	private int interpretFirstRow(int zeroBasedFirstResult) {
+		return getFactory().getDialect().convertToFirstRowValue( zeroBasedFirstResult );
+	}
+
 	/**
 	 * Should we pre-process the SQL string, adding a dialect-specific
 	 * LIMIT clause.
@@ -1606,7 +1610,7 @@
 	 * @return The appropriate value to bind into the limit clause.
 	 */
 	private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
-		final int firstRow = getFirstRow( selection );
+		final int firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) );
 		final int lastRow = selection.getMaxRows().intValue();
 		if ( dialect.useMaxForLimit() ) {
 			return lastRow + firstRow;
@@ -1636,7 +1640,7 @@
 		if ( !hasMaxRows( selection ) ) {
 			throw new AssertionFailure( "no max results set" );
 		}
-		int firstRow = getFirstRow( selection );
+		int firstRow = interpretFirstRow( getFirstRow( selection ) );
 		int lastRow = getMaxOrLimit( selection, dialect );
 		boolean hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() );
 		boolean reverse = dialect.bindLimitParametersInReverseOrder();
@@ -1654,7 +1658,7 @@
 			final PreparedStatement st,
 			final RowSelection selection) throws SQLException {
 		if ( hasMaxRows( selection ) ) {
-			st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
+			st.setMaxRows( selection.getMaxRows().intValue() + interpretFirstRow( getFirstRow( selection ) ) );
 		}
 	}
 




More information about the hibernate-commits mailing list