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

amogh-jahagirdar 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 52ea8a497f API, Core: Add toString to StructProjection and 
StructLikeUtil (#18342)
52ea8a497f is described below

commit 52ea8a497f2565a789cd5626c6716ca809a263ec
Author: Anoop Johnson <[email protected]>
AuthorDate: Fri Oct 2 06:07:02 2026 -0700

    API, Core: Add toString to StructProjection and StructLikeUtil (#18342)
---
 .../org/apache/iceberg/util/StructProjection.java  | 23 +++++++++++++++++
 .../apache/iceberg/util/TestStructProjection.java  | 29 ++++++++++++++++++++++
 .../org/apache/iceberg/util/StructLikeUtil.java    |  7 ++++++
 3 files changed, 59 insertions(+)

diff --git a/api/src/main/java/org/apache/iceberg/util/StructProjection.java 
b/api/src/main/java/org/apache/iceberg/util/StructProjection.java
index 9db90a061c..8471d017e4 100644
--- a/api/src/main/java/org/apache/iceberg/util/StructProjection.java
+++ b/api/src/main/java/org/apache/iceberg/util/StructProjection.java
@@ -20,6 +20,7 @@ package org.apache.iceberg.util;
 
 import java.util.List;
 import java.util.Set;
+import java.util.StringJoiner;
 import org.apache.iceberg.Schema;
 import org.apache.iceberg.StructLike;
 import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
@@ -223,4 +224,26 @@ public class StructProjection implements StructLike {
   public <T> void set(int pos, T value) {
     throw new UnsupportedOperationException("Cannot set fields in a 
TypeProjection");
   }
+
+  @Override
+  public String toString() {
+    List<Types.NestedField> fields = type.fields();
+    StringJoiner joiner = new StringJoiner(", ", "StructProjection{", "}");
+    for (int pos = 0; pos < fields.size(); pos += 1) {
+      int structPos = positionMap[pos];
+      Object value;
+      if (struct == null || structPos == -1) {
+        value = null;
+      } else if (nestedProjections[pos] != null) {
+        StructLike nestedStruct = struct.get(structPos, StructLike.class);
+        value = nestedStruct == null ? null : 
nestedProjections[pos].copyFor(nestedStruct);
+      } else {
+        value = struct.get(structPos, Object.class);
+      }
+
+      joiner.add(fields.get(pos).name() + "=" + value);
+    }
+
+    return joiner.toString();
+  }
 }
diff --git 
a/api/src/test/java/org/apache/iceberg/util/TestStructProjection.java 
b/api/src/test/java/org/apache/iceberg/util/TestStructProjection.java
index 579918c755..33f60a59b5 100644
--- a/api/src/test/java/org/apache/iceberg/util/TestStructProjection.java
+++ b/api/src/test/java/org/apache/iceberg/util/TestStructProjection.java
@@ -69,4 +69,33 @@ class TestStructProjection {
         .isInstanceOf(IllegalArgumentException.class)
         .hasMessageStartingWith("Cannot find field");
   }
+
+  @Test
+  void toStringRendersNestedProjectionRecursively() {
+    StructProjection projection = StructProjection.create(PROJECTED_STRUCT, 
PROJECTED_STRUCT);
+    projection.wrap(Row.of(1L, Row.of("John", "Q", "Doe")));
+
+    assertThat(projection)
+        .hasToString(
+            "StructProjection{id=1, person=StructProjection{first=John, 
middle=Q, last=Doe}}");
+  }
+
+  @Test
+  void toStringRendersNullNestedStructAsNull() {
+    StructProjection projection = StructProjection.create(PROJECTED_STRUCT, 
PROJECTED_STRUCT);
+    projection.wrap(Row.of(1L, null));
+
+    assertThat(projection).hasToString("StructProjection{id=1, person=null}");
+  }
+
+  @Test
+  void toStringRendersMissingNestedFieldAsNull() {
+    StructProjection projection =
+        StructProjection.createAllowMissing(DATA_STRUCT_MISSING_NESTED_FIELD, 
PROJECTED_STRUCT);
+    projection.wrap(Row.of(1L, Row.of("John", "Doe")));
+
+    assertThat(projection)
+        .hasToString(
+            "StructProjection{id=1, person=StructProjection{first=John, 
middle=null, last=Doe}}");
+  }
 }
diff --git a/core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java 
b/core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java
index c3a728f810..613c5a04e3 100644
--- a/core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java
+++ b/core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java
@@ -19,6 +19,8 @@
 package org.apache.iceberg.util;
 
 import java.io.Serializable;
+import java.util.Arrays;
+import java.util.stream.Collectors;
 import org.apache.iceberg.StructLike;
 
 public class StructLikeUtil {
@@ -64,5 +66,10 @@ public class StructLikeUtil {
     public <T> void set(int pos, T value) {
       throw new UnsupportedOperationException("Struct copy cannot be 
modified");
     }
+
+    @Override
+    public String toString() {
+      return 
Arrays.stream(values).map(String::valueOf).collect(Collectors.joining(", ", 
"[", "]"));
+    }
   }
 }

Reply via email to