Skip to content

GH-35815: [C++] Provided dictionary support for utf8_trim - #51134

Open
NathanChung4 wants to merge 2 commits into
apache:mainfrom
NathanChung4:gh35815-utf8-trim-dictionary
Open

GH-35815: [C++] Provided dictionary support for utf8_trim#51134
NathanChung4 wants to merge 2 commits into
apache:mainfrom
NathanChung4:gh35815-utf8-trim-dictionary

Conversation

@NathanChung4

Copy link
Copy Markdown
Contributor

Rationale for this change

utf8_trim, utf8_ltrim, and utf8_rtrim error out on dictionary encoded string arrays instead of working.

What changes are included in this PR?

A new ScalarFunction subclass with a DispatchBest mechanism that unwraps a dictionary
to its value type and retries dispatch, and the three trim functions (utf8_trim,
utf8_ltrim, utf8_rtrim) switched over to use it instead of the default.

Are these changes tested?

These changes are tested. arrow-compute-scalar-type-test (253 tests, including the
new one) passed, and I ran the entire arrow::compute test suite (15 test binaries)
to make sure nothing else broke. pre-commit (C++ Format + C++ Lint) came back clean.

Are there any user-facing changes?

Yes. The three trim functions now accept dictionary encoded string arrays instead
of raising NotImplemented.

AI Disclosure

Claude helped and guided me through most of the work: it helped trace the dispatch
mechanism, identified the existing pattern to follow (from scalar_compare.cc), wrote
the implementation and the added test case, and ran the builds and test suites. Claude
also walked me through the mechanism until I understood it. I decided to scope this
to just the three trim functions rather than the whole file, reviewed the diff, and
wrote the commit message and this PR description myself.

What was broken: utf8_trim/utf8_ltrim/utf8_rtrim errored out on dictionary
encoded string input instead of working because the functions only had
kernels that registered for plain and not for dictionary so the dispatch
didn't have anywhere to go. My fix was to add a small ScalarFunction subclass
that unwraps a dictionary to its value type and tries again if no exact type
kernel matches. I registered the three trim functions with this subclass
instead of the default one. To test I added a dictionary input case to the
existing TrimUTF8 test.
@NathanChung4
NathanChung4 requested a review from pitrou as a code owner September 2, 2026 05:07
Copilot AI lite review requested due to automatic review settings September 2, 2026 05:07
@github-actions github-actions Bot added the awaiting review Awaiting review label Sep 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new behavior for dictionary inputs is only partially covered by tests (missing ltrim/rtrim and the issue-reported int64 dictionary indices).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds dictionary-encoded input support for the UTF-8 trim compute functions by introducing a custom ScalarFunction dispatch path that unwraps dictionary types to their value type, allowing existing string kernels to run after implicit decoding/casting.

Changes:

  • Introduce UnaryStringWithDictionaryFunction with a DispatchBest override that retries dispatch after EnsureDictionaryDecoded.
  • Switch utf8_trim, utf8_ltrim, and utf8_rtrim to use the new function type via MakeUnaryStringBatchKernelWithState.
  • Add a new test exercising dictionary input for utf8_trim.
File summaries
File Description
cpp/src/arrow/compute/kernels/scalar_string_utf8.cc Adds a ScalarFunction subclass to unwrap dictionary inputs during dispatch and applies it to UTF-8 trim functions.
cpp/src/arrow/compute/kernels/scalar_string_internal.h Generalizes MakeUnaryStringBatchKernelWithState to allow constructing a custom ScalarFunction subclass.
cpp/src/arrow/compute/kernels/scalar_string_test.cc Adds a regression test for dictionary input support in utf8_trim.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +2474 to +2477
this->CheckUnary("utf8_trim",
ArrayFromJSON(dictionary(int32(), this->type()),
R"(["azȺz矢ba", null, "bab", "zȺz"])"),
this->type(), R"(["zȺz矢", null, "", "zȺz"])", &options);
Responding to Copilot's automated review on PR apache#51134. I added ltrim/rtrim
dictionary cases and switched all three to int64 indices. Verified through
arrow-compute-scalar-type-test with 253/253 tests still passing and the
pre-commit being clean.
Copilot AI review requested due to automatic review settings September 2, 2026 05:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The dispatch change follows an established pattern (EnsureDictionaryDecoded + redispatch) and is covered by new tests for dictionary-encoded inputs.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants