Skip to content

Commit 6129423

Browse files
authored
GH-3627: Add missing onAppend() to VariantBuilder#appendUUIDBytes (#3624)
1 parent 8db1c67 commit 6129423

4 files changed

Lines changed: 81 additions & 0 deletions

File tree

parquet-variant/src/main/java/org/apache/parquet/variant/VariantBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ public void appendUUID(java.util.UUID uuid) {
420420
* @param bytes a 16-byte value.
421421
*/
422422
void appendUUIDBytes(ByteBuffer bytes) {
423+
onAppend();
423424
checkCapacity(1 + VariantUtil.UUID_SIZE);
424425
writeBuffer[writePos++] = VariantUtil.primitiveHeader(VariantUtil.UUID);
425426
if (bytes.remaining() < VariantUtil.UUID_SIZE) {

parquet-variant/src/test/java/org/apache/parquet/variant/TestVariantArrayBuilder.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
package org.apache.parquet.variant;
2020

21+
import java.nio.ByteBuffer;
22+
import java.nio.ByteOrder;
23+
import java.util.UUID;
2124
import org.junit.Assert;
2225
import org.junit.Test;
2326
import org.slf4j.Logger;
@@ -26,6 +29,34 @@
2629
public class TestVariantArrayBuilder {
2730
private static final Logger LOG = LoggerFactory.getLogger(TestVariantArrayBuilder.class);
2831

32+
@Test
33+
public void testArrayBuilderWithUUIDBytes() {
34+
byte[] uuid = new byte[] {0, 17, 34, 51, 68, 85, 102, 119, -120, -103, -86, -69, -52, -35, -18, -1};
35+
long msb = ByteBuffer.wrap(uuid, 0, 8).order(ByteOrder.BIG_ENDIAN).getLong();
36+
long lsb = ByteBuffer.wrap(uuid, 8, 8).order(ByteOrder.BIG_ENDIAN).getLong();
37+
UUID expected = new UUID(msb, lsb);
38+
39+
VariantBuilder builder = new VariantBuilder();
40+
VariantArrayBuilder array = builder.startArray();
41+
array.appendInt(1);
42+
// appendUUIDBytes must go through onAppend() so that the element offset is recorded and
43+
// numValues is incremented. Otherwise the offset list is wrong and the UUID element is lost.
44+
array.appendUUIDBytes(ByteBuffer.wrap(uuid));
45+
array.appendInt(2);
46+
builder.endArray();
47+
48+
VariantTestUtil.testVariant(builder.build(), v -> {
49+
VariantTestUtil.checkType(v, VariantUtil.ARRAY, Variant.Type.ARRAY);
50+
Assert.assertEquals(3, v.numArrayElements());
51+
VariantTestUtil.checkType(v.getElementAtIndex(0), VariantUtil.PRIMITIVE, Variant.Type.INT);
52+
Assert.assertEquals(1, v.getElementAtIndex(0).getInt());
53+
VariantTestUtil.checkType(v.getElementAtIndex(1), VariantUtil.PRIMITIVE, Variant.Type.UUID);
54+
Assert.assertEquals(expected, v.getElementAtIndex(1).getUUID());
55+
VariantTestUtil.checkType(v.getElementAtIndex(2), VariantUtil.PRIMITIVE, Variant.Type.INT);
56+
Assert.assertEquals(2, v.getElementAtIndex(2).getInt());
57+
});
58+
}
59+
2960
@Test
3061
public void testEmptyArrayBuilder() {
3162
VariantBuilder b = new VariantBuilder();

parquet-variant/src/test/java/org/apache/parquet/variant/TestVariantObjectBuilder.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
package org.apache.parquet.variant;
2020

2121
import java.nio.ByteBuffer;
22+
import java.nio.ByteOrder;
23+
import java.util.UUID;
2224
import org.junit.Assert;
2325
import org.junit.Ignore;
2426
import org.junit.Test;
@@ -28,6 +30,29 @@
2830
public class TestVariantObjectBuilder {
2931
private static final Logger LOG = LoggerFactory.getLogger(TestVariantObjectBuilder.class);
3032

33+
@Test
34+
public void testObjectBuilderWithUUIDBytes() {
35+
byte[] uuid = new byte[] {0, 17, 34, 51, 68, 85, 102, 119, -120, -103, -86, -69, -52, -35, -18, -1};
36+
long msb = ByteBuffer.wrap(uuid, 0, 8).order(ByteOrder.BIG_ENDIAN).getLong();
37+
long lsb = ByteBuffer.wrap(uuid, 8, 8).order(ByteOrder.BIG_ENDIAN).getLong();
38+
UUID expected = new UUID(msb, lsb);
39+
40+
VariantBuilder builder = new VariantBuilder();
41+
VariantObjectBuilder object = builder.startObject();
42+
object.appendKey("id");
43+
// appendUUIDBytes must go through onAppend() so that numValues stays in sync with the
44+
// appended keys. Otherwise endObject() throws because keys (1) != values (0).
45+
object.appendUUIDBytes(ByteBuffer.wrap(uuid));
46+
builder.endObject();
47+
48+
VariantTestUtil.testVariant(builder.build(), v -> {
49+
VariantTestUtil.checkType(v, VariantUtil.OBJECT, Variant.Type.OBJECT);
50+
Assert.assertEquals(1, v.numObjectElements());
51+
VariantTestUtil.checkType(v.getFieldByKey("id"), VariantUtil.PRIMITIVE, Variant.Type.UUID);
52+
Assert.assertEquals(expected, v.getFieldByKey("id").getUUID());
53+
});
54+
}
55+
3156
@Test
3257
public void testEmptyObjectBuilder() {
3358
VariantBuilder b = new VariantBuilder();

parquet-variant/src/test/java/org/apache/parquet/variant/TestVariantScalarBuilder.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,4 +512,28 @@ public void testUUIDBuilder() {
512512
// expected
513513
}
514514
}
515+
516+
@Test
517+
public void testUUIDBytesBuilder() {
518+
byte[] uuid = new byte[] {0, 17, 34, 51, 68, 85, 102, 119, -120, -103, -86, -69, -52, -35, -18, -1};
519+
long msb = ByteBuffer.wrap(uuid, 0, 8).order(ByteOrder.BIG_ENDIAN).getLong();
520+
long lsb = ByteBuffer.wrap(uuid, 8, 8).order(ByteOrder.BIG_ENDIAN).getLong();
521+
UUID expected = new UUID(msb, lsb);
522+
523+
VariantBuilder vb = new VariantBuilder();
524+
vb.appendUUIDBytes(ByteBuffer.wrap(uuid));
525+
VariantTestUtil.testVariant(vb.build(), v -> {
526+
VariantTestUtil.checkType(v, VariantUtil.PRIMITIVE, Variant.Type.UUID);
527+
Assert.assertEquals(expected, v.getUUID());
528+
});
529+
530+
// appendUUIDBytes must go through onAppend(), so a second append on the root builder
531+
// (which already holds a value) must be rejected instead of producing a multi-value buffer.
532+
try {
533+
vb.appendUUIDBytes(ByteBuffer.wrap(uuid));
534+
Assert.fail("Expected Exception when appending multiple values");
535+
} catch (Exception e) {
536+
// expected
537+
}
538+
}
515539
}

0 commit comments

Comments
 (0)