This is an automated email from the ASF dual-hosted git repository.
sivabalan 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 c02706ed4c1f [HUDI-9798][RFC-101] Updates to the HoodieRecordMerger
Interface (#13865)
c02706ed4c1f is described below
commit c02706ed4c1f45c57330a8d6742c819222d5ab6d
Author: Tim Brown <[email protected]>
AuthorDate: Sat Sep 13 12:39:36 2025 -0400
[HUDI-9798][RFC-101] Updates to the HoodieRecordMerger Interface (#13865)
---
rfc/README.md | 2 +-
rfc/rfc-101/rfc-101.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/rfc/README.md b/rfc/README.md
index 1f37521008ae..1867381ce1e1 100644
--- a/rfc/README.md
+++ b/rfc/README.md
@@ -136,4 +136,4 @@ The list of all RFCs can be found here.
| 98 | [Spark Datasource V2 Read](./rfc-98/rfc-98.md)
| :eyes:
`UNDER REVIEW` |
| 99 | [Hudi Type System Redesign](./rfc-99/rfc-99.md)
| :eyes:
`UNDER REVIEW` |
| 100 | [Unstructured Data Storage in Hudi](./rfc-100/rfc-100.md)
| :eyes:
`UNDER REVIEW` |
-| 100 | Updates to the HoodieRecordMerger API
|
:hammer_and_wrench: `IN PROGRESS` |
\ No newline at end of file
+| 100 | [Updates to the HoodieRecordMerger API](./rfc-101/rfc-101.md)
|
:hammer_and_wrench: `IN PROGRESS` |
\ No newline at end of file
diff --git a/rfc/rfc-101/rfc-101.md b/rfc/rfc-101/rfc-101.md
new file mode 100644
index 000000000000..276a0e83d5cc
--- /dev/null
+++ b/rfc/rfc-101/rfc-101.md
@@ -0,0 +1,103 @@
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+# RFC-101: Updates to the HoodieRecordMerger API
+
+## Proposers
+
+- @the-other-tim-brown
+
+## Approvers
+ - @<approver1 github username>
+ - @<approver2 github username>
+
+## Status
+
+JIRA: https://issues.apache.org/jira/browse/HUDI-9798
+
+> Please keep the status updated in `rfc/README.md`.
+
+## Abstract
+The HoodieRecordMerger interface allows users to implement custom merging
logic for records. The interface does not provide clear instructions on how to
handle deletions and can currently lead to differences in behavior based on
execution engine.
+This RFC proposes updates to the interface to clarify the expectations so that
out of order updates and deletes are handled properly across implementations.
+
+## Background
+Currently, the
[HoodieRecordMerger](https://github.com/apache/hudi/blob/9ca72f9d932b14b414ca605560d1145de7e525a6/hudi-common/src/main/java/org/apache/hudi/common/model/HoodieRecordMerger.java)
interface implementations within the Hudi codebase are not consistent when it
comes to how deletions are handled and can lead to differences in the results
when merging records as part of the writer or reader path. Also, it is unclear
from the current documentation of the interface for how the impl [...]
+
+As part of the migration to the new
[HoodieFileGroupReader](https://github.com/apache/hudi/blob/9ca72f9d932b14b414ca605560d1145de7e525a6/hudi-common/src/main/java/org/apache/hudi/common/table/read/HoodieFileGroupReader.java),
the merging logic has been refactored for the common use cases by creating a
[BufferedRecord](https://github.com/apache/hudi/blob/9ca72f9d932b14b414ca605560d1145de7e525a6/hudi-common/src/main/java/org/apache/hudi/common/table/read/BufferedRecord.java),
which wraps t [...]
+
+## Implementation
+The HoodieRecordMerger interface will be updated to no longer rely on the
HoodieRecord class, and instead use the `BufferedRecord` and `RecordContext`
classes.
+The `BufferedRecord` class contains the data as well as the record key,
ordering value, schema identifier, and the `HoodieOperation`.
+
+The existing interface methods are listed here for reference:
+
+```java
+import java.io.IOException;
+
+Option<Pair<HoodieRecord, Schema>> partialMerge(HoodieRecord older, Schema
oldSchema, HoodieRecord newer,
+ Schema newSchema, Schema
readerSchema, TypedProperties props) throws IOException;
+
+Option<Pair<HoodieRecord, Schema>> merge(HoodieRecord older, Schema oldSchema,
HoodieRecord newer, Schema newSchema,
+ TypedProperties props) throws
IOException;
+
+ist<Pair<HoodieRecord, Schema>> fullOuterMerge(HoodieRecord older, Schema
oldSchema, HoodieRecord newer,
+ Schema newSchema,
TypedProperties props) throws IOException;
+
+boolean shouldFlush(HoodieRecord record, Schema schema, TypedProperties props)
throws IOException;
+```
+
+The methods in the interface will be updated as follows:
+```java
+<T> BufferedRecord<T> partialMerge(BufferedRecord<T> older, BufferedRecord<T>
newer, Schema readerSchema,
+ RecordContext<T> recordContext,
MergerConfig config) throws IOException;
+
+<T> BufferedRecord merge(BufferedRecord<T> older, BufferedRecord<T> newer,
RecordContext<T> recordContext,
+ MergerConfig config) throws IOException;
+---
+
+/**
+ * MergerConfig is a configuration class used to pass all the required
properties for merging records.
+ * The record key, partition, and ordering field configurations along with
options required by the
+ * DeleteContext will be present in this object. Any custom options provided
to the reader or writer
+ * will also be passed to this object to ensure custom mergers and payloads
have access to the properties
+ * set by the user.
+ */
+public class MergerConfig extends HoodieConfig {
+ ...
+}
+```
+For both the `merge` and `partialMerge` methods, the implementation will mark
the resulting `BufferedRecord` as a delete operation if the resulting record
should result in a deletion of the row matching that record key. The
implementation should also return the data in the `BufferedRecord` as non-null
whenever possible to allow for the logic in future merge operations to
reference the previous value of the data, even if that value results in a
deletion. The ordering values must always be [...]
+
+Using the new `BufferedRecord` class will allow for easier integration with
the `BufferedRecordMerger` interface used by the `HoodieFileGroupReader` and
avoid converting to and from the `HoodieRecord` class while merging.
+
+In addition to the updates to the existing methods, two methods will be
removed. The `shouldFlush` method will be removed from the interface as part of
simplifying the interface. This method served as another way a user could
decide to not write the output to a file, but now any record that should not be
written to the file should simply be marked as a delete operation. The
`fullOuterMerge` method will also be removed since it is not used in the
current codebase. It can be re-added if th [...]
+
+## Rollout/Adoption Plan
+
+ - What impact (if any) will there be on existing users?
+ - This change is a breaking change in the API. For all users relying simply
on the merging logic that the project already provides, they will not need to
make any changes. For other users that have a custom implementation, it will
cause failures. They will need to update their implementation to comply with
the new interface and expectations.
+ - If we are changing behavior how will we phase out the older behavior?
+ - The change will force users to update their implementation as part of
upgrading to Apache Hudi 1.1.0 or above. The usage of the `shouldFlush` API
will be removed from the codebase and the updates to the existing merger
implementations will be handled before the Apache Hudi 1.1.0 release.
+ - If we need special migration tools, describe them here.
+ - When will we remove the existing behavior
+ - As part of the Apache Hudi 1.1.0 release.
+
+## Test Plan
+
+1. Ensure that all existing tests pass with the new interface and
implementation updates.
+2. Add new unit tests for the usage of custom mergers and payloads within the
HoodieFileGroupReader path to ensure that a custom ordering is respected across
updates and deletes.
+3. Add functional tests to ensure the end-to-end writer flows work as expected
when using a custom merger implementation.
\ No newline at end of file