Conversation
|
|
||
| private static final UTF8String DEFAULT_TRIM_STRING = UTF8String.fromString(" "); | ||
|
|
||
| private static boolean useCollationAwareDefaultTrim(final int collationId) { |
There was a problem hiding this comment.
Document why useCollationAwareDefaultTrim is only isCaseInsensitive.
That helper is the whole policy, and it is not obvious. A short comment should say:
CI/CI_AI ICU collations use primary/secondary strength, so UCA treats many Zs characters as equal to U+0020.
CS ICU stays binary because tertiary strength distinguishes them.
Non-ICU collations are already excluded by isCaseInsensitive.
CS_AI is not a valid trim input type.
Without that, the next change is likely to “fix” it into always-ICU (a UNICODE perf hit) or add isAccentInsensitive (dead for SQL trim).
| @@ -2757,11 +2757,11 @@ private void assertStringTrim(String collationName, String sourceString, String | |||
|
|
|||
There was a problem hiding this comment.
assertStringTrimLeft / assertStringTrimRight still call the old 1-arg exec(src).
The PR updated assertStringTrim to pass collationId when the trim string is the default space, but Left/Right helpers still hit the binary-only overloads. Existing testStringTrimLeft / testStringTrimRight default-space cases therefore do not exercise the new product path. After this lands, those 1-arg methods are a footgun: they look like the public API but no longer match StringTrimLeft.doEval.
| */ | ||
| public final class CollationSupport { | ||
|
|
||
| private static final UTF8String DEFAULT_TRIM_STRING = UTF8String.fromString(" "); |
There was a problem hiding this comment.
Reuse UTF8String.SPACE_UTF8 instead of a new DEFAULT_TRIM_STRING.
Same value, already a public constant on UTF8String.
| collation, "\u200Babc\u200B", "\u200Babc\u200B", "\u200Babc\u200B", "\u200Babc\u200B"); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Test gaps - the Catalyst test only checks NBSP on UNICODE_CI vs UNICODE. Worth adding, still in checkEvaluation:
- unary vs StringTrim(src, Literal(" ")) at the expression level (the Java suite does this, Catalyst does not)
- mixed padding, e.g. "\u00A0 abc \u00A0" → "abc"
- a string of only NBSP → empty
- en_CI / other locale CI names are covered by the helper, but only UNICODE_* names are tested
| return CollationFactory.isCaseInsensitive(collationId); | ||
| } | ||
|
|
||
| /** |
There was a problem hiding this comment.
Nit: unary exec(src, collationId) could delegate to exec(src, SPACE_UTF8, collationId) for CI instead of calling execICU directly. Same result today; one dispatcher if trim collation policy changes.
| assertDefaultStringTrims( | ||
| collation, "\u200Babc\u200B", "\u200Babc\u200B", "\u200Babc\u200B", "\u200Babc\u200B"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Add the JIRA reproduction as a SQL test.
collations-padding-trim.sql already covers two-arg TRIM/LTRIM/RTRIM and has no unary TRIM(col COLLATE UNICODE_CI) case. A golden SQL test for
trim(concat(chr(160), 'abc', chr(160)) COLLATE UNICODE_CI)
versus the explicit ' ' form is what will catch a parser/analysis/codegen miss that the Java helper tests will not.
What changes were proposed in this pull request?
This PR makes unary
trim,ltrim, andrtrimuse collation-aware matching forcase-insensitive ICU collations.
The expressions now pass their collation ID to
CollationSupport. Interpreted executiondispatches affected collations to the existing ICU implementation with an ASCII-space trim
string. Code generation selects either the ICU or binary implementation while generating code,
avoiding per-row collation dispatch in generated code.
Binary, lowercase, and case-sensitive ICU collations continue to use the existing binary
implementation.
Why are the changes needed?
Unary trimming currently removes only literal ASCII space, regardless of the input collation.
The explicit two-argument forms use ICU matching for ICU-collated operands. As a result, the
forms disagree under case-insensitive ICU collations, where Unicode space separators such as
NBSP compare as equivalent to ASCII space.
For example, these expressions currently produce different results:
The unary form preserves both NBSP characters while the explicit form returns
abc. Both formsshould apply the same default trim string with the same collation semantics.
Does this PR introduce any user-facing change?
Yes. Unary
trim,ltrim, andrtrimnow remove characters that compare as equivalent to thedefault ASCII-space trim string under case-insensitive ICU collations, matching their explicit
two-argument forms. Behavior is unchanged for other collations.
How was this patch tested?
Added tests covering:
Zs) character.UNICODE_CI,UNICODE_CI_AI, and their_RTRIMvariants.Ran locally:
Both passed.
CollationSupportSuite#testDefaultStringTrimsUseCollationis a JUnit test, so it isselected with a method glob rather than ScalaTest
-z. The Catalyst testdefault trim uses collation-aware space matchingcovers interpreted and generated code.The fork's Build and test and Report test results workflows are enabled for CI validation.
Was this patch authored or co-authored using generative AI tooling?
Generated-by: Cursor Agent (Auto, 2026-09-18)