@@ -22,6 +22,7 @@ import org.apache.hudi.DataSourceOptionsHelper.allAlternatives
2222import org .apache .hudi .DataSourceWriteOptions ._
2323import org .apache .hudi .common .config .{DFSPropertiesConfiguration , HoodieCommonConfig , HoodieConfig , TypedProperties }
2424import org .apache .hudi .common .config .HoodieMetadataConfig .ENABLE
25+ import org .apache .hudi .common .config .RecordMergeMode .CUSTOM
2526import org .apache .hudi .common .model .{DefaultHoodieRecordPayload , HoodieRecord , OverwriteWithLatestAvroPayload , WriteOperationType }
2627import org .apache .hudi .common .table .{HoodieTableConfig , HoodieTableVersion }
2728import org .apache .hudi .common .util .StringUtils
@@ -173,15 +174,15 @@ object HoodieWriterUtils {
173174 || key.equals(RECORD_MERGE_MODE .key())
174175 || key.equals(RECORD_MERGE_STRATEGY_ID .key())))
175176
176- ignoreConfig = ignoreConfig || (key.equals(PAYLOAD_CLASS_NAME .key()) && shouldIgnorePayloadValidation(value, params, tableConfig))
177+ ignoreConfig = ignoreConfig || (key.equals(PAYLOAD_CLASS_NAME .key()) && shouldIgnorePayloadValidation(value, tableConfig))
177178 // If hoodie.database.name is empty, ignore validation.
178179 ignoreConfig = ignoreConfig || (key.equals(HoodieTableConfig .DATABASE_NAME .key()) && isNullOrEmpty(getStringFromTableConfigWithAlternatives(tableConfig, key)))
179180 ignoreConfig
180181 }
181182
182- def shouldIgnorePayloadValidation (value : String , params : Map [ String , String ] , tableConfig : HoodieConfig ): Boolean = {
183+ def shouldIgnorePayloadValidation (incomingPayloadClass : String , tableConfig : HoodieConfig ): Boolean = {
183184 // don't validate the payload only in the case that insert into is using fallback to some legacy configs
184- val ignoreConfig = value .equals(VALIDATE_DUPLICATE_KEY_PAYLOAD_CLASS_NAME )
185+ val ignoreConfig = incomingPayloadClass .equals(VALIDATE_DUPLICATE_KEY_PAYLOAD_CLASS_NAME )
185186 if (ignoreConfig) {
186187 ignoreConfig
187188 } else {
@@ -201,10 +202,18 @@ object HoodieWriterUtils {
201202 HoodieTableVersion .current()
202203 }
203204
205+ val recordMergeMode = tableConfig.getStringOrDefault(HoodieTableConfig .RECORD_MERGE_MODE .key(), " " )
204206 if (tableVersion == HoodieTableVersion .EIGHT && initTableVersion.lesserThan(HoodieTableVersion .EIGHT )
205- && value .equals(classOf [OverwriteWithLatestAvroPayload ].getName)
207+ && incomingPayloadClass .equals(classOf [OverwriteWithLatestAvroPayload ].getName)
206208 && tableConfig.getString(HoodieTableConfig .PAYLOAD_CLASS_NAME .key()).equals(classOf [DefaultHoodieRecordPayload ].getName)) {
207209 true
210+ } else if (tableVersion.greaterThanOrEquals(HoodieTableVersion .NINE ) && ! recordMergeMode.equals(CUSTOM .name)) {
211+ // When table version >= v9, if the merge mode is not CUSTOM, we can safely skip payload class check
212+ // since the payload class is ignored during these writes. Meanwhile, we should give a warning about this behavior.
213+ if (! StringUtils .isNullOrEmpty(incomingPayloadClass)) {
214+ log.warn(s " Payload class ' $incomingPayloadClass' is ignored since merge behavior is determined by merge mode: $recordMergeMode" )
215+ }
216+ true
208217 } else {
209218 ignoreConfig
210219 }
0 commit comments