Skip to content

perf: opt substr into make_scalar_function dict fast path - #25874

Open
Rich-T-kid wants to merge 1 commit into
apache:mainfrom
Rich-T-kid:rich-T-kid/substr-dict-encoding-preservation
Open

Rich-T-kid wants to merge 1 commit into
apache:mainfrom
Rich-T-kid:rich-T-kid/substr-dict-encoding-preservation

Conversation

@Rich-T-kid

@Rich-T-kid Rich-T-kid commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #26170.

Rationale for this change

substr(dict_col, 1, 3) was casting the dict to its value type before running. For scalar start/length we can just substr the unique values and reuse the keys.

What changes are included in this PR?

Keep the dict wrapper through coercion (EncodingPreservation::dictionary()) and add a fast path that runs substr on dict.values(), then re-wraps via with_values(..). Per-row start/length still falls back to materializing the dict.

Are these changes tested?

Unit test covers the fast path. SLT regression (dictionary_utf8.slt) asserts arrow_typeof stays Dictionary(..) for scalar start/length.

Are there any user-facing changes?

No.

@github-actions github-actions Bot added the functions Changes to functions implementation label Sep 29, 2026
@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/substr-dict-encoding-preservation branch from 71ad106 to 0f9e4cd Compare September 29, 2026 13:26
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

will wait until we can enable the dictionary flag to run the benchmarks. This should have a significant affect on query performance

@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/substr-dict-encoding-preservation branch from 0f9e4cd to 497b608 Compare October 9, 2026 20:22
@github-actions github-actions Bot added the sqllogictest SQL Logic Tests (.slt) label Oct 9, 2026
@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/substr-dict-encoding-preservation branch 2 times, most recently from 6318fb4 to d172c89 Compare October 9, 2026 20:43
For scalar start/length, substr can run over the dict's unique values
and reuse the keys instead of casting the dict to its value type.

- Signature uses EncodingPreservation::dictionary() so coercion keeps
  the dict wrapper.
- Fast path in invoke_with_args runs substr on dict.values() and
  rewraps via with_values(..).
- Per-row start/length still materializes the dict.
- return_field_from_args declares Dictionary for the scalar case and
  the value type for the per-row case so the planner's expected schema
  matches runtime output.

Closes apache#26170
@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/substr-dict-encoding-preservation branch from d172c89 to c11a73c Compare October 9, 2026 20:50
@Rich-T-kid
Rich-T-kid marked this pull request as ready for review October 9, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

functions Changes to functions implementation sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

substr on Dictionary(_, Utf8) inserts implicit CAST to Utf8View

1 participant