Skip to content

Commit 100b904

Browse files
Brian Chenschmidt-sebastian
authored andcommitted
Add IN and ARRAY_CONTAINS_ANY (not publicly exposed) (#519)
1 parent fab9711 commit 100b904

File tree

11 files changed

+510
-36
lines changed

11 files changed

+510
-36
lines changed

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/FirestoreTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,26 +509,34 @@ public void testQueriesAreValidatedOnClient() {
509509
// NOTE: Failure cases are validated in ValidationTest.
510510
CollectionReference collection = testCollection();
511511
final Query query = collection.whereGreaterThanOrEqualTo("x", 32);
512-
// Same inequality field works;
512+
// Same inequality field works.
513513
query.whereLessThanOrEqualTo("x", "cat");
514-
// Equality on different field works;
514+
// Equality on different field works.
515515
query.whereEqualTo("y", "cat");
516-
// Array contains on different field works;
516+
// Array contains on different field works.
517517
query.whereArrayContains("y", "cat");
518+
// Array contains any on different field works.
519+
query.whereArrayContainsAny("y", Arrays.asList("cat"));
520+
// In on different field works.
521+
query.whereIn("y", Arrays.asList("cat"));
518522

519523
// Ordering by inequality field succeeds.
520524
query.orderBy("x");
521525
collection.orderBy("x").whereGreaterThanOrEqualTo("x", 32);
522526

523-
// inequality same as first order by works
527+
// Inequality same as first order by works.
524528
query.orderBy("x").orderBy("y");
525529
collection.orderBy("x").orderBy("y").whereGreaterThanOrEqualTo("x", 32);
526530
collection.orderBy("x", Direction.DESCENDING).whereEqualTo("y", "true");
527531

528-
// Equality different than orderBy works
532+
// Equality different than orderBy works.
529533
collection.orderBy("x").whereEqualTo("y", "cat");
530-
// Array contains different than orderBy works
534+
// Array contains different than orderBy works.
531535
collection.orderBy("x").whereArrayContains("y", "cat");
536+
// Array contains any different than orderBy works.
537+
collection.orderBy("x").whereArrayContainsAny("y", Arrays.asList("cat"));
538+
// In different than orderBy works.
539+
collection.orderBy("x").whereIn("y", Arrays.asList("cat"));
532540
}
533541

534542
@Test

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/QueryTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.Map;
3939
import java.util.concurrent.Semaphore;
4040
import org.junit.After;
41+
import org.junit.Ignore;
4142
import org.junit.Test;
4243
import org.junit.runner.RunWith;
4344

@@ -427,6 +428,55 @@ public void testQueriesCanUseArrayContainsFilters() {
427428
// much of anything else interesting to test.
428429
}
429430

431+
// TODO(in-queries): Re-enable once emulator support is added to travis.
432+
@Test
433+
@Ignore
434+
public void testQueriesCanUseInFilters() {
435+
Map<String, Object> docA = map("zip", 98101);
436+
Map<String, Object> docB = map("zip", 91102);
437+
Map<String, Object> docC = map("zip", 98103);
438+
Map<String, Object> docD = map("zip", asList(98101));
439+
Map<String, Object> docE = map("zip", asList("98101", map("zip", 98101)));
440+
Map<String, Object> docF = map("zip", map("code", 500));
441+
CollectionReference collection =
442+
testCollectionWithDocs(
443+
map("a", docA, "b", docB, "c", docC, "d", docD, "e", docE, "f", docF));
444+
445+
// Search for zips matching [98101, 98103].
446+
QuerySnapshot snapshot = waitFor(collection.whereIn("zip", asList(98101, 98103)).get());
447+
assertEquals(asList(docA, docC), querySnapshotToValues(snapshot));
448+
449+
// With objects.
450+
snapshot = waitFor(collection.whereIn("zip", asList(map("code", 500))).get());
451+
assertEquals(asList(docF), querySnapshotToValues(snapshot));
452+
}
453+
454+
// TODO(in-queries): Re-enable once emulator support is added to travis.
455+
@Test
456+
@Ignore
457+
public void testQueriesCanUseArrayContainsAnyFilters() {
458+
Map<String, Object> docA = map("array", asList(42L));
459+
Map<String, Object> docB = map("array", asList("a", 42L, "c"));
460+
Map<String, Object> docC = map("array", asList(41.999, "42", map("a", asList(42))));
461+
Map<String, Object> docD = map("array", asList(42L), "array2", asList("bingo"));
462+
Map<String, Object> docE = map("array", asList(43L));
463+
Map<String, Object> docF = map("array", asList(map("a", 42L)));
464+
Map<String, Object> docG = map("array", 42L);
465+
466+
CollectionReference collection =
467+
testCollectionWithDocs(
468+
map("a", docA, "b", docB, "c", docC, "d", docD, "e", docE, "f", docF));
469+
470+
// Search for "array" to contain [42, 43].
471+
QuerySnapshot snapshot =
472+
waitFor(collection.whereArrayContainsAny("array", asList(42L, 43L)).get());
473+
assertEquals(asList(docA, docB, docD, docE), querySnapshotToValues(snapshot));
474+
475+
// With objects.
476+
snapshot = waitFor(collection.whereArrayContainsAny("array", asList(map("a", 42L))).get());
477+
assertEquals(asList(docF), querySnapshotToValues(snapshot));
478+
}
479+
430480
@Test
431481
public void testCollectionGroupQueries() {
432482
FirebaseFirestore db = testFirestore();

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/ValidationTest.java

Lines changed: 138 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,12 @@ public void queriesWithNullOrNaNFiltersOtherThanEqualityFail() {
404404
expectError(
405405
() -> collection.whereArrayContains("a", null),
406406
"Invalid Query. You can only perform equality comparisons on null (via whereEqualTo()).");
407+
expectError(
408+
() -> collection.whereArrayContainsAny("a", null),
409+
"Invalid Query. A non-empty array is required for 'array_contains_any' filters.");
410+
expectError(
411+
() -> collection.whereIn("a", null),
412+
"Invalid Query. A non-empty array is required for 'in' filters.");
407413

408414
expectError(
409415
() -> collection.whereGreaterThan("a", Double.NaN),
@@ -535,10 +541,129 @@ public void queriesWithInequalityDifferentThanFirstOrderByFail() {
535541
}
536542

537543
@Test
538-
public void queriesWithMultipleArrayContainsFiltersFail() {
544+
public void queriesWithMultipleArrayFiltersFail() {
539545
expectError(
540546
() -> testCollection().whereArrayContains("foo", 1).whereArrayContains("foo", 2),
541-
"Invalid Query. Queries only support having a single array-contains filter.");
547+
"Invalid Query. You cannot use more than one 'array_contains' filter.");
548+
549+
expectError(
550+
() ->
551+
testCollection()
552+
.whereArrayContains("foo", 1)
553+
.whereArrayContainsAny("foo", asList(1, 2)),
554+
"Invalid Query. You cannot use 'array_contains_any' filters with 'array_contains' filters.");
555+
556+
expectError(
557+
() ->
558+
testCollection()
559+
.whereArrayContainsAny("foo", asList(1, 2))
560+
.whereArrayContains("foo", 1),
561+
"Invalid Query. You cannot use 'array_contains' filters with 'array_contains_any' filters.");
562+
}
563+
564+
@Test
565+
public void queriesWithMultipleDisjunctiveFiltersFail() {
566+
expectError(
567+
() -> testCollection().whereIn("foo", asList(1, 2)).whereIn("bar", asList(1, 2)),
568+
"Invalid Query. You cannot use more than one 'in' filter.");
569+
570+
expectError(
571+
() ->
572+
testCollection()
573+
.whereArrayContainsAny("foo", asList(1, 2))
574+
.whereArrayContainsAny("bar", asList(1, 2)),
575+
"Invalid Query. You cannot use more than one 'array_contains_any' filter.");
576+
577+
expectError(
578+
() ->
579+
testCollection()
580+
.whereArrayContainsAny("foo", asList(1, 2))
581+
.whereIn("bar", asList(1, 2)),
582+
"Invalid Query. You cannot use 'in' filters with 'array_contains_any' filters.");
583+
584+
expectError(
585+
() ->
586+
testCollection()
587+
.whereIn("bar", asList(1, 2))
588+
.whereArrayContainsAny("foo", asList(1, 2)),
589+
"Invalid Query. You cannot use 'array_contains_any' filters with 'in' filters.");
590+
591+
// This is redundant with the above tests, but makes sure our validation doesn't get confused.
592+
expectError(
593+
() ->
594+
testCollection()
595+
.whereIn("bar", asList(1, 2))
596+
.whereArrayContains("foo", 1)
597+
.whereArrayContainsAny("foo", asList(1, 2)),
598+
"Invalid Query. You cannot use 'array_contains_any' filters with 'in' filters.");
599+
600+
expectError(
601+
() ->
602+
testCollection()
603+
.whereArrayContains("foo", 1)
604+
.whereIn("bar", asList(1, 2))
605+
.whereArrayContainsAny("foo", asList(1, 2)),
606+
"Invalid Query. You cannot use 'array_contains_any' filters with 'in' filters.");
607+
}
608+
609+
@Test
610+
public void queriesCanUseInWithArrayContains() {
611+
testCollection().whereArrayContains("foo", 1).whereIn("bar", asList(1, 2));
612+
testCollection().whereIn("bar", asList(1, 2)).whereArrayContains("foo", 1);
613+
614+
expectError(
615+
() ->
616+
testCollection()
617+
.whereIn("bar", asList(1, 2))
618+
.whereArrayContains("foo", 1)
619+
.whereArrayContains("foo", 1),
620+
"Invalid Query. You cannot use more than one 'array_contains' filter.");
621+
622+
expectError(
623+
() ->
624+
testCollection()
625+
.whereArrayContains("foo", 1)
626+
.whereIn("bar", asList(1, 2))
627+
.whereIn("bar", asList(1, 2)),
628+
"Invalid Query. You cannot use more than one 'in' filter.");
629+
}
630+
631+
@Test
632+
public void queriesInAndArrayContainsAnyArrayRules() {
633+
expectError(
634+
() -> testCollection().whereIn("bar", asList()),
635+
"Invalid Query. A non-empty array is required for 'in' filters.");
636+
637+
expectError(
638+
() -> testCollection().whereArrayContainsAny("bar", asList()),
639+
"Invalid Query. A non-empty array is required for 'array_contains_any' filters.");
640+
641+
expectError(
642+
// The 10 element max includes duplicates.
643+
() -> testCollection().whereIn("bar", asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9)),
644+
"Invalid Query. 'in' filters support a maximum of 10 elements in the value array.");
645+
646+
expectError(
647+
// The 10 element max includes duplicates.
648+
() ->
649+
testCollection().whereArrayContainsAny("bar", asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9)),
650+
"Invalid Query. 'array_contains_any' filters support a maximum of 10 elements in the value array.");
651+
652+
expectError(
653+
() -> testCollection().whereIn("bar", asList("foo", null)),
654+
"Invalid Query. 'in' filters cannot contain 'null' in the value array.");
655+
656+
expectError(
657+
() -> testCollection().whereArrayContainsAny("bar", asList("foo", null)),
658+
"Invalid Query. 'array_contains_any' filters cannot contain 'null' in the value array.");
659+
660+
expectError(
661+
() -> testCollection().whereIn("bar", asList("foo", Double.NaN)),
662+
"Invalid Query. 'in' filters cannot contain 'NaN' in the value array.");
663+
664+
expectError(
665+
() -> testCollection().whereArrayContainsAny("bar", asList("foo", Float.NaN)),
666+
"Invalid Query. 'array_contains_any' filters cannot contain 'NaN' in the value array.");
542667
}
543668

544669
@Test
@@ -576,6 +701,11 @@ public void queriesFilteredByDocumentIDMustUseStringsOrDocumentReferences() {
576701
+ "a valid String or DocumentReference, but it was of type: java.lang.Integer";
577702
expectError(() -> collection.whereGreaterThanOrEqualTo(FieldPath.documentId(), 1), reason);
578703

704+
reason =
705+
"Invalid query. When querying with FieldPath.documentId() you must provide "
706+
+ "a valid String or DocumentReference, but it was of type: java.util.Arrays$ArrayList";
707+
expectError(() -> collection.whereIn(FieldPath.documentId(), asList(1, 2)), reason);
708+
579709
reason =
580710
"Invalid query. When querying a collection group by FieldPath.documentId(), the value "
581711
+ "provided must result in a valid document path, but 'foo' is not because it has "
@@ -587,10 +717,13 @@ public void queriesFilteredByDocumentIDMustUseStringsOrDocumentReferences() {
587717
.whereGreaterThanOrEqualTo(FieldPath.documentId(), "foo"),
588718
reason);
589719

590-
reason =
591-
"Invalid query. You can't perform array-contains queries on FieldPath.documentId() since "
592-
+ "document IDs are not arrays.";
720+
reason = "Invalid query. You can't perform 'array_contains' queries on FieldPath.documentId().";
593721
expectError(() -> collection.whereArrayContains(FieldPath.documentId(), 1), reason);
722+
723+
reason =
724+
"Invalid query. You can't perform 'array_contains_any' queries on FieldPath.documentId().";
725+
expectError(
726+
() -> collection.whereArrayContainsAny(FieldPath.documentId(), asList(1, 2)), reason);
594727
}
595728

596729
// Helpers

0 commit comments

Comments
 (0)