MCPcopy Create free account
hub / github.com/apache/datafusion / string_to_array_scalar_args

Function string_to_array_scalar_args

datafusion/functions-nested/src/string.rs:335–415  ·  view source on GitHub ↗

Optimized `string_to_array` implementation for the common case where delimiter and null_value are scalar values.

(
    string_array: &StringArrType,
    delimiter: Option<&str>,
    null_value: Option<&str>,
    string_builder: StringBuilderType,
)

Source from the content-addressed store, hash-verified

333/// Optimized `string_to_array` implementation for the common case where
334/// delimiter and null_value are scalar values.
335fn string_to_array_scalar_args<'a, StringArrType, StringBuilderType>(
336 string_array: &StringArrType,
337 delimiter: Option<&str>,
338 null_value: Option<&str>,
339 string_builder: StringBuilderType,
340) -> Result<ArrayRef>
341where
342 StringArrType: StringArrayType<'a>,
343 StringBuilderType: StringArrayBuilderType,
344{
345 let mut list_builder = ListBuilder::new(string_builder);
346
347 match delimiter {
348 Some("") => {
349 // Empty delimiter: each non-empty string becomes a single-element list.
350 // Empty strings produce an empty array (PostgreSQL compat).
351 for i in 0..string_array.len() {
352 if string_array.is_null(i) {
353 list_builder.append(false);
354 continue;
355 }
356 let string = string_array.value(i);
357 if !string.is_empty() {
358 append_part(list_builder.values(), string, null_value);
359 }
360 list_builder.append(true);
361 }
362 }
363 Some(delimiter) => {
364 // Rather than using `str::split`, do the split ourselves using
365 // `memmem::Finder`. This allows pre-compiling the delimiter search
366 // pattern once and reusing it for all rows.
367 let finder = memchr::memmem::Finder::new(delimiter.as_bytes());
368 let delim_len = delimiter.len();
369
370 for i in 0..string_array.len() {
371 if string_array.is_null(i) {
372 list_builder.append(false);
373 continue;
374 }
375 let string = string_array.value(i);
376 if !string.is_empty() {
377 let bytes = string.as_bytes();
378 let mut start = 0;
379 for pos in finder.find_iter(bytes) {
380 append_part(
381 list_builder.values(),
382 &string[start..pos],
383 null_value,
384 );
385 start = pos + delim_len;
386 }
387 // Trailing part after last delimiter (or entire string if no
388 // delimiter was found).
389 append_part(list_builder.values(), &string[start..], null_value);
390 }
391 list_builder.append(true);
392 }

Callers 1

invoke_with_argsMethod · 0.85

Calls 9

newFunction · 0.85
append_partFunction · 0.85
lenMethod · 0.45
is_nullMethod · 0.45
appendMethod · 0.45
valueMethod · 0.45
is_emptyMethod · 0.45
valuesMethod · 0.45
finishMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…