Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Firestore/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Unreleased
- [fixed] Fixed the `null` value handling in `isNotEqualTo` and `notIn` filters.

# 11.11.0
- [fixed] Fixed the customized priority queue compare function used cache index manager. (#14496)

Expand Down
52 changes: 52 additions & 0 deletions Firestore/Example/Tests/Integration/API/FIRQueryTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,31 @@ - (void)testQueriesCanUseNotEqualFiltersWithDocIds {
(@[ testDocs[@"ab"], testDocs[@"ba"], testDocs[@"bb"] ]));
}

- (void)testSDKUsesNotEqualFiltersSameAsServer {
NSDictionary *testDocs = @{
@"a" : @{@"zip" : @(NAN)},
@"b" : @{@"zip" : @91102},
@"c" : @{@"zip" : @98101},
@"d" : @{@"zip" : @"98101"},
@"e" : @{@"zip" : @[ @98101 ]},
@"f" : @{@"zip" : @[ @98101, @98102 ]},
@"g" : @{@"zip" : @[ @"98101", @{@"zip" : @98101} ]},
@"h" : @{@"zip" : @{@"code" : @500}},
@"i" : @{@"zip" : [NSNull null]},
@"j" : @{@"code" : @500},
};
FIRCollectionReference *collection = [self collectionRefWithDocuments:testDocs];

// populate cache with all documents first to ensure getDocsFromCache() scans all docs
[self readDocumentSetForRef:collection];

[self checkOnlineAndOfflineQuery:[collection queryWhereField:@"zip" isNotEqualTo:@98101]
matchesResult:@[ @"a", @"b", @"d", @"e", @"f", @"g", @"h" ]];

[self checkOnlineAndOfflineQuery:[collection queryWhereField:@"zip" isNotEqualTo:@(NAN)]
matchesResult:@[ @"b", @"c", @"d", @"e", @"f", @"g", @"h" ]];
}

- (void)testQueriesCanUseArrayContainsFilters {
NSDictionary *testDocs = @{
@"a" : @{@"array" : @[ @42 ]},
Expand Down Expand Up @@ -694,6 +719,33 @@ - (void)testQueriesCanUseNotInFiltersWithDocIds {
XCTAssertEqualObjects(FIRQuerySnapshotGetData(snapshot), (@[ testDocs[@"ba"], testDocs[@"bb"] ]));
}

- (void)testSDKUsesNotInFiltersSameAsServer {
NSDictionary *testDocs = @{
@"a" : @{@"zip" : @(NAN)},
@"b" : @{@"zip" : @91102},
@"c" : @{@"zip" : @98101},
@"d" : @{@"zip" : @"98101"},
@"e" : @{@"zip" : @[ @98101 ]},
@"f" : @{@"zip" : @[ @98101, @98102 ]},
@"g" : @{@"zip" : @[ @"98101", @{@"zip" : @98101} ]},
@"h" : @{@"zip" : @{@"code" : @500}},
@"i" : @{@"zip" : [NSNull null]},
@"j" : @{@"code" : @500},
};
FIRCollectionReference *collection = [self collectionRefWithDocuments:testDocs];

// populate cache with all documents first to ensure getDocsFromCache() scans all docs
[self readDocumentSetForRef:collection];

[self checkOnlineAndOfflineQuery:[collection
queryWhereField:@"zip"
notIn:@[ @98101, @98103, @[ @98101, @98102 ] ]]
matchesResult:@[ @"a", @"b", @"d", @"e", @"g", @"h" ]];

[self checkOnlineAndOfflineQuery:[collection queryWhereField:@"zip" notIn:@[ [NSNull null] ]]
matchesResult:@[]];
}

- (void)testQueriesCanUseArrayContainsAnyFilters {
NSDictionary *testDocs = @{
@"a" : @{@"array" : @[ @42 ]},
Expand Down
3 changes: 2 additions & 1 deletion Firestore/core/src/core/field_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ bool FieldFilter::Rep::Matches(const model::Document& doc) const {

// Types do not have to match in NotEqual filters.
if (op_ == Operator::NotEqual) {
return MatchesComparison(Compare(lhs, *value_rhs_));
return lhs.which_value_type != google_firestore_v1_Value_null_value_tag &&
MatchesComparison(Compare(lhs, *value_rhs_));
}

// Only compare types with matching backend order (such as double and int).
Expand Down
5 changes: 4 additions & 1 deletion Firestore/core/src/core/not_in_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ bool NotInFilter::Rep::Matches(const Document& doc) const {
return false;
}
absl::optional<google_firestore_v1_Value> maybe_lhs = doc->field(field());
return maybe_lhs && !Contains(array_value, *maybe_lhs);
return maybe_lhs &&
maybe_lhs->which_value_type !=
google_firestore_v1_Value_null_value_tag &&
!Contains(array_value, *maybe_lhs);
}

} // namespace core
Expand Down
4 changes: 2 additions & 2 deletions Firestore/core/test/unit/core/query_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ TEST(QueryTest, NanFilter) {
EXPECT_THAT(query, Matches(doc3));
EXPECT_THAT(query, Matches(doc4));
EXPECT_THAT(query, Matches(doc5));
EXPECT_THAT(query, Matches(doc6));
EXPECT_THAT(query, Not(Matches(doc6)));
}

TEST(QueryTest, ArrayContainsFilter) {
Expand Down Expand Up @@ -383,7 +383,7 @@ TEST(QueryTest, NotInFilters) {

// Null match.
doc = Doc("collection/1", 0, Map("zip", nullptr));
EXPECT_THAT(query, Matches(doc));
EXPECT_THAT(query, Not(Matches(doc)));

// NAN match.
doc = Doc("collection/1", 0, Map("zip", NAN));
Expand Down
Loading