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,
)
| 333 | /// Optimized `string_to_array` implementation for the common case where |
| 334 | /// delimiter and null_value are scalar values. |
| 335 | fn 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> |
| 341 | where |
| 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 | } |
no test coverage detected
searching dependent graphs…