11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4-
4+ using System . Linq ;
55using NHibernate . Event ;
66using NHibernate . Hql ;
7- using NHibernate . Linq ;
87using NHibernate . Type ;
98using NHibernate . Util ;
109
@@ -96,8 +95,15 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
9695 QueryParameters queryParametersToUse ;
9796 if ( needsLimit )
9897 {
99- Log . Warn ( "firstResult/maxResults specified on polymorphic query; applying in memory!" ) ;
98+ if ( Translators . Any ( t => t . ContainsOrderByClause ) )
99+ // in memory evaluation is only problematic if items are skipped or if there is an order by clause thus correctness is not ensured
100+ Log . Warn ( "firstResult/maxResults specified on polymorphic query with order by; applying in memory!" ) ;
101+ else if ( queryParameters . RowSelection . FirstRow > 0 )
102+ // in memory evaluation is only problematic if items are skipped or if there is an order by clause thus correctness is not ensured
103+ Log . Warn ( "firstResult specified on polymorphic query; applying in memory!" ) ;
104+
100105 RowSelection selection = new RowSelection ( ) ;
106+ UpdateRowSelection ( selection , alreadyIncluded : 0 ) ;
101107 selection . FetchSize = queryParameters . RowSelection . FetchSize ;
102108 selection . Timeout = queryParameters . RowSelection . Timeout ;
103109 queryParametersToUse = queryParameters . CreateCopyUsing ( selection ) ;
@@ -109,7 +115,7 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
109115
110116 IList combinedResults = results ?? new List < object > ( ) ;
111117 var distinction = new HashSet < object > ( ReferenceComparer < object > . Instance ) ;
112- int includedCount = - 1 ;
118+ int includedCount = 0 ;
113119 for ( int i = 0 ; i < Translators . Length ; i ++ )
114120 {
115121 IList tmp = Translators [ i ] . List ( session , queryParametersToUse ) ;
@@ -120,9 +126,7 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
120126 ? 0
121127 : queryParameters . RowSelection . FirstRow ;
122128
123- int max = queryParameters . RowSelection . MaxRows == RowSelection . NoValue
124- ? RowSelection . NoValue
125- : queryParameters . RowSelection . MaxRows ;
129+ int max = queryParametersToUse . RowSelection . MaxRows ;
126130
127131 int size = tmp . Count ;
128132 for ( int x = 0 ; x < size ; x ++ )
@@ -132,22 +136,34 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
132136 {
133137 continue ;
134138 }
135- includedCount ++ ;
136- if ( includedCount < first )
139+ if ( includedCount ++ < first )
137140 {
138141 continue ;
139142 }
140143 combinedResults . Add ( result ) ;
141- if ( max >= 0 && includedCount > max )
144+ if ( max != RowSelection . NoValue && includedCount >= max )
142145 {
143146 // break the outer loop !!!
144147 return ;
145148 }
146149 }
150+
151+ UpdateRowSelection ( queryParametersToUse . RowSelection , includedCount ) ;
147152 }
148153 else
149154 ArrayHelper . AddAll ( combinedResults , tmp ) ;
150155 }
156+
157+ void UpdateRowSelection ( RowSelection selection , int alreadyIncluded )
158+ {
159+ if ( queryParameters . RowSelection . MaxRows != RowSelection . NoValue )
160+ {
161+ if ( queryParameters . RowSelection . FirstRow > 0 )
162+ selection . MaxRows = Math . Max ( 0 , queryParameters . RowSelection . FirstRow + queryParameters . RowSelection . MaxRows - alreadyIncluded ) ;
163+ else
164+ selection . MaxRows = Math . Max ( 0 , queryParameters . RowSelection . MaxRows - alreadyIncluded ) ;
165+ }
166+ }
151167 }
152168
153169 public IEnumerable PerformIterate ( QueryParameters queryParameters , IEventSource session )
0 commit comments