This is an automated email from the ASF dual-hosted git repository.

englefly pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 917c9995b7d [fix](constraint) Fix NPE in PrimaryKeyConstraint when 
loading old metadata (#61342)
917c9995b7d is described below

commit 917c9995b7dfd38e42025b5695288279e28647e1
Author: minghong <[email protected]>
AuthorDate: Tue Mar 17 11:46:11 2026 +0800

    [fix](constraint) Fix NPE in PrimaryKeyConstraint when loading old metadata 
(#61342)
    
    ### What problem does this PR solve?
    
    
    When FE starts with -r (metadata_failure_recovery) or without a
    checkpoint image, it replays all journal logs from the beginning. Old
    journal entries may contain PrimaryKeyConstraint objects that were
    serialized before the fields foreignTables, foreignTableNameStrs, or
    foreignTableInfos were added to the class.
    
    Gson uses Unsafe to instantiate objects during deserialization,
    bypassing the constructor and its field initializers. If a field is
    absent from the JSON, Gson leaves it as null rather than using the
    declared initializer (e.g. `= new HashSet<>()`). Calling .isEmpty() or
    any method on a null collection then throws a NullPointerException.
    
    Fix: remove `final` from the three collection fields (so they can be
    reassigned in gsonPostProcess) and add null-guards at the top of
    gsonPostProcess() to initialize them to empty collections when absent.
    
    Impact on -r mode: when FE is started with --metadata_failure_recovery
    it replays every journal from journal #1, encountering the oldest
    serialized PrimaryKeyConstraint objects. Without this fix, FE always
    crashes during -r recovery if any PrimaryKeyConstraint was persisted
    before these fields existed.
---
 .../doris/catalog/constraint/PrimaryKeyConstraint.java    | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/constraint/PrimaryKeyConstraint.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/constraint/PrimaryKeyConstraint.java
index 77a279c4f7f..e6569f733d2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/constraint/PrimaryKeyConstraint.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/constraint/PrimaryKeyConstraint.java
@@ -40,14 +40,14 @@ public class PrimaryKeyConstraint extends Constraint 
implements GsonPostProcessa
 
     // record the foreign table which references the primary key
     @SerializedName(value = "ft")
-    private final Set<TableIdentifier> foreignTables = new HashSet<>();
+    private Set<TableIdentifier> foreignTables = new HashSet<>();
 
     // qualified name strings kept for backward-compatible deserialization
     @SerializedName(value = "ftn")
-    private final Set<String> foreignTableNameStrs = new HashSet<>();
+    private Set<String> foreignTableNameStrs = new HashSet<>();
 
     @SerializedName(value = "ftni")
-    private final List<TableNameInfo> foreignTableInfos = new ArrayList<>();
+    private List<TableNameInfo> foreignTableInfos = new ArrayList<>();
 
     public PrimaryKeyConstraint(String name, Set<String> columns) {
         super(ConstraintType.PRIMARY_KEY, name);
@@ -116,6 +116,15 @@ public class PrimaryKeyConstraint extends Constraint 
implements GsonPostProcessa
 
     @Override
     public void gsonPostProcess() throws IOException {
+        if (foreignTables == null) {
+            foreignTables = new HashSet<>();
+        }
+        if (foreignTableNameStrs == null) {
+            foreignTableNameStrs = new HashSet<>();
+        }
+        if (foreignTableInfos == null) {
+            foreignTableInfos = new ArrayList<>();
+        }
         if (foreignTableInfos.isEmpty() && !foreignTableNameStrs.isEmpty()) {
             for (String qualifiedName : foreignTableNameStrs) {
                 foreignTableInfos.add(new TableNameInfo(qualifiedName));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to