Skip to content

Commit c701438

Browse files
committed
noticket: FIX: UuidFieldValue.getRaw() should return the underlying java.util.UUID
...and **not** the UUID's `java.lang.String` representation, which is used for proper sort order (`UuidFieldValue.getComparableByType()`).
1 parent 6a0593f commit c701438

File tree

10 files changed

+70
-4
lines changed

10 files changed

+70
-4
lines changed

databind/src/main/java/tech/ydb/yoj/databind/expression/values/BooleanFieldValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package tech.ydb.yoj.databind.expression.values;
22

3+
import lombok.NonNull;
34
import tech.ydb.yoj.databind.FieldValueType;
45
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.BooleanFieldExpected;
56

@@ -27,6 +28,7 @@ public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueT
2728
: invalidFieldValue(BooleanFieldExpected::new, p -> format("Specified a boolean value for non-boolean field \"%s\"", p));
2829
}
2930

31+
@NonNull
3032
@Override
3133
public String toString() {
3234
return Boolean.toString(bool);

databind/src/main/java/tech/ydb/yoj/databind/expression/values/ByteArrayFieldValue.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueT
3030
: invalidFieldValue(ByteArrayFieldExpected::new, p -> format("Specified a ByteArray value for non-ByteArray field \"%s\"", p));
3131
}
3232

33+
@NonNull
3334
@Override
3435
public String toString() {
3536
return byteArray.toString();

databind/src/main/java/tech/ydb/yoj/databind/expression/values/FieldValue.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ public sealed interface FieldValue extends tech.ydb.yoj.databind.expression.Fiel
3232

3333
ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueType);
3434

35+
/**
36+
* Provides a human-readable representation of this {@code FieldValue}, potentially indicating
37+
* this value's type (e.g., value will be in {@code "double quotes"} for {@code StringFieldValue}).
38+
*
39+
* @return human-readable representation of field value
40+
*/
41+
@NonNull
42+
@Override
43+
String toString();
44+
3545
@Override
3646
default Object getRaw(@NonNull JavaField field) {
3747
field = field.isFlat() ? field.toFlatField() : field;

databind/src/main/java/tech/ydb/yoj/databind/expression/values/IntegerFieldValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package tech.ydb.yoj.databind.expression.values;
22

3+
import lombok.NonNull;
34
import tech.ydb.yoj.databind.FieldValueType;
45
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.IntegerBadTimestamp;
56
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.IntegerFieldExpected;
@@ -34,6 +35,7 @@ public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueT
3435
};
3536
}
3637

38+
@NonNull
3739
@Override
3840
public String toString() {
3941
return Long.toString(num);

databind/src/main/java/tech/ydb/yoj/databind/expression/values/RealFieldValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package tech.ydb.yoj.databind.expression.values;
22

3+
import lombok.NonNull;
34
import tech.ydb.yoj.databind.FieldValueType;
45
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.IntegerToRealInexact;
56
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.RealFieldExpected;
@@ -37,6 +38,7 @@ public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueT
3738
};
3839
}
3940

41+
@NonNull
4042
@Override
4143
public String toString() {
4244
return Double.toString(real);

databind/src/main/java/tech/ydb/yoj/databind/expression/values/StringFieldValue.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ private static boolean enumHasConstant(@NonNull Class<?> enumClass, @NonNull Str
6868
return stream(enumClass.getEnumConstants()).anyMatch(c -> enumConstant.equals(((Enum<?>) c).name()));
6969
}
7070

71+
@NonNull
7172
@Override
7273
public String toString() {
7374
return "\"" + str + "\"";

databind/src/main/java/tech/ydb/yoj/databind/expression/values/TimestampFieldValue.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ private boolean isValidInteger() {
4343
}
4444
}
4545

46+
@NonNull
4647
@Override
4748
public String toString() {
4849
return "#" + timestamp + "#";

databind/src/main/java/tech/ydb/yoj/databind/expression/values/TupleFieldValue.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueT
5757
.orElse(ValidationResult.validFieldValue());
5858
}
5959

60+
@NonNull
6061
@Override
6162
public String toString() {
6263
return tuple.toString();

databind/src/main/java/tech/ydb/yoj/databind/expression/values/UuidFieldValue.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import lombok.NonNull;
44
import tech.ydb.yoj.databind.FieldValueType;
55
import tech.ydb.yoj.databind.expression.IllegalExpressionException.FieldTypeError.UuidFieldExpected;
6+
import tech.ydb.yoj.databind.schema.Schema;
67

78
import java.lang.reflect.Type;
89
import java.util.Optional;
@@ -21,15 +22,26 @@ public Optional<Comparable<?>> getComparableByType(Type fieldType, FieldValueTyp
2122
};
2223
}
2324

25+
@Override
26+
public Object getRaw(@NonNull Schema.JavaField field) {
27+
field = field.isFlat() ? field.toFlatField() : field;
28+
if (field.getValueType() == FieldValueType.UUID) {
29+
return uuid;
30+
}
31+
32+
return FieldValue.super.getRaw(field);
33+
}
34+
2435
@Override
2536
public ValidationResult isValidValueOfType(Type fieldType, FieldValueType valueType) {
2637
return valueType == FieldValueType.UUID || valueType == FieldValueType.STRING
2738
? validFieldValue() // All UUIDs are representable as both UUID and String
2839
: invalidFieldValue(UuidFieldExpected::new, p -> format("Specified an UUID value for non-UUID/non-String field \"%s\"", p));
2940
}
3041

42+
@NonNull
3143
@Override
3244
public String toString() {
33-
return uuid.toString();
45+
return "{" + uuid + "}";
3446
}
3547
}

repository-test/src/main/java/tech/ydb/yoj/repository/test/ListingTest.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import tech.ydb.yoj.repository.test.sample.model.Project;
2020
import tech.ydb.yoj.repository.test.sample.model.TypeFreak;
2121
import tech.ydb.yoj.repository.test.sample.model.TypeFreak.Status;
22+
import tech.ydb.yoj.repository.test.sample.model.annotations.UniqueEntityNative;
2223

2324
import java.time.Instant;
25+
import java.util.UUID;
2426

2527
import static java.time.temporal.ChronoUnit.MILLIS;
2628
import static java.util.Collections.emptyList;
@@ -127,6 +129,38 @@ public void complexIdFullScan() {
127129
});
128130
}
129131

132+
@Test
133+
public void uuid() {
134+
UUID uuid1 = UUID.fromString("5bedcf4a-d2fb-4ff1-817f-98589adff554");
135+
UUID uuid2 = UUID.fromString("5bedcf4a-d2fb-4ff1-817f-98589adff555");
136+
UUID uuid3 = UUID.fromString("5bedcf4a-d2fb-4ff1-817f-98589adff556");
137+
UUID uuid4 = UUID.fromString("5bedcf4a-d2fb-4ff1-817f-98589adff557");
138+
139+
UniqueEntityNative c1 = new UniqueEntityNative(new UniqueEntityNative.Id(uuid1), "c1");
140+
UniqueEntityNative c2 = new UniqueEntityNative(new UniqueEntityNative.Id(uuid2), "c2");
141+
UniqueEntityNative c3 = new UniqueEntityNative(new UniqueEntityNative.Id(uuid3), "c3");
142+
UniqueEntityNative c4 = new UniqueEntityNative(new UniqueEntityNative.Id(uuid4), "c4");
143+
db.tx(() -> db.table(UniqueEntityNative.class).insert(c1, c2, c3, c4));
144+
145+
db.tx(() -> {
146+
ListResult<UniqueEntityNative> page1 = db.table(UniqueEntityNative.class).list(
147+
ListRequest.builder(UniqueEntityNative.class)
148+
.pageSize(3)
149+
.build()
150+
);
151+
assertThat(page1).containsExactly(c1, c2, c3);
152+
153+
ListResult<UniqueEntityNative> page2 = db.table(UniqueEntityNative.class).list(
154+
ListRequest.builder(UniqueEntityNative.class)
155+
.pageSize(3)
156+
.filter(fb -> fb.where("id").gt(c3.id()))
157+
.build()
158+
);
159+
assertThat(page2).containsExactly(c4);
160+
assertThat(page2.isLastPage()).isTrue();
161+
});
162+
}
163+
130164
@Test
131165
public void failOnZeroPageSize() {
132166
db.tx(() -> {
@@ -285,7 +319,7 @@ public void complexIdIn() {
285319
ListResult<Complex> page = listComplex(ListRequest.builder(Complex.class)
286320
.pageSize(100)
287321
.filter(fb -> fb
288-
.where("id.a").in(999_999,999_000)
322+
.where("id.a").in(999_999, 999_000)
289323
.and("id.b").in(15L, 13L)
290324
.and("id.c").in("AAA", "CCC")
291325
.and("id.d").in(Complex.Status.OK, Complex.Status.FAIL)
@@ -311,7 +345,7 @@ public void complexUnixTimestampRelational() {
311345
db.tx(() -> {
312346
ListResult<Complex> page = listComplex(ListRequest.builder(Complex.class)
313347
.pageSize(100)
314-
.filter(fb -> fb.where("id.a").in(999_999,999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
348+
.filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").gte(now).and("id.b").lt(nowPlus2))
315349
.orderBy(ob -> ob.orderBy("id.a").descending())
316350
.build());
317351
Assertions.assertThat(page).containsExactlyInAnyOrder(c1, c2);
@@ -333,7 +367,7 @@ public void complexUnixTimestampIn() {
333367
db.tx(() -> {
334368
ListResult<Complex> page = listComplex(ListRequest.builder(Complex.class)
335369
.pageSize(100)
336-
.filter(fb -> fb.where("id.a").in(999_999,999_000).and("id.b").in(now, nowPlus2))
370+
.filter(fb -> fb.where("id.a").in(999_999, 999_000).and("id.b").in(now, nowPlus2))
337371
.orderBy(ob -> ob.orderBy("id.a").descending())
338372
.build());
339373
Assertions.assertThat(page).containsExactly(c1, c3);

0 commit comments

Comments
 (0)