From: <ste...@us...> - 2006-02-16 22:51:05
|
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 ); } |