This is an automated email from the ASF dual-hosted git repository.

amoghj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new 5091e5752f ORC: Fail when initial default support is required. (#12026)
5091e5752f is described below

commit 5091e5752f8000afe3e116e5114d15eb61a4f9ef
Author: Ryan Blue <[email protected]>
AuthorDate: Wed Jan 22 07:14:29 2025 -0800

    ORC: Fail when initial default support is required. (#12026)
---
 .../java/org/apache/iceberg/orc/ORCSchemaUtil.java | 28 +++++++++++++--------
 .../apache/iceberg/orc/TestBuildOrcProjection.java | 29 +++++++++++++++++++++-
 2 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/orc/src/main/java/org/apache/iceberg/orc/ORCSchemaUtil.java 
b/orc/src/main/java/org/apache/iceberg/orc/ORCSchemaUtil.java
index 89a1632d5a..0a57c2f9ff 100644
--- a/orc/src/main/java/org/apache/iceberg/orc/ORCSchemaUtil.java
+++ b/orc/src/main/java/org/apache/iceberg/orc/ORCSchemaUtil.java
@@ -19,7 +19,6 @@
 package org.apache.iceberg.orc;
 
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -264,11 +263,11 @@ public final class ORCSchemaUtil {
   public static TypeDescription buildOrcProjection(
       Schema schema, TypeDescription originalOrcSchema) {
     final Map<Integer, OrcField> icebergToOrc = icebergToOrcMapping("root", 
originalOrcSchema);
-    return buildOrcProjection(Integer.MIN_VALUE, schema.asStruct(), true, 
icebergToOrc);
+    return buildOrcProjection(schema, Integer.MIN_VALUE, schema.asStruct(), 
true, icebergToOrc);
   }
 
   private static TypeDescription buildOrcProjection(
-      Integer fieldId, Type type, boolean isRequired, Map<Integer, OrcField> 
mapping) {
+      Schema root, Integer fieldId, Type type, boolean isRequired, 
Map<Integer, OrcField> mapping) {
     final TypeDescription orcType;
 
     switch (type.typeId()) {
@@ -284,6 +283,7 @@ public final class ORCSchemaUtil {
                   .orElseGet(() -> nestedField.name() + "_r" + 
nestedField.fieldId());
           TypeDescription childType =
               buildOrcProjection(
+                  root,
                   nestedField.fieldId(),
                   nestedField.type(),
                   isRequired && nestedField.isRequired(),
@@ -295,6 +295,7 @@ public final class ORCSchemaUtil {
         Types.ListType list = (Types.ListType) type;
         TypeDescription elementType =
             buildOrcProjection(
+                root,
                 list.elementId(),
                 list.elementType(),
                 isRequired && list.isElementRequired(),
@@ -304,10 +305,10 @@ public final class ORCSchemaUtil {
       case MAP:
         Types.MapType map = (Types.MapType) type;
         TypeDescription keyType =
-            buildOrcProjection(map.keyId(), map.keyType(), isRequired, 
mapping);
+            buildOrcProjection(root, map.keyId(), map.keyType(), isRequired, 
mapping);
         TypeDescription valueType =
             buildOrcProjection(
-                map.valueId(), map.valueType(), isRequired && 
map.isValueRequired(), mapping);
+                root, map.valueId(), map.valueType(), isRequired && 
map.isValueRequired(), mapping);
         orcType = TypeDescription.createMap(keyType, valueType);
         break;
       default:
@@ -326,13 +327,20 @@ public final class ORCSchemaUtil {
             orcType = originalType.clone();
           }
         } else {
+          Types.NestedField field = root.findField(fieldId);
           if (isRequired) {
-            throw new IllegalArgumentException(
+            Preconditions.checkArgument(
+                field.initialDefault() != null,
+                "Missing required field: %s (%s)",
+                root.findColumnName(fieldId),
+                type);
+          }
+
+          if (field.initialDefault() != null) {
+            throw new UnsupportedOperationException(
                 String.format(
-                    Locale.ROOT,
-                    "Field %d of type %s is required and was not found.",
-                    fieldId,
-                    type));
+                    "ORC cannot read default value for field %s (%s): %s",
+                    root.findColumnName(fieldId), type, 
field.initialDefault()));
           }
 
           orcType = convert(fieldId, type, false);
diff --git 
a/orc/src/test/java/org/apache/iceberg/orc/TestBuildOrcProjection.java 
b/orc/src/test/java/org/apache/iceberg/orc/TestBuildOrcProjection.java
index a179cb2f64..2d35f58613 100644
--- a/orc/src/test/java/org/apache/iceberg/orc/TestBuildOrcProjection.java
+++ b/orc/src/test/java/org/apache/iceberg/orc/TestBuildOrcProjection.java
@@ -162,6 +162,33 @@ public class TestBuildOrcProjection {
 
     assertThatThrownBy(() -> ORCSchemaUtil.buildOrcProjection(evolvedSchema, 
baseOrcSchema))
         .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("Field 4 of type long is required and was not found.");
+        .hasMessage("Missing required field: b.d (long)");
+  }
+
+  @Test
+  public void testRequiredNestedFieldWithDefaultMissingInFile() {
+    Schema baseSchema =
+        new Schema(
+            required(1, "a", Types.IntegerType.get()),
+            required(2, "b", Types.StructType.of(required(3, "c", 
Types.LongType.get()))));
+    TypeDescription baseOrcSchema = ORCSchemaUtil.convert(baseSchema);
+
+    Schema evolvedSchema =
+        new Schema(
+            required(1, "a", Types.IntegerType.get()),
+            required(
+                2,
+                "b",
+                Types.StructType.of(
+                    required(3, "c", Types.LongType.get()),
+                    Types.NestedField.required("d")
+                        .withId(4)
+                        .ofType(Types.LongType.get())
+                        .withInitialDefault(34L)
+                        .build())));
+
+    assertThatThrownBy(() -> ORCSchemaUtil.buildOrcProjection(evolvedSchema, 
baseOrcSchema))
+        .isInstanceOf(UnsupportedOperationException.class)
+        .hasMessage("ORC cannot read default value for field b.d (long): 34");
   }
 }

Reply via email to