use of com.apple.foundationdb.record.metadata.Key in project fdb-record-layer by FoundationDB.
the class FDBOrQueryToUnionTest method testOrQuery6.
/**
* Verify that a complex query with an OR of an AND produces a union plan if appropriate indexes are defined.
* In particular, verify that it can use the last field of an index and does not require primary key ordering
* compatibility.
*/
@DualPlannerTest
void testOrQuery6() throws Exception {
RecordMetaDataHook hook = metaData -> metaData.addIndex("MySimpleRecord", new Index("str_value_3_index", "str_value_indexed", "num_value_3_indexed"));
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.or(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").greaterThan(3)), Query.field("num_value_3_indexed").lessThan(1))).build();
// Index(str_value_3_index ([even, 3],[even]]) ∪[Field { 'num_value_3_indexed' None}, Field { 'rec_no' None}] Index(MySimpleRecord$num_value_3_indexed ([null],[1]))
RecordQueryPlan plan = planner.plan(query);
if (planner instanceof CascadesPlanner) {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = fetchFromPartialRecordPlan(unionPlan(coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]"))))), coveringIndexPlan().where(indexPlanOf(indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([null],[1])")))))).where(comparisonKey(concat(Key.Expressions.field("num_value_3_indexed"), primaryKey("MySimpleRecord")))));
assertMatchesExactly(plan, planMatcher);
assertEquals(-835124758, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(778876973, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1061354639, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
} else {
final BindingMatcher<? extends RecordQueryPlan> planMatcher = unionPlan(indexPlan().where(indexName("str_value_3_index")).and(scanComparisons(range("([even, 3],[even]]"))), indexPlan().where(indexName("MySimpleRecord$num_value_3_indexed")).and(scanComparisons(range("([null],[1])")))).where(comparisonKey(concat(Key.Expressions.field("num_value_3_indexed"), primaryKey("MySimpleRecord"))));
assertMatchesExactly(plan, planMatcher);
assertEquals(1721396731, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1374663850, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1092186184, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(Objects.requireNonNull(rec).getRecord());
assertTrue((myrec.getStrValueIndexed().equals("even") && myrec.getNumValue3Indexed() > 3) || myrec.getNumValue3Indexed() < 1);
i++;
}
}
assertEquals(20 + 10, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.metadata.Key in project fdb-record-layer by FoundationDB.
the class OnlineIndexerSimpleTest method testOnlineIndexerBuilderWriteLimitBytes.
@Test
public void testOnlineIndexerBuilderWriteLimitBytes() throws Exception {
List<TestRecords1Proto.MySimpleRecord> records = LongStream.range(0, 200).mapToObj(val -> TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(val).setNumValue2((int) val + 1).build()).collect(Collectors.toList());
Index index = new Index("newIndex", field("num_value_2").ungrouped(), IndexTypes.SUM);
IndexAggregateFunction aggregateFunction = new IndexAggregateFunction(FunctionNames.SUM, index.getRootExpression(), index.getName());
List<String> indexTypes = Collections.singletonList("MySimpleRecord");
FDBRecordStoreTestBase.RecordMetaDataHook hook = metaDataBuilder -> metaDataBuilder.addIndex("MySimpleRecord", index);
openSimpleMetaData();
try (FDBRecordContext context = openContext()) {
records.forEach(recordStore::saveRecord);
context.commit();
}
openSimpleMetaData(hook);
final FDBStoreTimer timer = new FDBStoreTimer();
try (FDBRecordContext context = openContext()) {
recordStore.checkVersion(null, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS).join();
// Build in this transaction.
try (OnlineIndexer indexer = OnlineIndexer.newBuilder().setRecordStore(recordStore).setTimer(timer).setIndex("newIndex").setLimit(100000).setMaxWriteLimitBytes(1).build()) {
// this call will "flatten" the staccato iterations to a whole range. Testing compatibility.
indexer.rebuildIndex(recordStore);
}
recordStore.markIndexReadable("newIndex").join();
assertEquals(200, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RECORDS_SCANNED));
assertEquals(200, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RECORDS_INDEXED));
assertEquals(199, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_SIZE));
// last item
assertEquals(1, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_COUNT));
context.commit();
}
try (FDBRecordContext context = openContext()) {
assertTrue(recordStore.isIndexReadable("newIndex"));
recordStore.clearAndMarkIndexWriteOnly("newIndex").join();
context.commit();
}
timer.reset();
try (FDBRecordContext context = openContext()) {
recordStore.checkVersion(null, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS).join();
// Build in this transaction.
try (OnlineIndexer indexer = OnlineIndexer.newBuilder().setRecordStore(recordStore).setTimer(timer).setIndex("newIndex").setLimit(100000).setMaxWriteLimitBytes(1).build()) {
Key.Evaluated key = indexer.buildUnbuiltRange(Key.Evaluated.scalar(0L), Key.Evaluated.scalar(25L)).join();
assertEquals(1, key.getLong(0));
assertEquals(1, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_SIZE));
assertEquals(0, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_COUNT));
}
recordStore.clearAndMarkIndexWriteOnly("newIndex").join();
context.commit();
}
timer.reset();
try (OnlineIndexer indexer = OnlineIndexer.newBuilder().setDatabase(fdb).setMetaData(metaData).setSubspace(subspace).setTimer(timer).setIndex(index).setLimit(100000).setMaxWriteLimitBytes(1).setRecordsPerSecond(OnlineIndexer.UNLIMITED).build()) {
indexer.buildIndex();
}
assertEquals(200, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RECORDS_SCANNED));
assertEquals(200, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RECORDS_INDEXED));
// this includes two endpoints + one range = total of 3 terminations by count
// - note that (last, null] endpoint is en empty range
assertEquals(3, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_COUNT));
// this is the range between the endpoints - 199 items in (first, last] interval
assertEquals(198, timer.getCount(FDBStoreTimer.Counts.ONLINE_INDEX_BUILDER_RANGES_BY_SIZE));
}
use of com.apple.foundationdb.record.metadata.Key in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByRecordId.
@Test
public void testQueryByRecordId() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by leading portion of primary key that is not hidden behind the function
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.field("rec_id").equalsValue("/s:foo_3_blah")).build();
RecordQueryPlan plan = planner.plan(query);
Assertions.assertEquals("Scan(<,>) | rec_id EQUALS /s:foo_3_blah", plan.toString());
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertEquals("/s:foo_3_blah", record.getRecId());
count.incrementAndGet();
}).get();
Assertions.assertEquals(1, count.get(), "Too few records returned");
}
}
}
use of com.apple.foundationdb.record.metadata.Key in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByLeadingPortionOfKey.
@Test
public void testQueryByLeadingPortionOfKey() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by leading portion of primary key that is not hidden behind the function
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.and(Query.field("int_value").greaterThanOrEquals(1), Query.field("int_value").lessThanOrEquals(2))).build();
RecordQueryPlan plan = planner.plan(query);
Assertions.assertEquals("Scan([[1],[2]])", plan.toString());
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertTrue(record.getLongField() % 3 == 1 || record.getLongField() % 3 == 2);
count.incrementAndGet();
}).get();
Assertions.assertEquals(6, count.get(), "Too few records returned");
}
}
}
use of com.apple.foundationdb.record.metadata.Key in project fdb-record-layer by FoundationDB.
the class FunctionKeyRecordTest method testQueryByNonKeyField.
@Test
public void testQueryByNonKeyField() throws Exception {
RecordMetaDataHook hook = setupQueryData();
// Query by non-primary key field and make sure that works.
RecordQuery query = RecordQuery.newBuilder().setRecordType("StringRecordId").setFilter(Query.or(Query.field("str_field").equalsValue("hello_0"), Query.field("str_field").equalsValue("hello_3"), Query.field("str_field").equalsValue("hello_6"))).build();
RecordQueryPlan plan = planner.plan(query);
try (FDBRecordContext context = openContext()) {
openRecordStore(context, hook);
try (RecordCursor<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan)) {
AtomicInteger count = new AtomicInteger();
cursor.forEach(queriedRecord -> {
TestRecords8Proto.StringRecordId record = validateQueryData(queriedRecord);
Assertions.assertTrue(record.getIntValue() >= 0 && record.getIntValue() <= 2, "Unexpected record returned");
count.incrementAndGet();
}).get();
Assertions.assertEquals(3, count.get(), "Too few records returned");
}
}
}
Aggregations