Skip to content

Commit 9473e1f

Browse files
committed
Add Variant logical type annotation to parquet-java
1 parent ccac04f commit 9473e1f

3 files changed

Lines changed: 82 additions & 0 deletions

File tree

parquet-column/src/main/java/org/apache/parquet/schema/LogicalTypeAnnotation.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ protected LogicalTypeAnnotation fromString(List<String> params) {
5656
return listType();
5757
}
5858
},
59+
VARIANT {
60+
@Override
61+
protected LogicalTypeAnnotation fromString(List<String> params) {
62+
return variantType();
63+
}
64+
},
5965
STRING {
6066
@Override
6167
protected LogicalTypeAnnotation fromString(List<String> params) {
@@ -263,6 +269,10 @@ public static ListLogicalTypeAnnotation listType() {
263269
return ListLogicalTypeAnnotation.INSTANCE;
264270
}
265271

272+
public static VariantLogicalTypeAnnotation variantType() {
273+
return VariantLogicalTypeAnnotation.INSTANCE;
274+
}
275+
266276
public static EnumLogicalTypeAnnotation enumType() {
267277
return EnumLogicalTypeAnnotation.INSTANCE;
268278
}
@@ -1091,6 +1101,28 @@ public int hashCode() {
10911101
}
10921102
}
10931103

1104+
public static class VariantLogicalTypeAnnotation extends LogicalTypeAnnotation {
1105+
private static final VariantLogicalTypeAnnotation INSTANCE = new VariantLogicalTypeAnnotation();
1106+
1107+
private VariantLogicalTypeAnnotation() {}
1108+
1109+
@Override
1110+
public OriginalType toOriginalType() {
1111+
// No OriginalType for Variant
1112+
return null;
1113+
}
1114+
1115+
@Override
1116+
public <T> Optional<T> accept(LogicalTypeAnnotationVisitor<T> logicalTypeAnnotationVisitor) {
1117+
return logicalTypeAnnotationVisitor.visit(this);
1118+
}
1119+
1120+
@Override
1121+
LogicalTypeToken getType() {
1122+
return LogicalTypeToken.VARIANT;
1123+
}
1124+
}
1125+
10941126
/**
10951127
* Implement this interface to visit a logical type annotation in the schema.
10961128
* The default implementation for each logical type specific visitor method is empty.
@@ -1115,6 +1147,10 @@ default Optional<T> visit(ListLogicalTypeAnnotation listLogicalType) {
11151147
return empty();
11161148
}
11171149

1150+
default Optional<T> visit(VariantLogicalTypeAnnotation variantLogicalType) {
1151+
return empty();
1152+
}
1153+
11181154
default Optional<T> visit(EnumLogicalTypeAnnotation enumLogicalType) {
11191155
return empty();
11201156
}

parquet-column/src/test/java/org/apache/parquet/schema/TestTypeBuilders.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import static org.apache.parquet.schema.Type.Repetition.OPTIONAL;
5151
import static org.apache.parquet.schema.Type.Repetition.REPEATED;
5252
import static org.apache.parquet.schema.Type.Repetition.REQUIRED;
53+
import static org.junit.Assert.assertEquals;
5354

5455
import java.util.ArrayList;
5556
import java.util.List;
@@ -1414,6 +1415,26 @@ public void testTimestampLogicalTypeWithUTCParameter() {
14141415
Assert.assertEquals(nonUtcMicrosExpected, nonUtcMicrosActual);
14151416
}
14161417

1418+
@Test
1419+
public void testVariantLogicalType() {
1420+
String name = "variant_field";
1421+
GroupType variantExpected = new GroupType(
1422+
REQUIRED,
1423+
name,
1424+
LogicalTypeAnnotation.variantType(),
1425+
new PrimitiveType(REQUIRED, BINARY, "metadata"),
1426+
new PrimitiveType(REQUIRED, BINARY, "value"));
1427+
1428+
GroupType variantActual = Types.buildGroup(REQUIRED)
1429+
.addFields(
1430+
Types.required(BINARY).named("metadata"),
1431+
Types.required(BINARY).named("value"))
1432+
.as(LogicalTypeAnnotation.variantType())
1433+
.named(name);
1434+
1435+
assertEquals(variantExpected, variantActual);
1436+
}
1437+
14171438
@Test(expected = IllegalArgumentException.class)
14181439
public void testDecimalLogicalTypeWithDeprecatedScaleMismatch() {
14191440
Types.required(BINARY)

parquet-column/src/test/java/org/apache/parquet/schema/TestTypeBuildersWithLogicalTypes.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import static org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT96;
4242
import static org.apache.parquet.schema.Type.Repetition.REQUIRED;
4343
import static org.junit.Assert.assertEquals;
44+
import static org.junit.Assert.assertNull;
45+
import static org.junit.Assert.assertTrue;
4446

4547
import java.util.concurrent.Callable;
4648
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName;
@@ -473,6 +475,29 @@ public void testFloat16LogicalType() {
473475
.toString());
474476
}
475477

478+
@Test
479+
public void testVariantLogicalType() {
480+
String name = "variant_field";
481+
GroupType variant = new GroupType(
482+
REQUIRED,
483+
name,
484+
LogicalTypeAnnotation.variantType(),
485+
Types.required(BINARY).named("metadata"),
486+
Types.required(BINARY).named("value"));
487+
488+
assertEquals(
489+
"required group variant_field (VARIANT) {\n"
490+
+ " required binary metadata;\n"
491+
+ " required binary value;\n"
492+
+ "}",
493+
variant.toString());
494+
495+
LogicalTypeAnnotation annotation = variant.getLogicalTypeAnnotation();
496+
assertEquals(LogicalTypeAnnotation.LogicalTypeToken.VARIANT, annotation.getType());
497+
assertNull(annotation.toOriginalType());
498+
assertTrue(annotation instanceof LogicalTypeAnnotation.VariantLogicalTypeAnnotation);
499+
}
500+
476501
/**
477502
* A convenience method to avoid a large number of @Test(expected=...) tests
478503
*

0 commit comments

Comments
 (0)