Skip to content

Commit bceea26

Browse files
committed
CSI compatibility
1 parent 2ed1a48 commit bceea26

File tree

4 files changed

+98
-14
lines changed

4 files changed

+98
-14
lines changed

packages/firestore/src/local/indexeddb_index_manager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ export class IndexedDbIndexManager implements IndexManager {
275275
return this.getIndexType(transaction, subTarget).next(type => {
276276
if (type === IndexType.NONE || type === IndexType.PARTIAL) {
277277
const targetIndexMatcher = new TargetIndexMatcher(subTarget);
278-
return this.addFieldIndex(
279-
transaction,
280-
targetIndexMatcher.buildTargetIndex()
281-
);
278+
const fieldIndex = targetIndexMatcher.buildTargetIndex();
279+
if (fieldIndex != null) {
280+
return this.addFieldIndex(transaction, fieldIndex);
281+
}
282282
}
283283
});
284284
}

packages/firestore/src/model/target_index_matcher.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ export class TargetIndexMatcher {
8383
}
8484
}
8585

86+
hasMultipleInequality(): boolean {
87+
return this.inequalityFilters.size > 1;
88+
}
89+
8690
/**
8791
* Returns whether the index can be used to serve the TargetIndexMatcher's
8892
* target.
@@ -110,6 +114,11 @@ export class TargetIndexMatcher {
110114
'Collection IDs do not match'
111115
);
112116

117+
if (this.hasMultipleInequality()) {
118+
// Only single inequality is supported for now.
119+
return false;
120+
}
121+
113122
// If there is an array element, find a matching filter.
114123
const arraySegment = fieldIndexGetArraySegment(index);
115124
if (
@@ -148,11 +157,6 @@ export class TargetIndexMatcher {
148157
}
149158

150159
if (this.inequalityFilters.size > 0) {
151-
if (this.inequalityFilters.size > 1) {
152-
// Only single inequality is supported for now.
153-
return false;
154-
}
155-
156160
// Only a single inequality is currently supported. Get the only entry in the set.
157161
const inequalityFilter = this.inequalityFilters.getIterator().getNext();
158162
// If there is an inequality filter and the field was not in one of the
@@ -187,8 +191,15 @@ export class TargetIndexMatcher {
187191
return true;
188192
}
189193

190-
/** Returns a full matched field index for this target. */
191-
buildTargetIndex(): FieldIndex {
194+
/**
195+
* Returns a full matched field index for this target. Currently multiple
196+
* inequality query is not supported so function returns null.
197+
*/
198+
buildTargetIndex(): FieldIndex | null {
199+
if (this.hasMultipleInequality()) {
200+
return null;
201+
}
202+
192203
// We want to make sure only one segment created for one field. For example,
193204
// in case like a == 3 and a > 2, Index {a ASCENDING} will only be created
194205
// once.

packages/firestore/test/unit/local/local_store.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,4 +3098,57 @@ function indexedDbLocalStoreTests(
30983098
.toReturnChanged('coll/a')
30993099
.finish();
31003100
});
3101+
3102+
it('index auto creation does not work with multiple inequality', () => {
3103+
const query_ = query(
3104+
'coll',
3105+
filter('field1', '<', 5),
3106+
filter('field2', '<', 5)
3107+
);
3108+
return (
3109+
expectLocalStore()
3110+
.afterAllocatingQuery(query_)
3111+
.toReturnTargetId(2)
3112+
.afterIndexAutoCreationConfigure({
3113+
isEnabled: true,
3114+
indexAutoCreationMinCollectionSize: 0,
3115+
relativeIndexReadCostPerDocument: 2
3116+
})
3117+
.afterRemoteEvents([
3118+
docAddedRemoteEvent(
3119+
doc('coll/a', 10, { field1: 1, field2: 2 }),
3120+
[2],
3121+
[]
3122+
),
3123+
docAddedRemoteEvent(
3124+
doc('coll/b', 10, { field1: 8, field2: 2 }),
3125+
[2],
3126+
[]
3127+
),
3128+
docAddedRemoteEvent(
3129+
doc('coll/c', 10, { field1: 'string', field2: 2 }),
3130+
[2],
3131+
[]
3132+
),
3133+
docAddedRemoteEvent(doc('coll/d', 10, { field1: 1 }), [2], []),
3134+
docAddedRemoteEvent(
3135+
doc('coll/e', 10, { field1: 4, field2: 4 }),
3136+
[2],
3137+
[]
3138+
)
3139+
])
3140+
// First time query runs without indexes.
3141+
// Based on current heuristic, collection document counts (5) >
3142+
// 2 * resultSize (2).
3143+
// Full matched index will not be created since FieldIndex does not support multiple inequality.
3144+
.afterExecutingQuery(query_)
3145+
.toHaveRead({ documentsByKey: 0, documentsByCollection: 2 })
3146+
.toReturnChanged('coll/a', 'coll/e')
3147+
.afterBackfillIndexes()
3148+
.afterExecutingQuery(query_)
3149+
.toHaveRead({ documentsByKey: 0, documentsByCollection: 2 })
3150+
.toReturnChanged('coll/a', 'coll/e')
3151+
.finish()
3152+
);
3153+
});
31013154
}

packages/firestore/test/unit/model/target_index_matcher.test.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
newQueryForCollectionGroup
2626
} from '../../../src/core/query';
2727
import { targetGetSegmentCount } from '../../../src/core/target';
28-
import { IndexKind } from '../../../src/model/field_index';
28+
import { FieldIndex, IndexKind } from '../../../src/model/field_index';
2929
import { TargetIndexMatcher } from '../../../src/model/target_index_matcher';
3030
import { fieldIndex, filter, orderBy, query } from '../../util/helpers';
3131

@@ -956,12 +956,32 @@ describe('Target Bounds', () => {
956956
));
957957
});
958958

959+
describe('query with multiple inequality', () => {
960+
it('returns null', () => {
961+
const q = queryWithAddedFilter(
962+
queryWithAddedFilter(query('collId'), filter('a', '>=', 1)),
963+
filter('b', '<=', 10)
964+
);
965+
const target = queryToTarget(q);
966+
const targetIndexMatcher = new TargetIndexMatcher(target);
967+
expect(targetIndexMatcher.hasMultipleInequality()).is.true;
968+
const expectedIndex = targetIndexMatcher.buildTargetIndex();
969+
expect(expectedIndex).is.null;
970+
});
971+
});
972+
959973
function validateBuildTargetIndexCreateFullMatchIndex(q: Query): void {
960974
const target = queryToTarget(q);
961975
const targetIndexMatcher = new TargetIndexMatcher(target);
976+
expect(targetIndexMatcher.hasMultipleInequality()).is.false;
962977
const expectedIndex = targetIndexMatcher.buildTargetIndex();
963-
expect(targetIndexMatcher.servedByIndex(expectedIndex)).is.true;
964-
expect(expectedIndex.fields.length >= targetGetSegmentCount(target));
978+
expect(expectedIndex).is.not.null;
979+
expect(targetIndexMatcher.servedByIndex(expectedIndex as FieldIndex)).is
980+
.true;
981+
expect(
982+
(expectedIndex as FieldIndex).fields.length >=
983+
targetGetSegmentCount(target)
984+
);
965985
}
966986
});
967987

0 commit comments

Comments
 (0)