From b1f328e76003db14e77cd316258de8a2fc292a23 Mon Sep 17 00:00:00 2001 From: kanthi subramanian Date: Wed, 30 Sep 2026 12:43:28 -0500 Subject: [PATCH 1/3] Fixed creating table from schema with variant data type --- .../ice/cli/internal/util/IcebergTypeParser.java | 2 +- .../cli/internal/util/IceSchemaParserTest.java | 11 ++++++++++- .../cli/internal/util/IcebergTypeParserTest.java | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ice/src/main/java/com/altinity/ice/cli/internal/util/IcebergTypeParser.java b/ice/src/main/java/com/altinity/ice/cli/internal/util/IcebergTypeParser.java index ac5dc5dc..da64031d 100644 --- a/ice/src/main/java/com/altinity/ice/cli/internal/util/IcebergTypeParser.java +++ b/ice/src/main/java/com/altinity/ice/cli/internal/util/IcebergTypeParser.java @@ -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) { diff --git a/ice/src/test/java/com/altinity/ice/cli/internal/util/IceSchemaParserTest.java b/ice/src/test/java/com/altinity/ice/cli/internal/util/IceSchemaParserTest.java index 9cbd600c..01cdff1b 100644 --- a/ice/src/test/java/com/altinity/ice/cli/internal/util/IceSchemaParserTest.java +++ b/ice/src/test/java/com/altinity/ice/cli/internal/util/IceSchemaParserTest.java @@ -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 diff --git a/ice/src/test/java/com/altinity/ice/cli/internal/util/IcebergTypeParserTest.java b/ice/src/test/java/com/altinity/ice/cli/internal/util/IcebergTypeParserTest.java index ac355b29..780ad5cd 100644 --- a/ice/src/test/java/com/altinity/ice/cli/internal/util/IcebergTypeParserTest.java +++ b/ice/src/test/java/com/altinity/ice/cli/internal/util/IcebergTypeParserTest.java @@ -40,6 +40,8 @@ public Object[][] validTypes() { {"struct", Type.TypeID.STRUCT}, {"struct>", Type.TypeID.STRUCT}, {"list>", Type.TypeID.LIST}, + {"variant", Type.TypeID.VARIANT}, + {"VARIANT", Type.TypeID.VARIANT}, }; } @@ -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"); + assertThat(struct.field("b").type().typeId()).isEqualTo(Type.TypeID.VARIANT); + + Types.ListType list = (Types.ListType) IcebergTypeParser.parseType("list"); + assertThat(list.elementType().typeId()).isEqualTo(Type.TypeID.VARIANT); + + Types.MapType map = (Types.MapType) IcebergTypeParser.parseType("map"); + assertThat(map.valueType().typeId()).isEqualTo(Type.TypeID.VARIANT); + } + @DataProvider(name = "invalidTypes") public Object[][] invalidTypes() { return new Object[][] { From aa79e5e14c10caf165117032d9ca2a4613c67acf Mon Sep 17 00:00:00 2001 From: kanthi subramanian Date: Wed, 30 Sep 2026 13:03:44 -0500 Subject: [PATCH 2/3] update jackson version to address vulnerabilities --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2455bcf3..cf57c610 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 1.15.2 2.31.13 4.7.6 - 2.18.8 + 2.18.10 2.0.17 1.5.18 1.3.6 From 19ff3fc72fc1878fcaab64d6d226efc66ce3fea2 Mon Sep 17 00:00:00 2001 From: kanthi subramanian Date: Wed, 30 Sep 2026 15:27:22 -0500 Subject: [PATCH 3/3] Added test for create table with variant --- .../iceberg-v3-variant-type/run.sh.tmpl | 60 +++++++++++++++++++ .../iceberg-v3-variant-type/scenario.yaml | 9 +++ 2 files changed, 69 insertions(+) create mode 100644 ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/run.sh.tmpl create mode 100644 ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/scenario.yaml diff --git a/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/run.sh.tmpl b/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/run.sh.tmpl new file mode 100644 index 00000000..d4494046 --- /dev/null +++ b/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/run.sh.tmpl @@ -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"}]' +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" diff --git a/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/scenario.yaml b/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/scenario.yaml new file mode 100644 index 00000000..35c960f9 --- /dev/null +++ b/ice-rest-catalog/src/test/resources/scenarios/iceberg-v3-variant-type/scenario.yaml @@ -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"