diff --git a/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/provider/foundationdb/cursors/KeyComparisons.java b/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/provider/foundationdb/cursors/KeyComparisons.java index 2ef91a7219..9f344c0445 100644 --- a/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/provider/foundationdb/cursors/KeyComparisons.java +++ b/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/provider/foundationdb/cursors/KeyComparisons.java @@ -22,6 +22,7 @@ import com.apple.foundationdb.annotation.API; import com.apple.foundationdb.tuple.ByteArrayUtil; +import com.google.protobuf.ByteString; import java.util.Comparator; import java.util.List; @@ -43,6 +44,8 @@ public class KeyComparisons { return 1; } else if (o1 instanceof byte[]) { return ByteArrayUtil.compareUnsigned((byte[])o1, (byte[])o2); + } else if (o1 instanceof ByteString) { + return ByteString.unsignedLexicographicalComparator().compare((ByteString)o1, (ByteString)o2); } else if (o1 instanceof List) { return KeyComparisons.KEY_COMPARATOR.compare((List)o1, (List)o2); } else { diff --git a/fdb-record-layer-core/src/test/java/com/apple/foundationdb/record/provider/foundationdb/query/FDBOrderingQueryTest.java b/fdb-record-layer-core/src/test/java/com/apple/foundationdb/record/provider/foundationdb/query/FDBOrderingQueryTest.java index 8d64222b0c..103ac9318a 100644 --- a/fdb-record-layer-core/src/test/java/com/apple/foundationdb/record/provider/foundationdb/query/FDBOrderingQueryTest.java +++ b/fdb-record-layer-core/src/test/java/com/apple/foundationdb/record/provider/foundationdb/query/FDBOrderingQueryTest.java @@ -331,6 +331,32 @@ void testUnionOrdered3() throws Exception { } } + /** + * Union legs that tie on {@code num_value_2} have to be compared on the ordered bytes of {@code str_value_indexed}. + */ + @DualPlannerTest + void testUnionOrderedOverlappingRanges() throws Exception { + final RecordMetaDataHook hook = indexHook("order_desc_nulls_last"); + loadRecords(hook); + final RecordQuery query = RecordQuery.newBuilder() + .setRecordType("MySimpleRecord") + .setSort(fullOrderingKey("order_desc_nulls_last")) + .setFilter(Query.or( + Query.and(Query.field("num_value_2").equalsValue(101), + Query.field("str_value_indexed").greaterThanOrEquals("a"), Query.field("str_value_indexed").lessThan("b")), + Query.and(Query.field("num_value_2").equalsValue(101), + Query.field("str_value_indexed").greaterThan("a"), Query.field("str_value_indexed").lessThanOrEquals("b")))) + .build(); + try (FDBRecordContext context = openContext()) { + openSimpleRecordStore(context, hook); + final RecordQueryPlan plan = planner.planQuery(query).getPlan(); + final List actual = plan.execute(recordStore) + .map(r -> r.getPrimaryKey().getLong(0)) + .asList().join(); + assertEquals(List.of(5L, 4L, 3L), actual); + } + } + @DualPlannerTest void testCoveringOrdered() throws Exception { final RecordMetaDataHook hook = indexHook("order_desc_nulls_last");