@@ -117,15 +117,14 @@ public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(
117
117
return null ;
118
118
}
119
119
120
- if (indexType .equals (IndexType .PARTIAL )) {
120
+ if (query . hasLimit () && indexType .equals (IndexType .PARTIAL )) {
121
121
// We cannot apply a limit for targets that are served using a partial index.
122
122
// If a partial index will be used to serve the target, the query may return a superset of
123
123
// documents that match the target (e.g. if the index doesn't include all the target's
124
124
// filters), or may return the correct set of documents in the wrong order (e.g. if the index
125
125
// doesn't include a segment for one of the orderBys). Therefore a limit should not be applied
126
126
// in such cases.
127
- query = query .limitToFirst (Target .NO_LIMIT );
128
- target = query .toTarget ();
127
+ return performQueryUsingIndex (query .limitToFirst (Target .NO_LIMIT ));
129
128
}
130
129
131
130
List <DocumentKey > keys = indexManager .getDocumentsMatchingTarget (target );
@@ -136,9 +135,12 @@ public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(
136
135
IndexOffset offset = indexManager .getMinOffset (target );
137
136
138
137
ImmutableSortedSet <Document > previousResults = applyQuery (query , indexedDocuments );
139
- if ((query .hasLimitToFirst () || query .hasLimitToLast ())
140
- && needsRefill (query .getLimitType (), keys .size (), previousResults , offset .getReadTime ())) {
141
- return null ;
138
+ if (needsRefill (query , keys .size (), previousResults , offset .getReadTime ())) {
139
+ // A limit query whose boundaries change due to local edits can be re-run against the cache
140
+ // by excluding the limit. This ensures that all documents that match the query's filters are
141
+ // included in the result set. The SDK can then apply the limit once all local edits are
142
+ // incorporated.
143
+ return performQueryUsingIndex (query .limitToFirst (Target .NO_LIMIT ));
142
144
}
143
145
144
146
return appendRemainingResults (values (indexedDocuments ), query , offset );
@@ -167,12 +169,7 @@ && needsRefill(query.getLimitType(), keys.size(), previousResults, offset.getRea
167
169
localDocumentsView .getDocuments (remoteKeys );
168
170
ImmutableSortedSet <Document > previousResults = applyQuery (query , documents );
169
171
170
- if ((query .hasLimitToFirst () || query .hasLimitToLast ())
171
- && needsRefill (
172
- query .getLimitType (),
173
- remoteKeys .size (),
174
- previousResults ,
175
- lastLimboFreeSnapshotVersion )) {
172
+ if (needsRefill (query , remoteKeys .size (), previousResults , lastLimboFreeSnapshotVersion )) {
176
173
return null ;
177
174
}
178
175
@@ -211,7 +208,7 @@ private ImmutableSortedSet<Document> applyQuery(
211
208
* Determines if a limit query needs to be refilled from cache, making it ineligible for
212
209
* index-free execution.
213
210
*
214
- * @param limitType The type of limit query for refill calculation .
211
+ * @param query The query.
215
212
* @param expectedDocumentCount The number of documents keys that matched the query at the last
216
213
* snapshot.
217
214
* @param sortedPreviousResults The documents that match the query based on the previous result,
@@ -221,12 +218,17 @@ private ImmutableSortedSet<Document> applyQuery(
221
218
* synchronized.
222
219
*/
223
220
private boolean needsRefill (
224
- Query . LimitType limitType ,
221
+ Query query ,
225
222
int expectedDocumentCount ,
226
223
ImmutableSortedSet <Document > sortedPreviousResults ,
227
224
SnapshotVersion limboFreeSnapshotVersion ) {
228
- // The query needs to be refilled if a previously matching document no longer matches.
225
+ if (!query .hasLimit ()) {
226
+ // Queries without limits do not need to be refilled.
227
+ return false ;
228
+ }
229
+
229
230
if (expectedDocumentCount != sortedPreviousResults .size ()) {
231
+ // The query needs to be refilled if a previously matching document no longer matches.
230
232
return true ;
231
233
}
232
234
@@ -237,7 +239,7 @@ private boolean needsRefill(
237
239
// did not change and documents from cache will continue to be "rejected" by this boundary.
238
240
// Therefore, we can ignore any modifications that don't affect the last document.
239
241
Document documentAtLimitEdge =
240
- limitType == Query .LimitType .LIMIT_TO_FIRST
242
+ query . getLimitType () == Query .LimitType .LIMIT_TO_FIRST
241
243
? sortedPreviousResults .getMaxEntry ()
242
244
: sortedPreviousResults .getMinEntry ();
243
245
if (documentAtLimitEdge == null ) {
0 commit comments