Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/engine/query
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13121/src/org/hibernate/engine/query
Modified Files:
HQLQueryPlan.java
Log Message:
HHH-1411 & HHH-1412 : in-memory application of DISTINCT and firstRow/maxRows in conjunction with collection fetches
Index: HQLQueryPlan.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/engine/query/HQLQueryPlan.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- HQLQueryPlan.java 27 Jan 2006 23:38:07 -0000 1.7
+++ HQLQueryPlan.java 16 Feb 2006 22:50:59 -0000 1.8
@@ -14,6 +14,7 @@
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.RowSelection;
import org.hibernate.event.EventSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -148,9 +149,51 @@
log.trace( "find: " + getSourceQuery() );
queryParameters.traceParameters( session.getFactory() );
}
+ boolean needsLimit = translators.length > 1 && queryParameters.getRowSelection().definesLimits();
+ QueryParameters queryParametersToUse;
+ if ( needsLimit ) {
+ log.warn( "firstResult/maxResults specified on polymorphic query; applying in memory!" );
+ RowSelection selection = new RowSelection();
+ selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
+ selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
+ queryParametersToUse = queryParameters.createCopyUsing( selection );
+ }
+ else {
+ queryParametersToUse = queryParameters;
+ }
+
List combinedResults = new ArrayList();
- for ( int i = 0; i < translators.length; i++ ) {
- combinedResults.addAll( translators[i].list( session, queryParameters ) );
+ int includedCount = -1;
+ translator_loop: for ( int i = 0; i < translators.length; i++ ) {
+ List tmp = translators[i].list( session, queryParametersToUse );
+ if ( needsLimit ) {
+ // NOTE : firstRow is zero-based
+ int first = queryParameters.getRowSelection().getFirstRow() == null
+ ? 0
+ : queryParameters.getRowSelection().getFirstRow().intValue();
+ int max = queryParameters.getRowSelection().getMaxRows() == null
+ ? -1
+ : queryParameters.getRowSelection().getMaxRows().intValue();
+ final int size = tmp.size();
+ for ( int x = 0; x < size; x++ ) {
+ final Object result = tmp.get( x );
+ if ( combinedResults.contains( result ) ) {
+ continue;
+ }
+ includedCount++;
+ if ( includedCount < first ) {
+ continue;
+ }
+ combinedResults.add( result );
+ if ( max >= 0 && includedCount > max ) {
+ // break the outer loop !!!
+ break translator_loop;
+ }
+ }
+ }
+ else {
+ combinedResults.addAll( tmp );
+ }
}
return combinedResults;
}
@@ -191,6 +234,9 @@
if ( translators.length != 1 ) {
throw new QueryException( "implicit polymorphism not supported for scroll() queries" );
}
+ if ( queryParameters.getRowSelection().definesLimits() && translators[0].containsCollectionFetches() ) {
+ throw new QueryException( "firstResult/maxResults not supported in conjunction with scroll() of a query containing collection fetches" );
+ }
return translators[0].scroll( queryParameters, session );
}
|