32
32
import com .apple .foundationdb .record .provider .foundationdb .FDBRecordVersion ;
33
33
import com .apple .foundationdb .record .query .RecordQuery ;
34
34
import com .apple .foundationdb .record .query .expressions .Query ;
35
+ import com .apple .foundationdb .record .query .expressions .QueryComponent ;
36
+ import com .apple .foundationdb .record .query .plan .RecordQueryPlanner ;
35
37
import com .apple .foundationdb .record .query .plan .plans .RecordQueryPlan ;
36
38
import com .apple .test .Tags ;
37
39
import com .google .common .collect .Collections2 ;
38
40
import com .google .protobuf .Message ;
41
+ import org .hamcrest .Matcher ;
39
42
import org .junit .jupiter .api .Tag ;
40
43
import org .junit .jupiter .api .Test ;
41
44
47
50
import static com .apple .foundationdb .record .TestHelpers .assertDiscardedNone ;
48
51
import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .bounds ;
49
52
import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .coveringIndexScan ;
50
- import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .descendant ;
53
+ import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .fetch ;
54
+ import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .filter ;
51
55
import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .hasTupleString ;
52
56
import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .indexName ;
53
57
import static com .apple .foundationdb .record .query .plan .match .PlanMatchers .indexScan ;
@@ -156,29 +160,39 @@ public void versionRangeCoalesce() throws Exception {
156
160
157
161
/**
158
162
* Verify that the planner removes duplicate filters.
159
- * TODO We currently don't. Update this test when it gets implemented.
160
- * TODO: Some query plans include redundant filtering operations even when the index is a complete specification (https://github.com/FoundationDB/fdb-record-layer/issues/2)
161
163
*/
162
- @ Test
164
+ @ DualPlannerTest
163
165
public void duplicateFilters () throws Exception {
164
166
RecordMetaDataHook hook = metaData -> {
165
167
metaData .addIndex ("MySimpleRecord" , new Index ("multi_index" , "str_value_indexed" , "num_value_3_indexed" ));
166
168
};
167
169
complexQuerySetup (hook );
170
+ QueryComponent filter = Query .field ("num_value_3_indexed" ).equalsValue (3 );
168
171
RecordQuery query = RecordQuery .newBuilder ()
169
172
.setRecordType ("MySimpleRecord" )
170
173
.setFilter (Query .and (
171
174
Query .field ("str_value_indexed" ).equalsValue ("even" ),
172
- Query . field ( "num_value_3_indexed" ). equalsValue ( 3 ) ,
173
- Query . field ( "num_value_3_indexed" ). equalsValue ( 3 ) ))
175
+ filter ,
176
+ filter ))
174
177
.build ();
175
178
176
- // Fetch(Covering(Index(multi_index [[even, 3],[even, 3]]) -> [num_value_3_indexed: KEY[1], rec_no: KEY[2], str_value_indexed: KEY[0]]) | num_value_3_indexed EQUALS 3)
177
179
RecordQueryPlan plan = planner .plan (query );
178
- assertThat (plan , descendant (coveringIndexScan (indexScan (allOf (indexName ("multi_index" ), bounds (hasTupleString ("[[even, 3],[even, 3]]" )))))));
179
- assertEquals (-766201402 , plan .planHash (PlanHashable .PlanHashKind .LEGACY ));
180
- assertEquals (-1632715349 , plan .planHash (PlanHashable .PlanHashKind .FOR_CONTINUATION ));
181
- assertEquals (-1418679945 , plan .planHash (PlanHashable .PlanHashKind .STRUCTURAL_WITHOUT_LITERALS ));
180
+ // Index(multi_index [[even, 3],[even, 3]]) -> [num_value_3_indexed: KEY[1], rec_no: KEY[2], str_value_indexed: KEY[0]])
181
+ final Matcher <RecordQueryPlan > matcher = indexScan (allOf (indexName ("multi_index" ), bounds (hasTupleString ("[[even, 3],[even, 3]]" ))));
182
+ if (planner instanceof RecordQueryPlanner ) {
183
+ // TODO: Update this test when it gets implemented for old planner.
184
+ // Some query plans include redundant filtering operations even when the index is a complete specification (https://github.com/FoundationDB/fdb-record-layer/issues/2)
185
+ // Fetch(Covering(...) | num_value_3_indexed EQUALS 3)
186
+ assertThat (plan , fetch (filter (filter , coveringIndexScan (matcher ))));
187
+ assertEquals (-766201402 , plan .planHash (PlanHashable .PlanHashKind .LEGACY ));
188
+ assertEquals (-1632715349 , plan .planHash (PlanHashable .PlanHashKind .FOR_CONTINUATION ));
189
+ assertEquals (-1418679945 , plan .planHash (PlanHashable .PlanHashKind .STRUCTURAL_WITHOUT_LITERALS ));
190
+ } else {
191
+ assertThat (plan , matcher );
192
+ assertEquals (681699231 , plan .planHash (PlanHashable .PlanHashKind .LEGACY ));
193
+ assertEquals (-1692140528 , plan .planHash (PlanHashable .PlanHashKind .FOR_CONTINUATION ));
194
+ assertEquals (463756249 , plan .planHash (PlanHashable .PlanHashKind .STRUCTURAL_WITHOUT_LITERALS ));
195
+ }
182
196
183
197
try (FDBRecordContext context = openContext ()) {
184
198
openSimpleRecordStore (context , hook );
@@ -203,7 +217,7 @@ public void duplicateFilters() throws Exception {
203
217
* TODO The planner does not currently coalesce the overlapping filters (>= 3 and > 0).
204
218
* TODO: Planner does not currently coalesce overlapping filters (https://github.com/FoundationDB/fdb-record-layer/issues/1)
205
219
*/
206
- @ Test
220
+ @ DualPlannerTest
207
221
public void overlappingFilters () throws Exception {
208
222
RecordMetaDataHook hook = metaData -> {
209
223
metaData .addIndex ("MySimpleRecord" , new Index ("multi_index" , "str_value_indexed" , "num_value_3_indexed" ));
0 commit comments