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

Function lpad_scalar_unicode

datafusion/functions/src/unicode/lpad.rs:245–295  ·  view source on GitHub ↗
(
    string_array: V,
    target_len: usize,
    fill: &str,
)

Source from the content-addressed store, hash-verified

243}
244
245fn lpad_scalar_unicode<'a, V: StringArrayType<'a> + Copy, T: OffsetSizeTrait>(
246 string_array: V,
247 target_len: usize,
248 fill: &str,
249) -> Result<ArrayRef> {
250 let fill_chars: Vec<char> = fill.chars().collect();
251
252 // With a scalar `target_len` and `fill`, we can precompute a padding buffer
253 // of `target_len` fill characters repeated cyclically. Because Unicode
254 // characters are variable-width, we build a byte-offset table to map from
255 // character count to the corresponding byte position in the padding buffer.
256 let (padding_buf, char_byte_offsets) = if !fill_chars.is_empty() {
257 let mut buf = String::new();
258 let mut offsets = Vec::with_capacity(target_len + 1);
259 offsets.push(0usize);
260 for i in 0..target_len {
261 buf.push(fill_chars[i % fill_chars.len()]);
262 offsets.push(buf.len());
263 }
264 (buf, offsets)
265 } else {
266 (String::new(), vec![0])
267 };
268
269 // Each output row is `target_len` chars; multiply by 4 (max UTF-8 bytes
270 // per char) for an upper bound in bytes.
271 let data_capacity = string_array.len().saturating_mul(target_len * 4);
272 let mut builder =
273 GenericStringBuilder::<T>::with_capacity(string_array.len(), data_capacity);
274
275 for maybe_string in string_array.iter() {
276 match maybe_string {
277 Some(string) => match char_count_or_boundary(string, target_len) {
278 StringCharLen::ByteOffset(offset) => {
279 builder.append_value(&string[..offset]);
280 }
281 StringCharLen::CharCount(char_count) => {
282 if !fill_chars.is_empty() {
283 let pad_chars = target_len - char_count;
284 let pad_bytes = char_byte_offsets[pad_chars];
285 builder.write_str(&padding_buf[..pad_bytes])?;
286 }
287 builder.append_value(string);
288 }
289 },
290 None => builder.append_null(),
291 }
292 }
293
294 Ok(Arc::new(builder.finish()) as ArrayRef)
295}
296
297/// Left-pads `string` to `target_len` using the fill string (default: space).
298/// Truncates from the right if `string` is already longer than `target_len`.

Callers

nothing calls this directly

Calls 11

newFunction · 0.85
char_count_or_boundaryFunction · 0.85
collectMethod · 0.80
write_strMethod · 0.80
is_emptyMethod · 0.45
pushMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
append_valueMethod · 0.45
append_nullMethod · 0.45
finishMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…