|
25 | 25 | import com.apple.foundationdb.record.RecordMetaDataBuilder; |
26 | 26 | import com.apple.foundationdb.record.TestRecordsNulls2Proto; |
27 | 27 | import com.apple.foundationdb.record.TestRecordsNulls3Proto; |
| 28 | +import com.apple.foundationdb.record.TestRecordsNulls3ExplicitProto; |
28 | 29 | import com.apple.foundationdb.record.TestRecordsTupleFieldsProto; |
29 | 30 | import com.apple.foundationdb.record.TupleFieldsProto; |
30 | 31 | import com.apple.foundationdb.record.metadata.Key; |
@@ -108,6 +109,10 @@ protected static RecordMetaData proto3NestedMetaData() { |
108 | 109 | return metaData.getRecordMetaData(); |
109 | 110 | } |
110 | 111 |
|
| 112 | + protected static RecordMetaData proto3ExplicitMetaData() { |
| 113 | + return RecordMetaData.newBuilder().setRecords(TestRecordsNulls3ExplicitProto.getDescriptor()).getRecordMetaData(); |
| 114 | + } |
| 115 | + |
111 | 116 | @FunctionalInterface |
112 | 117 | interface RecordBuilder<M extends Message> { |
113 | 118 | M build(@Nonnull String name, @Nullable Integer intValue, @Nullable String stringValue); |
@@ -175,6 +180,18 @@ protected static DynamicMessage buildRecord3Dynamic(@Nonnull String name, @Nulla |
175 | 180 | return builder.build(); |
176 | 181 | } |
177 | 182 |
|
| 183 | + protected static TestRecordsNulls3ExplicitProto.MyNullRecord buildRecord3Explicit(@Nonnull String name, @Nullable Integer intValue, @Nullable String stringValue) { |
| 184 | + TestRecordsNulls3ExplicitProto.MyNullRecord.Builder builder = TestRecordsNulls3ExplicitProto.MyNullRecord.newBuilder(); |
| 185 | + builder.setName(name); |
| 186 | + if (intValue != null) { |
| 187 | + builder.setIntValue(intValue); |
| 188 | + } |
| 189 | + if (stringValue != null) { |
| 190 | + builder.setStringValue(stringValue); |
| 191 | + } |
| 192 | + return builder.build(); |
| 193 | + } |
| 194 | + |
178 | 195 | protected <M extends Message> void saveTestRecords(@Nonnull RecordBuilder<M> builder) { |
179 | 196 | recordStore.saveRecord(builder.build("empty", null, null)); |
180 | 197 | recordStore.saveRecord(builder.build("default", 0, "")); |
@@ -365,6 +382,53 @@ public void testProto3Nested() { |
365 | 382 | } |
366 | 383 | } |
367 | 384 |
|
| 385 | + // Explicit presence ("optional") correctly distguishes as well (results same as proto2). |
| 386 | + @Test |
| 387 | + public void testProto3Explicit() { |
| 388 | + try (FDBRecordContext context = openContext()) { |
| 389 | + createOrOpenRecordStore(context, proto3ExplicitMetaData()); |
| 390 | + saveTestRecords(FDBRecordStoreNullQueryTest::buildRecord3Explicit); |
| 391 | + |
| 392 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 393 | + .setRecordType("MyNullRecord") |
| 394 | + .setFilter(Query.field("int_value").equalsValue(2)) |
| 395 | + .build()), |
| 396 | + is(Collections.singletonList("two"))); |
| 397 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 398 | + .setRecordType("MyNullRecord") |
| 399 | + .setFilter(Query.field("string_value").equalsValue("B")) |
| 400 | + .build()), |
| 401 | + is(Collections.singletonList("two"))); |
| 402 | + |
| 403 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 404 | + .setRecordType("MyNullRecord") |
| 405 | + .setFilter(Query.field("int_value").isNull()) |
| 406 | + .build()), |
| 407 | + is(Collections.singletonList("empty"))); |
| 408 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 409 | + .setRecordType("MyNullRecord") |
| 410 | + .setFilter(Query.field("int_value").equalsValue(0)) |
| 411 | + .build()), |
| 412 | + is(Collections.singletonList("default"))); |
| 413 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 414 | + .setRecordType("MyNullRecord") |
| 415 | + .setFilter(Query.field("string_value").isNull()) |
| 416 | + .build()), |
| 417 | + is(Collections.singletonList("empty"))); |
| 418 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 419 | + .setRecordType("MyNullRecord") |
| 420 | + .setFilter(Query.field("string_value").equalsValue("")) |
| 421 | + .build()), |
| 422 | + is(Collections.singletonList("default"))); |
| 423 | + |
| 424 | + assertThat(executeQuery(RecordQuery.newBuilder() |
| 425 | + .setRecordType("MyNullRecord") |
| 426 | + .setSort(Key.Expressions.field("int_value")) |
| 427 | + .build()), |
| 428 | + is(Arrays.asList("empty", "minus", "default", "one", "two"))); |
| 429 | + } |
| 430 | + } |
| 431 | + |
368 | 432 | @Test |
369 | 433 | public void testCompareSerialization() throws Exception { |
370 | 434 | final TestRecordsNulls2Proto.MyNullRecord emptyProto2 = buildRecord2("record", null, null); |
|
0 commit comments