lanky228 opened a new pull request, #5141:
URL: https://github.com/apache/calcite/pull/5141

   ## What
   
   `NlsString.compareTo()` only compared the decoded string value, ignoring 
`charsetName`, `collation`, and `bytesValue`. This made `compareTo` 
inconsistent with `equals()`/`hashCode()`, which consider all metadata fields.
   
   ## Why It Matters
   
   This violates the Java contract: when `equals() == true`, `compareTo() == 0` 
must also hold. The bug caused `TreeSet` and `TreeMap` to silently collapse 
distinct `NlsString` values that shared the same decoded string but differed in 
charset or collation.
   
   Example: `("hello", "LATIN1", null)` and `("hello", "UTF-8", null)` are not 
equal per `equals()`, but the old `compareTo()` returned 0 — causing a 
`TreeSet` to keep only one of them.
   
   ## Changes
   
   **`NlsString.java`** (+32 -2):
   - After comparing decoded string values (preserving the original collator 
branch), break ties by comparing:
     1. `charsetName` — `Comparator.nullsFirst(String::compareTo)` for null 
safety
     2. `collation` — `SqlCollation` does not implement `Comparable`, so 
`toString()` is used as proxy key
     3. `bytesValue` — `ByteString` implements `Comparable<ByteString>`, using 
`Comparator.naturalOrder()`
   - All comparisons use `Comparator.nullsFirst()` for null-safe handling 
(fields are `@Nullable`)
   - No new helper methods — standard library `Comparator` utilities only
   
   **`UtilTest.java`** (+53):
   - `testNlsStringCompareToConsistency()`: 5 cases verifying 
`compareTo`/`equals` consistency:
     - Same text, different charset → not equal, `compareTo != 0`
     - Same text, different collation → not equal, `compareTo != 0`
     - Identical values → equal, `compareTo == 0`
     - Both null charset → equal, `compareTo == 0`
     - One null, one non-null charset → not equal, `compareTo != 0`
   - `testNlsStringTreeSetRetainsDistinctValues()`: 4 values with same string 
"hello" but different charset — TreeSet must retain all 4 (before fix: 
collapsed to 1)
   
   ## Verification
   
   - `./gradlew :core:compileJava` — BUILD SUCCESSFUL
   - `./gradlew :core:checkstyleMain` — passed
   - `./gradlew :core:test --tests "org.apache.calcite.util.UtilTest"` — 7 
tests passed
   
   ## Note
   
   This is a behavior change: `TreeSet<NlsString>` ordering results may differ 
from before. This is the intended fix — the old behavior was a bug.
   
   ## Jira
   
   [CALCITE-7554](https://issues.apache.org/jira/browse/CALCITE-7554)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to