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

yihua pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/master by this push:
     new ea1e75de2488 feat(schema): Update serialization for HoodieSchema 
(#17575)
ea1e75de2488 is described below

commit ea1e75de248815b105c6d5a8ba2f9b072b205894
Author: Tim Brown <[email protected]>
AuthorDate: Fri Dec 12 01:37:37 2025 -0500

    feat(schema): Update serialization for HoodieSchema (#17575)
---
 .../apache/hudi/common/schema/HoodieSchema.java    | 21 +++++++--
 .../hudi/common/schema/TestHoodieSchema.java       | 50 ++++++++++++++++++++++
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git 
a/hudi-common/src/main/java/org/apache/hudi/common/schema/HoodieSchema.java 
b/hudi-common/src/main/java/org/apache/hudi/common/schema/HoodieSchema.java
index dd60e867f184..03a5c92a47dc 100644
--- a/hudi-common/src/main/java/org/apache/hudi/common/schema/HoodieSchema.java
+++ b/hudi-common/src/main/java/org/apache/hudi/common/schema/HoodieSchema.java
@@ -22,15 +22,17 @@ import org.apache.hudi.avro.HoodieAvroUtils;
 import org.apache.hudi.common.util.Option;
 import org.apache.hudi.common.util.ValidationUtils;
 import org.apache.hudi.exception.HoodieAvroSchemaException;
+import org.apache.hudi.exception.HoodieIOException;
 
 import org.apache.avro.JsonProperties;
 import org.apache.avro.LogicalType;
 import org.apache.avro.LogicalTypes;
 import org.apache.avro.Schema;
-import org.apache.hudi.exception.HoodieIOException;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -84,8 +86,8 @@ public class HoodieSchema implements Serializable {
    */
   public static final Object NULL_VALUE = JsonProperties.NULL_VALUE;
   private static final long serialVersionUID = 1L;
-  private final Schema avroSchema;
-  private final HoodieSchemaType type;
+  private Schema avroSchema;
+  private HoodieSchemaType type;
 
   /**
    * Creates a new HoodieSchema wrapping the given Avro schema.
@@ -1335,4 +1337,17 @@ public class HoodieSchema implements Serializable {
     MILLIS,
     MICROS
   }
+
+  private void writeObject(ObjectOutputStream oos) throws IOException {
+    oos.defaultWriteObject();
+    oos.writeObject(avroSchema.toString());
+  }
+
+  private void readObject(ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+    ois.defaultReadObject();
+    String schemaString = (String) ois.readObject();
+    avroSchema = new Schema.Parser().parse(schemaString);
+    type = HoodieSchemaType.fromAvro(avroSchema);
+  }
 }
diff --git 
a/hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchema.java 
b/hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchema.java
index f68de07cf4ab..6227c8556750 100644
--- 
a/hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchema.java
+++ 
b/hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchema.java
@@ -28,6 +28,10 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -930,4 +934,50 @@ public class TestHoodieSchema {
     assertTrue(retrievedValueSchema instanceof HoodieSchema.Time);
     assertEquals(HoodieSchema.TimePrecision.MILLIS, ((HoodieSchema.Time) 
retrievedValueSchema).getPrecision());
   }
+
+  @Test
+  void validateSerialization() throws Exception {
+    HoodieSchema originalSchema = HoodieSchema.parse(SAMPLE_RECORD_SCHEMA);
+    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+    try (ObjectOutputStream out = new ObjectOutputStream(byteOut)) {
+      out.writeObject(originalSchema);
+    }
+    byte[] bytesWritten = byteOut.toByteArray();
+    HoodieSchema deserializedSchema;
+    try (ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(bytesWritten))) {
+      deserializedSchema = (HoodieSchema) in.readObject();
+    }
+    assertEquals(originalSchema, deserializedSchema);
+  }
+
+  @Test
+  void validateSerializationOfSubclass() throws Exception {
+    HoodieSchema decimalSchema = HoodieSchema.createDecimal(15, 5);
+    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+    try (ObjectOutputStream out = new ObjectOutputStream(byteOut)) {
+      out.writeObject(decimalSchema);
+    }
+    byte[] bytesWritten = byteOut.toByteArray();
+    HoodieSchema deserializedSchema;
+    try (ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(bytesWritten))) {
+      deserializedSchema = (HoodieSchema) in.readObject();
+    }
+    assertEquals(decimalSchema, deserializedSchema);
+    assertTrue(deserializedSchema instanceof HoodieSchema.Decimal);
+    assertEquals(15, ((HoodieSchema.Decimal) 
deserializedSchema).getPrecision());
+    assertEquals(5, ((HoodieSchema.Decimal) deserializedSchema).getScale());
+
+    HoodieSchema timestampSchema = HoodieSchema.createTimestampMicros();
+    byteOut = new ByteArrayOutputStream();
+    try (ObjectOutputStream out = new ObjectOutputStream(byteOut)) {
+      out.writeObject(timestampSchema);
+    }
+    bytesWritten = byteOut.toByteArray();
+    try (ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(bytesWritten))) {
+      deserializedSchema = (HoodieSchema) in.readObject();
+    }
+    assertEquals(timestampSchema, deserializedSchema);
+    assertTrue(deserializedSchema instanceof HoodieSchema.Timestamp);
+    assertEquals(HoodieSchema.TimePrecision.MICROS, ((HoodieSchema.Timestamp) 
deserializedSchema).getPrecision());
+  }
 }

Reply via email to