5656import java .io .ByteArrayOutputStream ;
5757import java .io .IOException ;
5858import java .nio .file .Path ;
59+ import java .util .ArrayList ;
5960import java .util .Arrays ;
6061import java .util .Collections ;
6162import java .util .HashMap ;
63+ import java .util .List ;
6264import java .util .Map ;
6365import java .util .Set ;
6466import java .util .stream .Stream ;
@@ -117,6 +119,7 @@ public void setUp() throws IOException {
117119 when (table .getMetaClient ()).thenReturn (metaClient );
118120 when (metaClient .getTableConfig ()).thenReturn (tableConfig );
119121 when (config .autoUpgrade ()).thenReturn (true );
122+ when (config .getPayloadClass ()).thenReturn (null );
120123
121124 // Setup common mocks
122125 when (upgradeDowngradeHelper .getTable (config , context )).thenReturn (table );
@@ -125,6 +128,7 @@ public void setUp() throws IOException {
125128 when (metaClient .getStorage ()).thenReturn (storage );
126129 when (tableConfig .getTableVersion ()).thenReturn (HoodieTableVersion .EIGHT );
127130 when (tableConfig .getOrderingFieldsStr ()).thenReturn (Option .empty ());
131+ when (tableConfig .getPayloadClassIfPresent ()).thenReturn (Option .empty ());
128132
129133 // Use a temp file for index definition path
130134 indexDefPath = new StoragePath (tempDir .resolve ("index.json" ).toString ());
@@ -143,81 +147,55 @@ public void setUp() throws IOException {
143147 }
144148
145149 static Stream <Arguments > payloadClassTestCases () {
146- return Stream .of (
147- Arguments .of (
148- DefaultHoodieRecordPayload .class .getName (),
149- "" ,
150- null ,
151- null ,
152- "DefaultHoodieRecordPayload"
153- ),
154- Arguments .of (
155- EventTimeAvroPayload .class .getName (),
156- "" ,
157- EVENT_TIME_ORDERING .name (),
158- null ,
159- "EventTimeAvroPayload"
160- ),
161- Arguments .of (
162- OverwriteWithLatestAvroPayload .class .getName (),
163- "" ,
164- null ,
165- null ,
166- "OverwriteWithLatestAvroPayload"
167- ),
168- Arguments .of (
169- AWSDmsAvroPayload .class .getName (),
170- RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=Op,"
171- + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=D" , // mergeProperties
172- COMMIT_TIME_ORDERING .name (),
173- null ,
174- "AWSDmsAvroPayload"
175- ),
176- Arguments .of (
177- PostgresDebeziumAvroPayload .class .getName (),
178- RECORD_MERGE_PROPERTY_PREFIX + PARTIAL_UPDATE_UNAVAILABLE_VALUE + "=" + DEBEZIUM_UNAVAILABLE_VALUE + ","
179- + RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=_change_operation_type,"
180- + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=d" ,
181- EVENT_TIME_ORDERING .name (),
182- FILL_UNAVAILABLE .name (),
183- "PostgresDebeziumAvroPayload"
184- ),
185- Arguments .of (
186- PartialUpdateAvroPayload .class .getName (),
187- "" ,
188- EVENT_TIME_ORDERING .name (),
189- PartialUpdateMode .IGNORE_DEFAULTS .name (),
190- "PartialUpdateAvroPayload"
191- ),
192- Arguments .of (
193- MySqlDebeziumAvroPayload .class .getName (),
194- RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=_change_operation_type,"
195- + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=d" ,
196- EVENT_TIME_ORDERING .name (),
197- null ,
198- "MySqlDebeziumAvroPayload"
199- ),
200- Arguments .of (
201- OverwriteNonDefaultsWithLatestAvroPayload .class .getName (),
202- "" ,
203- COMMIT_TIME_ORDERING .name (),
204- PartialUpdateMode .IGNORE_DEFAULTS .name (),
205- "OverwriteNonDefaultsWithLatestAvroPayload"
206- )
207- );
150+ List <Arguments > arguments = new ArrayList <>();
151+ arguments .addAll (getArguments (DefaultHoodieRecordPayload .class .getName (), "" ,
152+ null , null , "DefaultHoodieRecordPayload" ));
153+ arguments .addAll (getArguments (EventTimeAvroPayload .class .getName (), "" ,
154+ EVENT_TIME_ORDERING .name (), null , "EventTimeAvroPayload" ));
155+ arguments .addAll (getArguments (OverwriteWithLatestAvroPayload .class .getName (), "" ,
156+ null , null , "OverwriteWithLatestAvroPayload" ));
157+ arguments .addAll (getArguments (AWSDmsAvroPayload .class .getName (), RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=Op,"
158+ + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=D" , // mergeProperties
159+ COMMIT_TIME_ORDERING .name (), null , "AWSDmsAvroPayload" ));
160+ arguments .addAll (getArguments (PostgresDebeziumAvroPayload .class .getName (), RECORD_MERGE_PROPERTY_PREFIX + PARTIAL_UPDATE_UNAVAILABLE_VALUE + "=" + DEBEZIUM_UNAVAILABLE_VALUE + ","
161+ + RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=_change_operation_type,"
162+ + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=d" ,
163+ EVENT_TIME_ORDERING .name (), FILL_UNAVAILABLE .name (), "PostgresDebeziumAvroPayload" ));
164+ arguments .addAll (getArguments (PartialUpdateAvroPayload .class .getName (), "" ,
165+ EVENT_TIME_ORDERING .name (), PartialUpdateMode .IGNORE_DEFAULTS .name (), "PartialUpdateAvroPayload" ));
166+ arguments .addAll (getArguments (MySqlDebeziumAvroPayload .class .getName (), RECORD_MERGE_PROPERTY_PREFIX + DELETE_KEY + "=_change_operation_type,"
167+ + RECORD_MERGE_PROPERTY_PREFIX + DELETE_MARKER + "=d" ,
168+ EVENT_TIME_ORDERING .name (), null , "MySqlDebeziumAvroPayload" ));
169+ arguments .addAll (getArguments (OverwriteNonDefaultsWithLatestAvroPayload .class .getName (), "" ,
170+ COMMIT_TIME_ORDERING .name (), PartialUpdateMode .IGNORE_DEFAULTS .name (), "OverwriteNonDefaultsWithLatestAvroPayload" ));
171+ return arguments .stream ();
172+ }
173+
174+ private static List <Arguments > getArguments (String payloadClassName , String expectedMergeProperties ,
175+ String expectedRecordMergeMode , String expectedPartialUpdateMode ,
176+ String testName ) {
177+ return Arrays .asList (
178+ Arguments .of (payloadClassName , expectedMergeProperties ,
179+ expectedRecordMergeMode , expectedPartialUpdateMode , testName , true ),
180+ Arguments .of (payloadClassName , expectedMergeProperties ,
181+ expectedRecordMergeMode , expectedPartialUpdateMode , testName , false ));
208182 }
209183
210184 @ ParameterizedTest (name = "testUpgradeWith{4}" )
211185 @ MethodSource ("payloadClassTestCases" )
212186 void testUpgradeWithPayloadClass (String payloadClassName , String expectedMergeProperties ,
213187 String expectedRecordMergeMode , String expectedPartialUpdateMode ,
214- String testName ) {
188+ String testName , boolean isPayloadClassConfiguredInTableConfig ) {
215189 try (org .mockito .MockedStatic <UpgradeDowngradeUtils > utilities =
216190 org .mockito .Mockito .mockStatic (UpgradeDowngradeUtils .class )) {
217191 utilities .when (() -> UpgradeDowngradeUtils .rollbackFailedWritesAndCompact (
218192 any (), any (), any (), any (), anyBoolean (), any ()))
219193 .thenAnswer (invocation -> null );
220- when (tableConfig .getPayloadClass ()).thenReturn (payloadClassName );
194+ if (isPayloadClassConfiguredInTableConfig ) {
195+ when (tableConfig .getPayloadClassIfPresent ()).thenReturn (Option .ofNullable (payloadClassName ));
196+ } else {
197+ when (config .getPayloadClass ()).thenReturn (payloadClassName );
198+ }
221199 when (tableConfig .getTableType ()).thenReturn (HoodieTableType .MERGE_ON_READ );
222200 when (tableConfig .getRecordMergeStrategyId ()).thenReturn (HoodieRecordMerger .CUSTOM_MERGE_STRATEGY_UUID );
223201 when (metaClient .getIndexMetadata ()).thenReturn (Option .empty ());
@@ -301,6 +279,7 @@ private void assertPayloadClassChange(Map<ConfigProperty, String> propertiesToAd
301279 if (payloadClass .equals (MySqlDebeziumAvroPayload .class .getName ())) {
302280 assertTrue (propertiesToAdd .containsKey (HoodieTableConfig .ORDERING_FIELDS ));
303281 assertEquals (FLATTENED_FILE_COL_NAME + "," + FLATTENED_POS_COL_NAME , propertiesToAdd .get (HoodieTableConfig .ORDERING_FIELDS ));
282+ assertTrue (propertiesToRemove .contains (HoodieTableConfig .PRECOMBINE_FIELD ));
304283 } else if (payloadClass .equals (PostgresDebeziumAvroPayload .class .getName ())) {
305284 assertEquals (FLATTENED_LSN_COL_NAME , propertiesToAdd .get (HoodieTableConfig .ORDERING_FIELDS ));
306285 }
0 commit comments