Liu created FLINK-39195:
---------------------------

             Summary: ObjectPath should implement Comparable
                 Key: FLINK-39195
                 URL: https://issues.apache.org/jira/browse/FLINK-39195
             Project: Flink
          Issue Type: Improvement
          Components: Table SQL / API
            Reporter: Liu


h2. Motivation

ObjectPath is a core value object in Flink's Table/SQL API that represents a 
database name and object (table/view/function) name combo in a catalog. It 
already 
implements equals() and hashCode(), and is widely used as a Map key throughout 
the 
codebase (e.g., GenericInMemoryCatalog has 8 Map<ObjectPath, ...> fields).

However, ObjectPath does not implement Comparable<ObjectPath>, which causes 
issues 
in several scenarios:

1. *Jackson JSON Serialization Failure*: Flink Planner's CompiledPlanSerdeUtil 
   enables SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS (line 110), which 
requires 
   Map keys to implement Comparable. Any object containing Map<ObjectPath, ...> 
fields 
   that goes through compilePlan().toJson() will fail with:
   \{code}
   java.lang.ClassCastException: class 
org.apache.flink.table.catalog.ObjectPath 
   cannot be cast to class java.lang.Comparable
   \{code}

2. *Value Object Completeness*: As a widely-used identifier class, ObjectPath 
has a 
   natural ordering semantic (databaseName + objectName, both Strings). 
Implementing 
   Comparable is a standard practice for value objects in Java (similar to 
java.io.File, 
   java.net.URI, java.nio.file.Path).

3. *Usability*: Users cannot currently use ObjectPath with TreeMap, TreeSet, or 
   Collections.sort(), which limits its utility in scenarios requiring sorted 
output 
   (logging, debugging, deterministic serialization).
h2. Proposed Change

Add Comparable<ObjectPath> to ObjectPath:

{code:java}
@PublicEvolving
public class ObjectPath implements Serializable, Comparable<ObjectPath> {
    // ... existing code unchanged ...

    @Override
    public int compareTo(ObjectPath other) {
        int cmp = this.databaseName.compareTo(other.databaseName);
        if (cmp != 0) {
            return cmp;
        }
        return this.objectName.compareTo(other.objectName);
    }
}
{code}

The comparison uses lexicographic ordering: first by databaseName, then by 
objectName. 
This is consistent with the format returned by getFullName() 
("databaseName.objectName").
h2. Compatibility

* *API Compatible*: Only adds a new interface implementation; no existing 
method 
  signatures are changed.
* *Behavior Compatible*: equals/hashCode behavior is unchanged.
* *Binary Compatible*: Adding a new method does not break existing bytecode.
h2. Impact

* Fixes Jackson serialization failure for any Map<ObjectPath, ...> in the 
Compiled 
  Plan JSON serialization path.
* Enables ObjectPath to be used with TreeMap/TreeSet/sorted collections.
* Zero risk to existing functionality.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to