Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash
set -e

echo "Running Iceberg v3 variant-type (--schema) test..."

# Create namespace
{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME}
echo "OK Created namespace: ${NAMESPACE_NAME}"

# Create a v3 table with an explicit schema containing v3-only variant columns,
# both top-level and nested inside a struct
{{ICE_CLI}} --config {{CLI_CONFIG}} create-table ${TABLE_NAME} --format-version=3 \
--schema '[{"name":"id","type":"long","required":true},{"name":"payload","type":"variant"},{"name":"s","type":"struct<a:string,b:variant>"}]'
echo "OK Created table ${TABLE_NAME} via --schema (variant columns)"

# Verify schema output shows the variant columns
{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/v3_variant_schema.txt
if ! grep -q "payload: optional variant" /tmp/v3_variant_schema.txt; then
echo "FAIL describe -s output missing 'payload: optional variant'"
cat /tmp/v3_variant_schema.txt
exit 1
fi
echo "OK describe -s shows payload: optional variant"
if ! grep -q "b: optional variant" /tmp/v3_variant_schema.txt; then
echo "FAIL describe -s output missing nested 'b: optional variant'"
cat /tmp/v3_variant_schema.txt
exit 1
fi
echo "OK describe -s shows nested b: optional variant"

# Verify describe output shows formatVersion 3 (Iceberg strips format-version from properties)
{{ICE_CLI}} --config {{CLI_CONFIG}} describe ${TABLE_NAME} > /tmp/v3_variant_describe.txt
if ! grep -q "formatVersion: 3" /tmp/v3_variant_describe.txt; then
echo "FAIL describe output missing 'formatVersion: 3'"
cat /tmp/v3_variant_describe.txt
exit 1
fi
echo "OK describe shows formatVersion: 3"

# Negative: variant type must be rejected without --format-version=3 (default is v2)
if {{ICE_CLI}} --config {{CLI_CONFIG}} create-table ${NAMESPACE_NAME}.t2 \
--schema '[{"name":"payload","type":"variant"}]' > /tmp/v3_variant_v2.out 2>&1; then
echo "FAIL create-table with variant type on v2 succeeded unexpectedly"
exit 1
fi
if ! grep -q "not supported until v3" /tmp/v3_variant_v2.out; then
echo "FAIL v2 rejection missing 'not supported until v3'"
cat /tmp/v3_variant_v2.out
exit 1
fi
echo "OK v2 table with variant type rejected"

# Cleanup
{{ICE_CLI}} --config {{CLI_CONFIG}} delete-table ${TABLE_NAME}
echo "OK Deleted table: ${TABLE_NAME}"

{{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME}
echo "OK Deleted namespace: ${NAMESPACE_NAME}"

echo "Iceberg v3 variant-type test completed successfully"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: "Iceberg v3 Variant Type via --schema"
description: "Tests create-table --schema with v3-only variant columns (top-level and nested); verifies via ice describe"

catalogConfig:
warehouse: "s3://test-bucket/warehouse"

env:
NAMESPACE_NAME: "test_v3_variant"
TABLE_NAME: "test_v3_variant.t1"
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static Type parseType(String typeString, AtomicInteger nextId) {
return parseStruct(s, nextId);
}

return Types.fromPrimitiveString(s);
return Types.fromTypeName(s);
}

private static Types.ListType parseList(String s, AtomicInteger nextId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,19 @@ public void testV3OnlyTypes() throws IOException {
IceSchemaParser.parse(
"[{\"name\":\"u\",\"type\":\"unknown\"},"
+ "{\"name\":\"t\",\"type\":\"timestamp_ns\"},"
+ "{\"name\":\"g\",\"type\":\"geometry\"}]");
+ "{\"name\":\"g\",\"type\":\"geometry\"},"
+ "{\"name\":\"v\",\"type\":\"variant\"}]");
assertThat(schema.findField("u").type().typeId()).isEqualTo(Type.TypeID.UNKNOWN);
assertThat(schema.findField("t").type().typeId()).isEqualTo(Type.TypeID.TIMESTAMP_NANO);
assertThat(schema.findField("g").type().typeId()).isEqualTo(Type.TypeID.GEOMETRY);
assertThat(schema.findField("v").type().typeId()).isEqualTo(Type.TypeID.VARIANT);
}

@Test
public void testVariant() throws IOException {
Schema schema = IceSchemaParser.parse("[{\"name\":\"v\",\"type\":\"variant\"}]");
assertThat(schema.columns()).hasSize(1);
assertThat(schema.findField("v").type().typeId()).isEqualTo(Type.TypeID.VARIANT);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public Object[][] validTypes() {
{"struct<a:string,b:long>", Type.TypeID.STRUCT},
{"struct<name:string,tags:list<string>>", Type.TypeID.STRUCT},
{"list<struct<id:long,name:string>>", Type.TypeID.LIST},
{"variant", Type.TypeID.VARIANT},
{"VARIANT", Type.TypeID.VARIANT},
};
}

Expand Down Expand Up @@ -72,6 +74,19 @@ public void testNestedStructFields() {
assertThat(inner.field("name").type().typeId()).isEqualTo(Type.TypeID.STRING);
}

@Test
public void testNestedVariant() {
Types.StructType struct =
(Types.StructType) IcebergTypeParser.parseType("struct<a:string,b:variant>");
assertThat(struct.field("b").type().typeId()).isEqualTo(Type.TypeID.VARIANT);

Types.ListType list = (Types.ListType) IcebergTypeParser.parseType("list<variant>");
assertThat(list.elementType().typeId()).isEqualTo(Type.TypeID.VARIANT);

Types.MapType map = (Types.MapType) IcebergTypeParser.parseType("map<string,variant>");
assertThat(map.valueType().typeId()).isEqualTo(Type.TypeID.VARIANT);
}

@DataProvider(name = "invalidTypes")
public Object[][] invalidTypes() {
return new Object[][] {
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<parquet.version>1.15.2</parquet.version>
<aws.java.sdk.version>2.31.13</aws.java.sdk.version>
<picocli.version>4.7.6</picocli.version>
<jackson.version>2.18.8</jackson.version>
<jackson.version>2.18.10</jackson.version>
<slf4j.version>2.0.17</slf4j.version>
<logback.version>1.5.18</logback.version>
<prometheus.version>1.3.6</prometheus.version>
Expand Down
Loading