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());
+ }
}