This is an automated email from the ASF dual-hosted git repository.
danny0405 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 1ec3e338e437 [MINOR] NullPointerException when reading action state of
old archived timelines (#13579)
1ec3e338e437 is described below
commit 1ec3e338e4377c37ff6854eecf3ba22e0992055c
Author: Tim Brown <[email protected]>
AuthorDate: Sat Jul 19 06:15:46 2025 -0400
[MINOR] NullPointerException when reading action state of old archived
timelines (#13579)
---
.../timeline/versioning/v1/ArchivedTimelineV1.java | 3 ++-
.../table/timeline/TestArchivedTimelineV1.java | 15 +++++++++++++
.../.hoodie/archived/.commits_.archive.1_1-0-1 | Bin 0 -> 15136 bytes
.../archived_timeline/.hoodie/hoodie.properties | 24 +++++++++++++++++++++
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git
a/hudi-common/src/main/java/org/apache/hudi/common/table/timeline/versioning/v1/ArchivedTimelineV1.java
b/hudi-common/src/main/java/org/apache/hudi/common/table/timeline/versioning/v1/ArchivedTimelineV1.java
index 0d4d4d624149..7b1101e6f68d 100644
---
a/hudi-common/src/main/java/org/apache/hudi/common/table/timeline/versioning/v1/ArchivedTimelineV1.java
+++
b/hudi-common/src/main/java/org/apache/hudi/common/table/timeline/versioning/v1/ArchivedTimelineV1.java
@@ -271,7 +271,8 @@ public class ArchivedTimelineV1 extends BaseTimelineV1
implements HoodieArchived
TimeRangeFilter timeRangeFilter) {
final String action = record.get(ACTION_TYPE_KEY).toString();
final String stateTransitionTime = (String)
record.get(STATE_TRANSITION_TIME);
- final HoodieInstant hoodieInstant = new
HoodieInstant(HoodieInstant.State.valueOf(record.get(ACTION_STATE).toString()),
action,
+ final HoodieInstant.State actionState =
Option.ofNullable(record.get(ACTION_STATE)).map(state ->
HoodieInstant.State.valueOf(state.toString())).orElse(HoodieInstant.State.COMPLETED);
+ final HoodieInstant hoodieInstant = new HoodieInstant(actionState, action,
instantTime, stateTransitionTime,
InstantComparatorV1.REQUESTED_TIME_BASED_COMPARATOR);
if (timeRangeFilter != null &&
!timeRangeFilter.isInRange(hoodieInstant.requestedTime())) {
return Option.empty();
diff --git
a/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/timeline/TestArchivedTimelineV1.java
b/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/timeline/TestArchivedTimelineV1.java
index be4112ee9dec..69cd03daf378 100644
---
a/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/timeline/TestArchivedTimelineV1.java
+++
b/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/timeline/TestArchivedTimelineV1.java
@@ -35,6 +35,7 @@ import org.apache.hudi.common.model.HoodieCommitMetadata;
import org.apache.hudi.common.model.HoodieRecord;
import org.apache.hudi.common.model.HoodieRollingStatMetadata;
import org.apache.hudi.common.model.WriteOperationType;
+import org.apache.hudi.common.table.HoodieTableMetaClient;
import org.apache.hudi.common.table.log.HoodieLogFormat;
import org.apache.hudi.common.table.log.HoodieLogFormat.Writer;
import org.apache.hudi.common.table.log.block.HoodieAvroDataBlock;
@@ -71,6 +72,7 @@ import java.util.stream.Stream;
import static
org.apache.hudi.common.table.timeline.HoodieInstant.State.COMPLETED;
import static
org.apache.hudi.common.table.timeline.HoodieInstant.State.INFLIGHT;
import static
org.apache.hudi.common.table.timeline.HoodieInstant.State.REQUESTED;
+import static
org.apache.hudi.common.testutils.HoodieTestUtils.getDefaultStorageConf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -419,6 +421,19 @@ public class TestArchivedTimelineV1 extends
HoodieCommonTestHarness {
assertEquals(instants, timeline.getInstants());
}
+ @Test
+ void readLegacyArchivedTimelineWithNullFields() {
+ String samplePath =
this.getClass().getClassLoader().getResource("archived_timeline").getPath();
+ metaClient = HoodieTableMetaClient.builder()
+ .setBasePath(samplePath)
+ .setConf(getDefaultStorageConf())
+ .setLoadActiveTimelineOnLoad(false)
+ .build();
+ HoodieArchivedTimeline timeline = new ArchivedTimelineV1(metaClient);
+ timeline.loadCompletedInstantDetailsInMemory();
+ assertEquals(3, timeline.getInstants().size());
+ }
+
/**
* Validate whether the instants of given timestamps of the hudi archived
timeline are loaded to memory or not.
* @param hoodieArchivedTimeline archived timeline to test against
diff --git
a/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/archived/.commits_.archive.1_1-0-1
b/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/archived/.commits_.archive.1_1-0-1
new file mode 100644
index 000000000000..3485b0ff5941
Binary files /dev/null and
b/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/archived/.commits_.archive.1_1-0-1
differ
diff --git
a/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/hoodie.properties
b/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/hoodie.properties
new file mode 100644
index 000000000000..9d3ecdb5d407
--- /dev/null
+++
b/hudi-hadoop-common/src/test/resources/archived_timeline/.hoodie/hoodie.properties
@@ -0,0 +1,24 @@
+# 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.
+
+hoodie.table.name=raw_trips
+hoodie.archivelog.folder=archived
+hoodie.table.type=COPY_ON_WRITE
+hoodie.table.version=6
+hoodie.table.partition.fields=some_nonexistent_field
+hoodie.timeline.layout.version=1
+hoodie.datasource.write.drop.partition.columns=false
+hoodie.table.checksum=3360473891