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

Function generic_string_substr

datafusion/functions/src/unicode/substr.rs:346–409  ·  view source on GitHub ↗
(
    string_array: &GenericStringArray<T>,
    args: &[ArrayRef],
)

Source from the content-addressed store, hash-verified

344
345#[expect(clippy::needless_range_loop)]
346fn generic_string_substr<T: OffsetSizeTrait>(
347 string_array: &GenericStringArray<T>,
348 args: &[ArrayRef],
349) -> Result<ArrayRef> {
350 // We'd like to return a StringViewArray that points into the input string
351 // array's values buffer. Since the Arrow spec defines StringView offsets
352 // as i32, we can't use this approach when the values buffer is >2GB, so
353 // fallback to copying.
354 if !values_fit_in_i32(string_array) {
355 return generic_string_substr_copy(string_array, args);
356 }
357
358 let start_array = as_int64_array(&args[0])?;
359 let count_array_opt = args.get(1).map(|a| as_int64_array(a)).transpose()?;
360
361 let is_ascii = enable_ascii_fast_path(&string_array, start_array, count_array_opt);
362 let offsets = string_array.value_offsets();
363 let mut views_buf = Vec::with_capacity(string_array.len());
364 let mut has_out_of_line = false;
365
366 // Combine null bitmaps from all inputs in bulk.
367 let nulls = NullBuffer::union_many([
368 string_array.nulls(),
369 start_array.nulls(),
370 count_array_opt.and_then(|a| a.nulls()),
371 ]);
372
373 for i in 0..string_array.len() {
374 if nulls.as_ref().is_some_and(|n| n.is_null(i)) {
375 views_buf.push(0);
376 continue;
377 }
378
379 let string = string_array.value(i);
380 let source_offset = offsets[i].as_usize();
381 let start = start_array.value(i);
382 let count = count_array_opt.map(|a| a.value(i));
383
384 let (byte_start, byte_end) = get_true_start_end(string, start, count, is_ascii)?;
385 has_out_of_line |= append_view_from_buffer(
386 &mut views_buf,
387 &string[byte_start..byte_end],
388 source_offset + byte_start,
389 );
390 }
391
392 let views_buf = ScalarBuffer::from(views_buf);
393
394 // If all result strings are stored inline, we don't need to retain the
395 // input string array.
396 let data_buffers = if has_out_of_line {
397 vec![string_array.values().clone()]
398 } else {
399 vec![]
400 };
401
402 // Safety:
403 // (1) The blocks of the given views are all provided

Callers 1

substrFunction · 0.85

Calls 15

as_int64_arrayFunction · 0.85
enable_ascii_fast_pathFunction · 0.85
get_true_start_endFunction · 0.85
append_view_from_bufferFunction · 0.85
newFunction · 0.85
value_offsetsMethod · 0.80
values_fit_in_i32Function · 0.70
mapMethod · 0.45
getMethod · 0.45
lenMethod · 0.45
nullsMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…