You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Locale-sensitive case conversions break identifier matching, enum parsing and request signing #9770
String.toLowerCase() and String.toUpperCase() follow the JVM default locale. Under a Turkish or Azeri default, i uppercases to the dotted İ and I lowercases to the dotless ı, so any token that is case-folded before being matched, parsed or signed stops matching what it is compared against.
This started as an identifier-matching bug. With case-sensitive = false, CDC table mapping, computed columns and the Arrow readers all route through StringUtils.toLowerCaseIfNeed, and CdcRecord.fieldNameLowerCase is the record side of the same join, so a source column INDEX stops mapping to schema field index and the column silently nulls out.
Auditing the rest of paimon-api, paimon-common and paimon-core turned up the same conversion in places where it throws rather than mismatching quietly:
CoreOptions.partitionMarkDoneActions() does PartitionMarkDoneAction.valueOf(x.replace('-','_').toUpperCase()). Both success-file and done-partition contain an i, so under Turkish this throws IllegalArgumentException: No enum constant ...PartitionMarkDoneAction.SUCCESS_FİLE.
RowKind.fromShortString("+i") uppercases to +İ, matches no case arm, and throws UnsupportedOperationException.
DistributedLockDialectFactory does JdbcProtocol.valueOf(protocol.toUpperCase()) and loses SQLITE and MARIADB, so JDBC catalog locking cannot resolve its dialect.
OperatingSystem lowercases os.name and then looks for solaris, which becomes solarıs, so the OS is reported as UNKNOWN.
The DLF request signers lowercase header names to build the signature, option key lookups and format identifiers lowercase user-supplied keys, and system table lookup lowercases the table name. All of these compare the result against a fixed ASCII string.
Expected behavior
None of these conversions should depend on the operator's locale: they are all machine-facing, so they should pin Locale.ROOT.
BinaryString.toLowerCase / toUpperCase are already safe: the ASCII path uses Character.toLowerCase and the non-ASCII fallback pins Locale.ROOT, so the SQL upper() / lower() transforms over user data are not affected.
changed the title [-][Bug] Case-insensitive identifier matching breaks under a Turkish default locale[/-][+][Bug] Locale-sensitive case conversions break identifier matching, enum parsing and request signing[/+]on Sep 13, 2026
Activity
[-][Bug] Case-insensitive identifier matching breaks under a Turkish default locale[/-][+][Bug] Locale-sensitive case conversions break identifier matching, enum parsing and request signing[/+]