|
17 | 17 | import static com.google.firebase.firestore.local.IndexManager.*;
|
18 | 18 | import static com.google.firebase.firestore.model.FieldIndex.*;
|
19 | 19 | import static com.google.firebase.firestore.model.FieldIndex.Segment.*;
|
| 20 | +import static com.google.firebase.firestore.testutil.TestUtil.andFilters; |
20 | 21 | import static com.google.firebase.firestore.testutil.TestUtil.doc;
|
21 | 22 | import static com.google.firebase.firestore.testutil.TestUtil.docMap;
|
22 | 23 | import static com.google.firebase.firestore.testutil.TestUtil.docSet;
|
23 | 24 | import static com.google.firebase.firestore.testutil.TestUtil.fieldIndex;
|
24 | 25 | import static com.google.firebase.firestore.testutil.TestUtil.filter;
|
25 | 26 | import static com.google.firebase.firestore.testutil.TestUtil.map;
|
| 27 | +import static com.google.firebase.firestore.testutil.TestUtil.orFilters; |
26 | 28 | import static com.google.firebase.firestore.testutil.TestUtil.orderBy;
|
27 | 29 | import static com.google.firebase.firestore.testutil.TestUtil.patchMutation;
|
28 | 30 | import static com.google.firebase.firestore.testutil.TestUtil.query;
|
@@ -108,4 +110,98 @@ public void testRefillsIndexedLimitQueries() throws Exception {
|
108 | 110 | DocumentSet result = expectOptimizedCollectionScan(() -> runQuery(query, SnapshotVersion.NONE));
|
109 | 111 | assertEquals(docSet(query.comparator(), doc1, doc2, doc4), result);
|
110 | 112 | }
|
| 113 | + |
| 114 | + @Test |
| 115 | + public void canPerformOrQueriesUsingIndexes() throws Exception { |
| 116 | + MutableDocument doc1 = doc("coll/1", 1, map("a", 1, "b", 0)); |
| 117 | + MutableDocument doc2 = doc("coll/2", 1, map("a", 2, "b", 1)); |
| 118 | + MutableDocument doc3 = doc("coll/3", 1, map("a", 3, "b", 2)); |
| 119 | + MutableDocument doc4 = doc("coll/4", 1, map("a", 1, "b", 3)); |
| 120 | + MutableDocument doc5 = doc("coll/5", 1, map("a", 1, "b", 1)); |
| 121 | + addDocument(doc1, doc2, doc3, doc4, doc5); |
| 122 | + indexManager.addFieldIndex(fieldIndex("coll", "a", Kind.ASCENDING)); |
| 123 | + indexManager.addFieldIndex(fieldIndex("coll", "a", Kind.DESCENDING)); |
| 124 | + indexManager.addFieldIndex(fieldIndex("coll", "b", Kind.ASCENDING)); |
| 125 | + indexManager.addFieldIndex(fieldIndex("coll", "b", Kind.DESCENDING)); |
| 126 | + indexManager.updateIndexEntries(docMap(doc1, doc2, doc3, doc4, doc5)); |
| 127 | + indexManager.updateCollectionGroup("coll", IndexOffset.fromDocument(doc5)); |
| 128 | + |
| 129 | + // Two equalities: a==1 || b==1. |
| 130 | + Query query1 = query("coll").filter(orFilters(filter("a", "==", 1), filter("b", "==", 1))); |
| 131 | + DocumentSet result1 = |
| 132 | + expectOptimizedCollectionScan(() -> runQuery(query1, SnapshotVersion.NONE)); |
| 133 | + assertEquals(docSet(query1.comparator(), doc1, doc2, doc4, doc5), result1); |
| 134 | + |
| 135 | + // with one inequality: a>2 || b==1. |
| 136 | + Query query2 = query("coll").filter(orFilters(filter("a", ">", 2), filter("b", "==", 1))); |
| 137 | + DocumentSet result2 = |
| 138 | + expectOptimizedCollectionScan(() -> runQuery(query2, SnapshotVersion.NONE)); |
| 139 | + assertEquals(docSet(query2.comparator(), doc2, doc3, doc5), result2); |
| 140 | + |
| 141 | + // (a==1 && b==0) || (a==3 && b==2) |
| 142 | + Query query3 = |
| 143 | + query("coll") |
| 144 | + .filter( |
| 145 | + orFilters( |
| 146 | + andFilters(filter("a", "==", 1), filter("b", "==", 0)), |
| 147 | + andFilters(filter("a", "==", 3), filter("b", "==", 2)))); |
| 148 | + DocumentSet result3 = |
| 149 | + expectOptimizedCollectionScan(() -> runQuery(query3, SnapshotVersion.NONE)); |
| 150 | + assertEquals(docSet(query3.comparator(), doc1, doc3), result3); |
| 151 | + |
| 152 | + // a==1 && (b==0 || b==3). |
| 153 | + Query query4 = |
| 154 | + query("coll") |
| 155 | + .filter( |
| 156 | + andFilters( |
| 157 | + filter("a", "==", 1), orFilters(filter("b", "==", 0), filter("b", "==", 3)))); |
| 158 | + DocumentSet result4 = |
| 159 | + expectOptimizedCollectionScan(() -> runQuery(query4, SnapshotVersion.NONE)); |
| 160 | + assertEquals(docSet(query4.comparator(), doc1, doc4), result4); |
| 161 | + |
| 162 | + // (a==2 || b==2) && (a==3 || b==3) |
| 163 | + Query query5 = |
| 164 | + query("coll") |
| 165 | + .filter( |
| 166 | + andFilters( |
| 167 | + orFilters(filter("a", "==", 2), filter("b", "==", 2)), |
| 168 | + orFilters(filter("a", "==", 3), filter("b", "==", 3)))); |
| 169 | + DocumentSet result5 = |
| 170 | + expectOptimizedCollectionScan(() -> runQuery(query5, SnapshotVersion.NONE)); |
| 171 | + assertEquals(docSet(query5.comparator(), doc3), result5); |
| 172 | + |
| 173 | + // Test with limits (implicit order by ASC): (a==1) || (b > 0) LIMIT 2 |
| 174 | + Query query6 = |
| 175 | + query("coll").filter(orFilters(filter("a", "==", 1), filter("b", ">", 0))).limitToFirst(2); |
| 176 | + DocumentSet result6 = |
| 177 | + expectOptimizedCollectionScan(() -> runQuery(query6, SnapshotVersion.NONE)); |
| 178 | + assertEquals(docSet(query6.comparator(), doc1, doc2), result6); |
| 179 | + |
| 180 | + // Test with limits (implicit order by DESC): (a==1) || (b > 0) LIMIT_TO_LAST 2 |
| 181 | + Query query7 = |
| 182 | + query("coll").filter(orFilters(filter("a", "==", 1), filter("b", ">", 0))).limitToLast(2); |
| 183 | + DocumentSet result7 = |
| 184 | + expectOptimizedCollectionScan(() -> runQuery(query7, SnapshotVersion.NONE)); |
| 185 | + assertEquals(docSet(query7.comparator(), doc3, doc4), result7); |
| 186 | + |
| 187 | + // Test with limits (explicit order by ASC): (a==2) || (b == 1) ORDER BY a LIMIT 1 |
| 188 | + Query query8 = |
| 189 | + query("coll") |
| 190 | + .filter(orFilters(filter("a", "==", 2), filter("b", "==", 1))) |
| 191 | + .limitToFirst(1) |
| 192 | + .orderBy(orderBy("a", "asc")); |
| 193 | + DocumentSet result8 = |
| 194 | + expectOptimizedCollectionScan(() -> runQuery(query8, SnapshotVersion.NONE)); |
| 195 | + assertEquals(docSet(query8.comparator(), doc5), result8); |
| 196 | + |
| 197 | + // Test with limits (explicit order by DESC): (a==2) || (b == 1) ORDER BY a LIMIT_TO_LAST 1 |
| 198 | + Query query9 = |
| 199 | + query("coll") |
| 200 | + .filter(orFilters(filter("a", "==", 2), filter("b", "==", 1))) |
| 201 | + .limitToLast(1) |
| 202 | + .orderBy(orderBy("a", "asc")); |
| 203 | + DocumentSet result9 = |
| 204 | + expectOptimizedCollectionScan(() -> runQuery(query9, SnapshotVersion.NONE)); |
| 205 | + assertEquals(docSet(query9.comparator(), doc2), result9); |
| 206 | + } |
111 | 207 | }
|
0 commit comments