From c8454fd8d0a2dfab2d22c0cc4f37974f732c95fa Mon Sep 17 00:00:00 2001 From: Neelesh Salian Date: Wed, 29 Jul 2026 15:09:20 -0700 Subject: [PATCH 1/4] Parquet, Spark, Flink: Type uniformity for variant shredding --- .../flink/TestFlinkVariantShreddingType.java | 39 ++----- .../parquet/VariantShreddingAnalyzer.java | 110 +++++++----------- .../parquet/TestVariantShreddingAnalyzer.java | 110 +++++++++++++++++- .../spark/variant/TestVariantShredding.java | 31 ++--- .../spark/variant/TestVariantShredding.java | 31 ++--- 5 files changed, 168 insertions(+), 153 deletions(-) diff --git a/flink/v2.1/flink/src/test/java/org/apache/iceberg/flink/TestFlinkVariantShreddingType.java b/flink/v2.1/flink/src/test/java/org/apache/iceberg/flink/TestFlinkVariantShreddingType.java index c4bd2efb4960..6cb035ddff9c 100644 --- a/flink/v2.1/flink/src/test/java/org/apache/iceberg/flink/TestFlinkVariantShreddingType.java +++ b/flink/v2.1/flink/src/test/java/org/apache/iceberg/flink/TestFlinkVariantShreddingType.java @@ -124,7 +124,7 @@ public void testExcludingNullValue() throws IOException { } @TestTemplate - public void testConsistentType() throws IOException { + public void testInconsistentTypeNotShredded() throws IOException { String values = """ (1, parse_json('{"age": "25"}')), @@ -133,18 +133,13 @@ public void testConsistentType() throws IOException { """; sql("INSERT INTO %s VALUES %s", TABLE_NAME, values); - GroupType age = - field( - "age", - shreddedPrimitive( - PrimitiveType.PrimitiveTypeName.BINARY, LogicalTypeAnnotation.stringType())); - GroupType address = variant("address", 2, Type.Repetition.REQUIRED, objectFields(age)); + GroupType address = variant("address", 2, Type.Repetition.REQUIRED); MessageType expectedSchema = parquetSchema(address); verifyParquetSchema(icebergTable, expectedSchema); } @TestTemplate - public void testPrimitiveType() throws IOException { + public void testMixedPrimitiveTypeAtRootNotShredded() throws IOException { String values = """ (1, parse_json('123')), @@ -153,13 +148,7 @@ public void testPrimitiveType() throws IOException { """; sql("INSERT INTO %s VALUES %s", TABLE_NAME, values); - GroupType address = - variant( - "address", - 2, - Type.Repetition.REQUIRED, - shreddedPrimitive( - PrimitiveType.PrimitiveTypeName.INT32, LogicalTypeAnnotation.intType(8, true))); + GroupType address = variant("address", 2, Type.Repetition.REQUIRED); MessageType expectedSchema = parquetSchema(address); assertThat(SimpleDataUtil.tableRecords(icebergTable)).hasSize(3); @@ -167,7 +156,7 @@ public void testPrimitiveType() throws IOException { } @TestTemplate - public void testPrimitiveDecimalType() throws IOException { + public void testMixedDecimalAndStringAtRootNotShredded() throws IOException { String values = """ (1, parse_json('123.56')), @@ -176,13 +165,7 @@ public void testPrimitiveDecimalType() throws IOException { """; sql("INSERT INTO %s VALUES %s", TABLE_NAME, values); - GroupType address = - variant( - "address", - 2, - Type.Repetition.REQUIRED, - shreddedPrimitive( - PrimitiveType.PrimitiveTypeName.INT32, LogicalTypeAnnotation.decimalType(2, 5))); + GroupType address = variant("address", 2, Type.Repetition.REQUIRED); MessageType expectedSchema = parquetSchema(address); assertThat(SimpleDataUtil.tableRecords(icebergTable)).hasSize(3); verifyParquetSchema(icebergTable, expectedSchema); @@ -587,7 +570,7 @@ public void testInfrequentFieldPruning() throws IOException { } @TestTemplate - public void testMixedTypeTieBreaking() throws IOException { + public void testMixedTypeFieldNotShredded() throws IOException { StringBuilder valuesBuilder = new StringBuilder(); for (int i = 1; i <= 10; i++) { if (i > 1) { @@ -617,13 +600,7 @@ public void testMixedTypeTieBreaking() throws IOException { sql("INSERT INTO %s VALUES %s", TABLE_NAME, valuesBuilder.toString()); - // 5 ints + 5 strings is a tie so STRING wins (higher TIE_BREAK_PRIORITY) - GroupType val = - field( - "val", - shreddedPrimitive( - PrimitiveType.PrimitiveTypeName.BINARY, LogicalTypeAnnotation.stringType())); - GroupType address = variant("address", 2, Type.Repetition.REQUIRED, objectFields(val)); + GroupType address = variant("address", 2, Type.Repetition.REQUIRED); MessageType expectedSchema = parquetSchema(address); verifyParquetSchema(icebergTable, expectedSchema); diff --git a/parquet/src/main/java/org/apache/iceberg/parquet/VariantShreddingAnalyzer.java b/parquet/src/main/java/org/apache/iceberg/parquet/VariantShreddingAnalyzer.java index 3e6694c38c05..c8e6ef26655a 100644 --- a/parquet/src/main/java/org/apache/iceberg/parquet/VariantShreddingAnalyzer.java +++ b/parquet/src/main/java/org/apache/iceberg/parquet/VariantShreddingAnalyzer.java @@ -51,10 +51,10 @@ * *