68
68
import com .google .firestore .v1 .StructuredQuery .CollectionSelector ;
69
69
import com .google .firestore .v1 .StructuredQuery .CompositeFilter ;
70
70
import com .google .firestore .v1 .StructuredQuery .FieldReference ;
71
- import com .google .firestore .v1 .StructuredQuery .Filter .FilterTypeCase ;
72
71
import com .google .firestore .v1 .StructuredQuery .Order ;
73
72
import com .google .firestore .v1 .StructuredQuery .UnaryFilter ;
74
73
import com .google .firestore .v1 .Target ;
@@ -634,54 +633,39 @@ public com.google.firebase.firestore.core.Target decodeQueryTarget(QueryTarget t
634
633
// Filters
635
634
636
635
private StructuredQuery .Filter encodeFilters (List <Filter > filters ) {
637
- List <StructuredQuery .Filter > protos = new ArrayList <>(filters .size ());
638
- for (Filter filter : filters ) {
639
- if (filter instanceof FieldFilter ) {
640
- protos .add (encodeUnaryOrFieldFilter ((FieldFilter ) filter ));
641
- }
642
- }
643
- if (filters .size () == 1 ) {
644
- return protos .get (0 );
645
- } else {
646
- CompositeFilter .Builder composite = CompositeFilter .newBuilder ();
647
- composite .setOp (CompositeFilter .Operator .AND );
648
- composite .addAllFilters (protos );
649
- return StructuredQuery .Filter .newBuilder ().setCompositeFilter (composite ).build ();
650
- }
636
+ // A target's filter list is implicitly a composite AND filter.
637
+ return encodeFilter (
638
+ new com .google .firebase .firestore .core .CompositeFilter (
639
+ filters , CompositeFilter .Operator .AND ));
651
640
}
652
641
653
642
private List <Filter > decodeFilters (StructuredQuery .Filter proto ) {
654
- List <StructuredQuery .Filter > filters ;
655
- if (proto .getFilterTypeCase () == FilterTypeCase .COMPOSITE_FILTER ) {
656
- hardAssert (
657
- proto .getCompositeFilter ().getOp () == CompositeFilter .Operator .AND ,
658
- "Only AND-type composite filters are supported, got %d" ,
659
- proto .getCompositeFilter ().getOp ());
660
- filters = proto .getCompositeFilter ().getFiltersList ();
661
- } else {
662
- filters = Collections .singletonList (proto );
643
+ Filter result = decodeFilter (proto );
644
+
645
+ // Instead of a singletonList containing AND(F1, F2, ...), we can return
646
+ // a list containing F1, F2, ...
647
+ // TODO(orquery): Once proper support for composite filters has been completed, we can remove
648
+ // this flattening from here.
649
+ if (result instanceof com .google .firebase .firestore .core .CompositeFilter ) {
650
+ com .google .firebase .firestore .core .CompositeFilter compositeFilter =
651
+ (com .google .firebase .firestore .core .CompositeFilter ) result ;
652
+ if (compositeFilter .isFlatConjunction ()) {
653
+ return compositeFilter .getFilters ();
654
+ }
663
655
}
664
656
665
- List <Filter > result = new ArrayList <>(filters .size ());
666
- for (StructuredQuery .Filter filter : filters ) {
667
- switch (filter .getFilterTypeCase ()) {
668
- case COMPOSITE_FILTER :
669
- throw fail ("Nested composite filters are not supported." );
670
-
671
- case FIELD_FILTER :
672
- result .add (decodeFieldFilter (filter .getFieldFilter ()));
673
- break ;
674
-
675
- case UNARY_FILTER :
676
- result .add (decodeUnaryFilter (filter .getUnaryFilter ()));
677
- break ;
657
+ return Collections .singletonList (result );
658
+ }
678
659
679
- default :
680
- throw fail ("Unrecognized Filter.filterType %d" , filter .getFilterTypeCase ());
681
- }
660
+ @ VisibleForTesting
661
+ StructuredQuery .Filter encodeFilter (com .google .firebase .firestore .core .Filter filter ) {
662
+ if (filter instanceof FieldFilter ) {
663
+ return encodeUnaryOrFieldFilter ((FieldFilter ) filter );
664
+ } else if (filter instanceof com .google .firebase .firestore .core .CompositeFilter ) {
665
+ return encodeCompositeFilter ((com .google .firebase .firestore .core .CompositeFilter ) filter );
666
+ } else {
667
+ throw fail ("Unrecognized filter type %s" , filter .toString ());
682
668
}
683
-
684
- return result ;
685
669
}
686
670
687
671
@ VisibleForTesting
@@ -711,6 +695,39 @@ StructuredQuery.Filter encodeUnaryOrFieldFilter(FieldFilter filter) {
711
695
return StructuredQuery .Filter .newBuilder ().setFieldFilter (proto ).build ();
712
696
}
713
697
698
+ @ VisibleForTesting
699
+ StructuredQuery .Filter encodeCompositeFilter (
700
+ com .google .firebase .firestore .core .CompositeFilter compositeFilter ) {
701
+ List <StructuredQuery .Filter > protos = new ArrayList <>(compositeFilter .getFilters ().size ());
702
+ for (Filter filter : compositeFilter .getFilters ()) {
703
+ protos .add (encodeFilter (filter ));
704
+ }
705
+
706
+ // If there's only one filter in the composite filter, use it directly.
707
+ if (protos .size () == 1 ) {
708
+ return protos .get (0 );
709
+ }
710
+
711
+ CompositeFilter .Builder composite = CompositeFilter .newBuilder ();
712
+ composite .setOp (compositeFilter .getOperator ());
713
+ composite .addAllFilters (protos );
714
+ return StructuredQuery .Filter .newBuilder ().setCompositeFilter (composite ).build ();
715
+ }
716
+
717
+ @ VisibleForTesting
718
+ Filter decodeFilter (StructuredQuery .Filter proto ) {
719
+ switch (proto .getFilterTypeCase ()) {
720
+ case COMPOSITE_FILTER :
721
+ return decodeCompositeFilter (proto .getCompositeFilter ());
722
+ case FIELD_FILTER :
723
+ return decodeFieldFilter (proto .getFieldFilter ());
724
+ case UNARY_FILTER :
725
+ return decodeUnaryFilter (proto .getUnaryFilter ());
726
+ default :
727
+ throw fail ("Unrecognized Filter.filterType %d" , proto .getFilterTypeCase ());
728
+ }
729
+ }
730
+
714
731
@ VisibleForTesting
715
732
FieldFilter decodeFieldFilter (StructuredQuery .FieldFilter proto ) {
716
733
FieldPath fieldPath = FieldPath .fromServerFormat (proto .getField ().getFieldPath ());
@@ -734,6 +751,16 @@ private Filter decodeUnaryFilter(StructuredQuery.UnaryFilter proto) {
734
751
}
735
752
}
736
753
754
+ @ VisibleForTesting
755
+ com .google .firebase .firestore .core .CompositeFilter decodeCompositeFilter (
756
+ StructuredQuery .CompositeFilter compositeFilter ) {
757
+ List <Filter > filters = new ArrayList <>();
758
+ for (StructuredQuery .Filter filter : compositeFilter .getFiltersList ()) {
759
+ filters .add (decodeFilter (filter ));
760
+ }
761
+ return new com .google .firebase .firestore .core .CompositeFilter (filters , compositeFilter .getOp ());
762
+ }
763
+
737
764
private FieldReference encodeFieldPath (FieldPath field ) {
738
765
return FieldReference .newBuilder ().setFieldPath (field .canonicalString ()).build ();
739
766
}
0 commit comments