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]