hudi-agent commented on code in PR #19908:
URL: https://github.com/apache/hudi/pull/19908#discussion_r3998624175


##########
hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/hudi/HoodieCreateRecordUtils.scala:
##########
@@ -155,9 +155,20 @@ object HoodieCreateRecordUtils {
             } else {
               avroRecWithoutMeta
             }
-            val hoodieRecord = if (shouldCombine && !orderingFields.isEmpty) {
+            // `shouldCombine` says whether the incoming batch needs 
de-duplicating, which is not the
+            // same question as whether this record needs an ordering value. 
Prepped Spark SQL writes
+            // emit one row per key and so set it false, which used to leave 
the record with no
+            // ordering value on tables that order by event time.
+            // Deletes take the ordering value too. A delete left on the 
default is treated as commit
+            // time ordered by 
BufferedRecordMergerFactory#shouldKeepNewerRecord, so excluding them

Review Comment:
   🤖 nit: this comment points at 
`BufferedRecordMergerFactory#shouldKeepNewerRecord` while the test javadoc 
(line 295 of the test) points at `#deltaMergeDeleteRecord` for the same 
behaviour — could you make both reference the same method so a reader chasing 
the default-means-commit-time rule lands in one place?
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



##########
hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/hudi/HoodieCreateRecordUtils.scala:
##########
@@ -155,9 +155,20 @@ object HoodieCreateRecordUtils {
             } else {
               avroRecWithoutMeta
             }
-            val hoodieRecord = if (shouldCombine && !orderingFields.isEmpty) {
+            // `shouldCombine` says whether the incoming batch needs 
de-duplicating, which is not the
+            // same question as whether this record needs an ordering value. 
Prepped Spark SQL writes
+            // emit one row per key and so set it false, which used to leave 
the record with no
+            // ordering value on tables that order by event time.
+            // Deletes take the ordering value too. A delete left on the 
default is treated as commit
+            // time ordered by 
BufferedRecordMergerFactory#shouldKeepNewerRecord, so excluding them
+            // here would let a stale delete remove a record with a higher 
ordering value, while the
+            // same delete written through a path where `shouldCombine` is 
true would correctly lose.
+            // A null ordering field stays tolerated for a delete, which may 
carry only its key: the
+            // value falls back to the default rather than failing the write.
+            val computeOrderingValue = shouldCombine || requiresOrderingValue
+            val hoodieRecord = if (computeOrderingValue && 
!orderingFields.isEmpty) {
               val orderingVal = getOrderingValue(orderingFields, avroRec, 
hoodieKey.getRecordKey,
-                consistentLogicalTimestampEnabled, requiresOrderingValue)
+                consistentLogicalTimestampEnabled, requiresOrderingValue && 
!isDelete)

Review Comment:
   🤖 The PR description still says deletes are deliberately excluded from the 
widened branch and stay commit-time ordered, but the code (and the comment 
above) now gives deletes a real ordering value too. Could you update the 
description so the semantics change for deletes on event-time tables is visible 
to reviewers?
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to