1
1
using System ;
2
2
using System . Collections ;
3
3
using System . Collections . Generic ;
4
-
4
+ using System . Linq ;
5
5
using NHibernate . Event ;
6
6
using NHibernate . Hql ;
7
- using NHibernate . Linq ;
8
7
using NHibernate . Type ;
9
8
using NHibernate . Util ;
10
9
@@ -96,8 +95,15 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
96
95
QueryParameters queryParametersToUse ;
97
96
if ( needsLimit )
98
97
{
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
+
100
105
RowSelection selection = new RowSelection ( ) ;
106
+ UpdateRowSelection ( selection , alreadyIncluded : 0 ) ;
101
107
selection . FetchSize = queryParameters . RowSelection . FetchSize ;
102
108
selection . Timeout = queryParameters . RowSelection . Timeout ;
103
109
queryParametersToUse = queryParameters . CreateCopyUsing ( selection ) ;
@@ -109,7 +115,7 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
109
115
110
116
IList combinedResults = results ?? new List < object > ( ) ;
111
117
var distinction = new HashSet < object > ( ReferenceComparer < object > . Instance ) ;
112
- int includedCount = - 1 ;
118
+ int includedCount = 0 ;
113
119
for ( int i = 0 ; i < Translators . Length ; i ++ )
114
120
{
115
121
IList tmp = Translators [ i ] . List ( session , queryParametersToUse ) ;
@@ -120,9 +126,7 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
120
126
? 0
121
127
: queryParameters . RowSelection . FirstRow ;
122
128
123
- int max = queryParameters . RowSelection . MaxRows == RowSelection . NoValue
124
- ? RowSelection . NoValue
125
- : queryParameters . RowSelection . MaxRows ;
129
+ int max = queryParametersToUse . RowSelection . MaxRows ;
126
130
127
131
int size = tmp . Count ;
128
132
for ( int x = 0 ; x < size ; x ++ )
@@ -132,22 +136,34 @@ public void PerformList(QueryParameters queryParameters, ISessionImplementor ses
132
136
{
133
137
continue ;
134
138
}
135
- includedCount ++ ;
136
- if ( includedCount < first )
139
+ if ( includedCount ++ < first )
137
140
{
138
141
continue ;
139
142
}
140
143
combinedResults . Add ( result ) ;
141
- if ( max >= 0 && includedCount > max )
144
+ if ( max != RowSelection . NoValue && includedCount >= max )
142
145
{
143
146
// break the outer loop !!!
144
147
return ;
145
148
}
146
149
}
150
+
151
+ UpdateRowSelection ( queryParametersToUse . RowSelection , includedCount ) ;
147
152
}
148
153
else
149
154
ArrayHelper . AddAll ( combinedResults , tmp ) ;
150
155
}
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
+ }
151
167
}
152
168
153
169
public IEnumerable PerformIterate ( QueryParameters queryParameters , IEventSource session )
0 commit comments