Skip to main content

arrow_ord/
sort.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Defines sort kernel for `ArrayRef`
19
20use crate::ord::{DynComparator, make_comparator};
21use arrow_array::builder::BufferBuilder;
22use arrow_array::cast::*;
23use arrow_array::types::*;
24use arrow_array::*;
25use arrow_buffer::ArrowNativeType;
26use arrow_buffer::BooleanBufferBuilder;
27use arrow_data::{ArrayDataBuilder, ByteView, MAX_INLINE_VIEW_LEN};
28use arrow_schema::{ArrowError, DataType};
29use arrow_select::take::take;
30use std::cmp::Ordering;
31use std::sync::Arc;
32
33use crate::rank::{can_rank, rank};
34pub use arrow_schema::SortOptions;
35
36/// Sort the `ArrayRef` using `SortOptions`.
37///
38/// Performs a sort on values and indices. Nulls are ordered according
39/// to the `nulls_first` flag in `options`.  Floats are sorted using
40/// IEEE 754 totalOrder
41///
42/// Returns an `ArrowError::ComputeError(String)` if the array type is
43/// either unsupported by `sort_to_indices` or `take`.
44///
45/// Note: this is an unstable_sort, meaning it may not preserve the
46/// order of equal elements.
47///
48/// # Example
49/// ```rust
50/// # use std::sync::Arc;
51/// # use arrow_array::Int32Array;
52/// # use arrow_ord::sort::sort;
53/// let array = Int32Array::from(vec![5, 4, 3, 2, 1]);
54/// let sorted_array = sort(&array, None).unwrap();
55/// assert_eq!(sorted_array.as_ref(), &Int32Array::from(vec![1, 2, 3, 4, 5]));
56/// ```
57pub fn sort(values: &dyn Array, options: Option<SortOptions>) -> Result<ArrayRef, ArrowError> {
58    downcast_primitive_array!(
59        values => sort_native_type(values, options),
60        DataType::RunEndEncoded(_, _) => sort_run(values, options, None),
61        _ => {
62            let indices = sort_to_indices(values, options, None)?;
63            take(values, &indices, None)
64        }
65    )
66}
67
68fn sort_native_type<T>(
69    primitive_values: &PrimitiveArray<T>,
70    options: Option<SortOptions>,
71) -> Result<ArrayRef, ArrowError>
72where
73    T: ArrowPrimitiveType,
74{
75    let sort_options = options.unwrap_or_default();
76
77    let mut mutable_buffer = vec![T::default_value(); primitive_values.len()];
78    let mutable_slice = &mut mutable_buffer;
79
80    let input_values = primitive_values.values().as_ref();
81
82    let nulls_count = primitive_values.null_count();
83    let valid_count = primitive_values.len() - nulls_count;
84
85    let null_bit_buffer = match nulls_count > 0 {
86        true => {
87            let mut validity_buffer = BooleanBufferBuilder::new(primitive_values.len());
88            if sort_options.nulls_first {
89                validity_buffer.append_n(nulls_count, false);
90                validity_buffer.append_n(valid_count, true);
91            } else {
92                validity_buffer.append_n(valid_count, true);
93                validity_buffer.append_n(nulls_count, false);
94            }
95            Some(validity_buffer.finish().into())
96        }
97        false => None,
98    };
99
100    if let Some(nulls) = primitive_values.nulls().filter(|n| n.null_count() > 0) {
101        let values_slice = match sort_options.nulls_first {
102            true => &mut mutable_slice[nulls_count..],
103            false => &mut mutable_slice[..valid_count],
104        };
105
106        for (write_index, index) in nulls.valid_indices().enumerate() {
107            values_slice[write_index] = primitive_values.value(index);
108        }
109
110        values_slice.sort_unstable_by(|a, b| a.compare(*b));
111        if sort_options.descending {
112            values_slice.reverse();
113        }
114    } else {
115        mutable_slice.copy_from_slice(input_values);
116        mutable_slice.sort_unstable_by(|a, b| a.compare(*b));
117        if sort_options.descending {
118            mutable_slice.reverse();
119        }
120    }
121
122    Ok(Arc::new(
123        PrimitiveArray::<T>::try_new(mutable_buffer.into(), null_bit_buffer)?
124            .with_data_type(primitive_values.data_type().clone()),
125    ))
126}
127
128/// Sort the `ArrayRef` partially.
129///
130/// If `limit` is specified, the resulting array will contain only
131/// first `limit` in the sort order. Any data data after the limit
132/// will be discarded.
133///
134/// Note: this is an unstable_sort, meaning it may not preserve the
135/// order of equal elements.
136///
137/// # Example
138/// ```rust
139/// # use std::sync::Arc;
140/// # use arrow_array::Int32Array;
141/// # use arrow_ord::sort::{sort_limit, SortOptions};
142/// let array = Int32Array::from(vec![5, 4, 3, 2, 1]);
143///
144/// // Find the the top 2 items
145/// let sorted_array = sort_limit(&array, None, Some(2)).unwrap();
146/// assert_eq!(sorted_array.as_ref(), &Int32Array::from(vec![1, 2]));
147///
148/// // Find the bottom top 2 items
149/// let options = Some(SortOptions {
150///                  descending: true,
151///                  ..Default::default()
152///               });
153/// let sorted_array = sort_limit(&array, options, Some(2)).unwrap();
154/// assert_eq!(sorted_array.as_ref(), &Int32Array::from(vec![5, 4]));
155/// ```
156pub fn sort_limit(
157    values: &dyn Array,
158    options: Option<SortOptions>,
159    limit: Option<usize>,
160) -> Result<ArrayRef, ArrowError> {
161    if let DataType::RunEndEncoded(_, _) = values.data_type() {
162        return sort_run(values, options, limit);
163    }
164    let indices = sort_to_indices(values, options, limit)?;
165    take(values, &indices, None)
166}
167
168/// we can only do this if the T is primitive
169#[inline]
170fn sort_unstable_by<T, F>(array: &mut [T], limit: usize, cmp: F)
171where
172    F: FnMut(&T, &T) -> Ordering,
173{
174    if array.len() == limit {
175        array.sort_unstable_by(cmp);
176    } else {
177        partial_sort(array, limit, cmp);
178    }
179}
180
181/// Partition indices of an Arrow array into two categories:
182/// - `valid`: indices of non-null elements
183/// - `nulls`: indices of null elements
184///
185/// Optimized for performance with fast-path for all-valid arrays
186/// and bit-parallel scan for null-containing arrays.
187#[inline(always)]
188pub fn partition_validity(array: &dyn Array) -> (Vec<u32>, Vec<u32>) {
189    let len = array.len();
190    let null_count = array.null_count();
191
192    // Fast path: if there are no nulls, all elements are valid
193    if null_count == 0 {
194        // Simply return a range of indices [0, len)
195        let valid = (0..len as u32).collect();
196        return (valid, Vec::new());
197    }
198
199    // null bitmap exists and some values are null
200    partition_validity_scan(array, len, null_count)
201}
202
203/// Scans the null bitmap and partitions valid/null indices efficiently.
204/// Uses bit-level operations to extract bit positions.
205/// This function is only called when nulls exist.
206#[inline(always)]
207fn partition_validity_scan(
208    array: &dyn Array,
209    len: usize,
210    null_count: usize,
211) -> (Vec<u32>, Vec<u32>) {
212    // SAFETY: Guaranteed by caller that null_count > 0, so bitmap must exist
213    let bitmap = array.nulls().unwrap();
214
215    // Preallocate result vectors with exact capacities (avoids reallocations)
216    let mut valid = Vec::with_capacity(len - null_count);
217    let mut nulls = Vec::with_capacity(null_count);
218
219    unsafe {
220        // 1) Write valid indices (bits == 1)
221        let valid_slice = valid.spare_capacity_mut();
222        for (i, idx) in bitmap.inner().set_indices_u32().enumerate() {
223            valid_slice[i].write(idx);
224        }
225
226        // 2) Write null indices by inverting
227        let inv_buf = !bitmap.inner();
228        let null_slice = nulls.spare_capacity_mut();
229        for (i, idx) in inv_buf.set_indices_u32().enumerate() {
230            null_slice[i].write(idx);
231        }
232
233        // Finalize lengths
234        valid.set_len(len - null_count);
235        nulls.set_len(null_count);
236    }
237
238    assert_eq!(valid.len(), len - null_count);
239    assert_eq!(nulls.len(), null_count);
240    (valid, nulls)
241}
242
243/// Whether `sort_to_indices` can sort an array of given data type.
244fn can_sort_to_indices(data_type: &DataType) -> bool {
245    data_type.is_primitive()
246        || matches!(
247            data_type,
248            DataType::Boolean
249                | DataType::Utf8
250                | DataType::LargeUtf8
251                | DataType::Utf8View
252                | DataType::Binary
253                | DataType::LargeBinary
254                | DataType::BinaryView
255                | DataType::FixedSizeBinary(_)
256        )
257        || match data_type {
258            DataType::List(f) if can_rank(f.data_type()) => true,
259            DataType::ListView(f) if can_rank(f.data_type()) => true,
260            DataType::LargeList(f) if can_rank(f.data_type()) => true,
261            DataType::LargeListView(f) if can_rank(f.data_type()) => true,
262            DataType::FixedSizeList(f, _) if can_rank(f.data_type()) => true,
263            DataType::Dictionary(_, values) if can_rank(values.as_ref()) => true,
264            DataType::RunEndEncoded(_, f) if can_sort_to_indices(f.data_type()) => true,
265            _ => false,
266        }
267}
268
269/// Sort elements from `ArrayRef` into an unsigned integer (`UInt32Array`) of indices.
270/// Floats are sorted using IEEE 754 totalOrder.  `limit` is an option for [partial_sort].
271pub fn sort_to_indices(
272    array: &dyn Array,
273    options: Option<SortOptions>,
274    limit: Option<usize>,
275) -> Result<UInt32Array, ArrowError> {
276    let options = options.unwrap_or_default();
277
278    let (v, n) = partition_validity(array);
279
280    Ok(downcast_primitive_array! {
281        array => sort_primitive(array, v, n, options, limit),
282        DataType::Boolean => sort_boolean(array.as_boolean(), v, n, options, limit),
283        DataType::Utf8 => sort_bytes(array.as_string::<i32>(), v, n, options, limit),
284        DataType::LargeUtf8 => sort_bytes(array.as_string::<i64>(), v, n, options, limit),
285        DataType::Utf8View => sort_byte_view(array.as_string_view(), v, n, options, limit),
286        DataType::Binary => sort_bytes(array.as_binary::<i32>(), v, n, options, limit),
287        DataType::LargeBinary => sort_bytes(array.as_binary::<i64>(), v, n, options, limit),
288        DataType::BinaryView => sort_byte_view(array.as_binary_view(), v, n, options, limit),
289        DataType::FixedSizeBinary(_) => sort_fixed_size_binary(array.as_fixed_size_binary(), v, n, options, limit),
290        DataType::List(_) => sort_list(array.as_list::<i32>(), v, n, options, limit)?,
291        DataType::ListView(_) => sort_list_view(array.as_list_view::<i32>(), v, n, options, limit)?,
292        DataType::LargeList(_) => sort_list(array.as_list::<i64>(), v, n, options, limit)?,
293        DataType::LargeListView(_) => sort_list_view(array.as_list_view::<i64>(), v, n, options, limit)?,
294        DataType::FixedSizeList(_, _) => sort_fixed_size_list(array.as_fixed_size_list(), v, n, options, limit)?,
295        DataType::Dictionary(_, _) => downcast_dictionary_array!{
296            array => sort_dictionary(array, v, n, options, limit)?,
297            _ => unreachable!()
298        }
299        DataType::RunEndEncoded(run_ends_field, _) => match run_ends_field.data_type() {
300            DataType::Int16 => sort_run_to_indices::<Int16Type>(array, options, limit),
301            DataType::Int32 => sort_run_to_indices::<Int32Type>(array, options, limit),
302            DataType::Int64 => sort_run_to_indices::<Int64Type>(array, options, limit),
303            dt => {
304                return Err(ArrowError::ComputeError(format!(
305                    "Invalid run end data type: {dt}"
306                )))
307            }
308        },
309        t => {
310            return Err(ArrowError::ComputeError(format!(
311                "Sort not supported for data type {t}"
312            )));
313        }
314    })
315}
316
317fn sort_boolean(
318    values: &BooleanArray,
319    value_indices: Vec<u32>,
320    null_indices: Vec<u32>,
321    options: SortOptions,
322    limit: Option<usize>,
323) -> UInt32Array {
324    let mut valids = value_indices
325        .into_iter()
326        .map(|index| (index, values.value(index as usize)))
327        .collect::<Vec<(u32, bool)>>();
328    sort_impl(options, &mut valids, &null_indices, limit, |a, b| a.cmp(&b)).into()
329}
330
331fn sort_primitive<T: ArrowPrimitiveType>(
332    values: &PrimitiveArray<T>,
333    value_indices: Vec<u32>,
334    nulls: Vec<u32>,
335    options: SortOptions,
336    limit: Option<usize>,
337) -> UInt32Array {
338    let mut valids = value_indices
339        .into_iter()
340        .map(|index| (index, values.value(index as usize)))
341        .collect::<Vec<(u32, T::Native)>>();
342    sort_impl(options, &mut valids, &nulls, limit, T::Native::compare).into()
343}
344
345fn sort_bytes<T: ByteArrayType>(
346    values: &GenericByteArray<T>,
347    value_indices: Vec<u32>,
348    nulls: Vec<u32>,
349    options: SortOptions,
350    limit: Option<usize>,
351) -> UInt32Array {
352    // Note: Why do we use 4‑byte prefix?
353    // Compute the 4‑byte prefix in BE order, or left‑pad if shorter.
354    // Most byte‐sequences differ in their first few bytes, so by
355    // comparing up to 4 bytes as a single u32 we avoid the overhead
356    // of a full lexicographical compare for the vast majority of cases.
357
358    // 1. Build a vector of (index, prefix, length) tuples
359    let mut valids: Vec<(u32, u32, u64)> = value_indices
360        .into_iter()
361        .map(|idx| unsafe {
362            let slice: &[u8] = values.value_unchecked(idx as usize).as_ref();
363            let len = slice.len() as u64;
364            // Compute the 4‑byte prefix in BE order, or left‑pad if shorter
365            let prefix = if slice.len() >= 4 {
366                let raw = std::ptr::read_unaligned(slice.as_ptr() as *const u32);
367                u32::from_be(raw)
368            } else if slice.is_empty() {
369                // Handle empty slice case to avoid shift overflow
370                0u32
371            } else {
372                let mut v = 0u32;
373                for &b in slice {
374                    v = (v << 8) | (b as u32);
375                }
376                // Safe shift: slice.len() is in range [1, 3], so shift is in range [8, 24]
377                v << (8 * (4 - slice.len()))
378            };
379            (idx, prefix, len)
380        })
381        .collect();
382
383    // 2. compute the number of non-null entries to partially sort
384    let vlimit = match (limit, options.nulls_first) {
385        (Some(l), true) => l.saturating_sub(nulls.len()).min(valids.len()),
386        _ => valids.len(),
387    };
388
389    // 3. Comparator: compare prefix, then (when both slices shorter than 4) length, otherwise full slice
390    let cmp_bytes = |a: &(u32, u32, u64), b: &(u32, u32, u64)| unsafe {
391        let (ia, pa, la) = *a;
392        let (ib, pb, lb) = *b;
393        // 3.1 prefix (first 4 bytes)
394        let ord = pa.cmp(&pb);
395        if ord != Ordering::Equal {
396            return ord;
397        }
398        // 3.2 only if both slices had length < 4 (so prefix was padded)
399        if la < 4 || lb < 4 {
400            let ord = la.cmp(&lb);
401            if ord != Ordering::Equal {
402                return ord;
403            }
404        }
405        // 3.3 full lexicographical compare
406        let a_bytes: &[u8] = values.value_unchecked(ia as usize).as_ref();
407        let b_bytes: &[u8] = values.value_unchecked(ib as usize).as_ref();
408        a_bytes.cmp(b_bytes)
409    };
410
411    // 4. Partially sort according to ascending/descending
412    if !options.descending {
413        sort_unstable_by(&mut valids, vlimit, cmp_bytes);
414    } else {
415        sort_unstable_by(&mut valids, vlimit, |x, y| cmp_bytes(x, y).reverse());
416    }
417
418    // 5. Assemble nulls and sorted indices into final output
419    let total = valids.len() + nulls.len();
420    let out_limit = limit.unwrap_or(total).min(total);
421    let mut out = Vec::with_capacity(out_limit);
422
423    if options.nulls_first {
424        out.extend_from_slice(&nulls[..nulls.len().min(out_limit)]);
425        let rem = out_limit - out.len();
426        out.extend(valids.iter().map(|&(i, _, _)| i).take(rem));
427    } else {
428        out.extend(valids.iter().map(|&(i, _, _)| i).take(out_limit));
429        let rem = out_limit - out.len();
430        out.extend_from_slice(&nulls[..rem]);
431    }
432
433    out.into()
434}
435
436fn sort_byte_view<T: ByteViewType>(
437    values: &GenericByteViewArray<T>,
438    value_indices: Vec<u32>,
439    nulls: Vec<u32>,
440    options: SortOptions,
441    limit: Option<usize>,
442) -> UInt32Array {
443    // 1. Build a list of (index, raw_view, length)
444    let mut valids: Vec<_>;
445    // 2. Compute the number of non-null entries to partially sort
446    let vlimit: usize = match (limit, options.nulls_first) {
447        (Some(l), true) => l.saturating_sub(nulls.len()).min(value_indices.len()),
448        _ => value_indices.len(),
449    };
450    // 3.a Check if all views are inline (no data buffers)
451    if values.data_buffers().is_empty() {
452        valids = value_indices
453            .into_iter()
454            .map(|idx| {
455                // SAFETY: we know idx < values.len()
456                let raw = unsafe { *values.views().get_unchecked(idx as usize) };
457                let inline_key = GenericByteViewArray::<T>::inline_key_fast(raw);
458                (idx, inline_key)
459            })
460            .collect();
461        let cmp_inline = |a: &(u32, u128), b: &(u32, u128)| a.1.cmp(&b.1);
462
463        // Partially sort according to ascending/descending
464        if !options.descending {
465            sort_unstable_by(&mut valids, vlimit, cmp_inline);
466        } else {
467            sort_unstable_by(&mut valids, vlimit, |x, y| cmp_inline(x, y).reverse());
468        }
469    } else {
470        valids = value_indices
471            .into_iter()
472            .map(|idx| {
473                // SAFETY: we know idx < values.len()
474                let raw = unsafe { *values.views().get_unchecked(idx as usize) };
475                (idx, raw)
476            })
477            .collect();
478        // 3.b Mixed comparator: first prefix, then inline vs full comparison
479        let cmp_mixed = |a: &(u32, u128), b: &(u32, u128)| {
480            let (_, raw_a) = *a;
481            let (_, raw_b) = *b;
482            let len_a = raw_a as u32;
483            let len_b = raw_b as u32;
484            // 3.b.1 Both inline (≤12 bytes): compare full 128-bit key including length
485            if len_a <= MAX_INLINE_VIEW_LEN && len_b <= MAX_INLINE_VIEW_LEN {
486                return GenericByteViewArray::<T>::inline_key_fast(raw_a)
487                    .cmp(&GenericByteViewArray::<T>::inline_key_fast(raw_b));
488            }
489
490            // 3.b.2 Compare 4-byte prefix in big-endian order
491            let pref_a = ByteView::from(raw_a).prefix.swap_bytes();
492            let pref_b = ByteView::from(raw_b).prefix.swap_bytes();
493            if pref_a != pref_b {
494                return pref_a.cmp(&pref_b);
495            }
496
497            // 3.b.3 Fallback to full byte-slice comparison
498            let full_a: &[u8] = unsafe { values.value_unchecked(a.0 as usize).as_ref() };
499            let full_b: &[u8] = unsafe { values.value_unchecked(b.0 as usize).as_ref() };
500            full_a.cmp(full_b)
501        };
502
503        // 3.b.4 Partially sort according to ascending/descending
504        if !options.descending {
505            sort_unstable_by(&mut valids, vlimit, cmp_mixed);
506        } else {
507            sort_unstable_by(&mut valids, vlimit, |x, y| cmp_mixed(x, y).reverse());
508        }
509    }
510
511    // 5. Assemble nulls and sorted indices into final output
512    let total = valids.len() + nulls.len();
513    let out_limit = limit.unwrap_or(total).min(total);
514    let mut out = Vec::with_capacity(total);
515
516    if options.nulls_first {
517        // Place null indices first
518        out.extend_from_slice(&nulls[..nulls.len().min(out_limit)]);
519        let rem = out_limit - out.len();
520        out.extend(valids.iter().map(|&(i, _)| i).take(rem));
521    } else {
522        // Place non-null indices first
523        out.extend(valids.iter().map(|&(i, _)| i).take(out_limit));
524        let rem = out_limit - out.len();
525        out.extend_from_slice(&nulls[..rem]);
526    }
527
528    out.into()
529}
530
531fn sort_fixed_size_binary(
532    values: &FixedSizeBinaryArray,
533    value_indices: Vec<u32>,
534    nulls: Vec<u32>,
535    options: SortOptions,
536    limit: Option<usize>,
537) -> UInt32Array {
538    let mut valids = value_indices
539        .iter()
540        .copied()
541        .map(|index| (index, values.value(index as usize)))
542        .collect::<Vec<(u32, &[u8])>>();
543    sort_impl(options, &mut valids, &nulls, limit, Ord::cmp).into()
544}
545
546fn sort_dictionary<K: ArrowDictionaryKeyType>(
547    dict: &DictionaryArray<K>,
548    value_indices: Vec<u32>,
549    null_indices: Vec<u32>,
550    options: SortOptions,
551    limit: Option<usize>,
552) -> Result<UInt32Array, ArrowError> {
553    let keys: &PrimitiveArray<K> = dict.keys();
554    let rank = child_rank(dict.values().as_ref(), options)?;
555
556    // create tuples that are used for sorting
557    let mut valids = value_indices
558        .into_iter()
559        .map(|index| {
560            let key: K::Native = keys.value(index as usize);
561            (index, rank[key.as_usize()])
562        })
563        .collect::<Vec<(u32, u32)>>();
564
565    Ok(sort_impl(options, &mut valids, &null_indices, limit, |a, b| a.cmp(&b)).into())
566}
567
568fn sort_list<O: OffsetSizeTrait>(
569    array: &GenericListArray<O>,
570    value_indices: Vec<u32>,
571    null_indices: Vec<u32>,
572    options: SortOptions,
573    limit: Option<usize>,
574) -> Result<UInt32Array, ArrowError> {
575    let rank = child_rank(array.values().as_ref(), options)?;
576    let offsets = array.value_offsets();
577    let mut valids = value_indices
578        .into_iter()
579        .map(|index| {
580            let end = offsets[index as usize + 1].as_usize();
581            let start = offsets[index as usize].as_usize();
582            (index, &rank[start..end])
583        })
584        .collect::<Vec<(u32, &[u32])>>();
585    Ok(sort_impl(options, &mut valids, &null_indices, limit, Ord::cmp).into())
586}
587
588fn sort_list_view<O: OffsetSizeTrait>(
589    array: &GenericListViewArray<O>,
590    value_indices: Vec<u32>,
591    null_indices: Vec<u32>,
592    options: SortOptions,
593    limit: Option<usize>,
594) -> Result<UInt32Array, ArrowError> {
595    let rank = child_rank(array.values().as_ref(), options)?;
596    let offsets = array.offsets();
597    let sizes = array.sizes();
598    let mut valids = value_indices
599        .into_iter()
600        .map(|index| {
601            let start = offsets[index as usize].as_usize();
602            let size = sizes[index as usize].as_usize();
603            let end = start + size;
604            (index, &rank[start..end])
605        })
606        .collect::<Vec<(u32, &[u32])>>();
607    Ok(sort_impl(options, &mut valids, &null_indices, limit, Ord::cmp).into())
608}
609
610fn sort_fixed_size_list(
611    array: &FixedSizeListArray,
612    value_indices: Vec<u32>,
613    null_indices: Vec<u32>,
614    options: SortOptions,
615    limit: Option<usize>,
616) -> Result<UInt32Array, ArrowError> {
617    let rank = child_rank(array.values().as_ref(), options)?;
618    let size = array.value_length() as usize;
619    let mut valids = value_indices
620        .into_iter()
621        .map(|index| {
622            let start = index as usize * size;
623            (index, &rank[start..start + size])
624        })
625        .collect::<Vec<(u32, &[u32])>>();
626    Ok(sort_impl(options, &mut valids, &null_indices, limit, Ord::cmp).into())
627}
628
629#[inline(never)]
630fn sort_impl<T: Copy>(
631    options: SortOptions,
632    valids: &mut [(u32, T)],
633    nulls: &[u32],
634    limit: Option<usize>,
635    mut cmp: impl FnMut(T, T) -> Ordering,
636) -> Vec<u32> {
637    let v_limit = match (limit, options.nulls_first) {
638        (Some(l), true) => l.saturating_sub(nulls.len()).min(valids.len()),
639        _ => valids.len(),
640    };
641
642    match options.descending {
643        false => sort_unstable_by(valids, v_limit, |a, b| cmp(a.1, b.1)),
644        true => sort_unstable_by(valids, v_limit, |a, b| cmp(a.1, b.1).reverse()),
645    }
646
647    let len = valids.len() + nulls.len();
648    let limit = limit.unwrap_or(len).min(len);
649    let mut out = Vec::with_capacity(len);
650    match options.nulls_first {
651        true => {
652            out.extend_from_slice(&nulls[..nulls.len().min(limit)]);
653            let remaining = limit - out.len();
654            out.extend(valids.iter().map(|x| x.0).take(remaining));
655        }
656        false => {
657            out.extend(valids.iter().map(|x| x.0).take(limit));
658            let remaining = limit - out.len();
659            out.extend_from_slice(&nulls[..remaining])
660        }
661    }
662    out
663}
664
665/// Computes the rank for a set of child values
666fn child_rank(values: &dyn Array, options: SortOptions) -> Result<Vec<u32>, ArrowError> {
667    // If parent sort order is descending we need to invert the value of nulls_first so that
668    // when the parent is sorted based on the produced ranks, nulls are still ordered correctly
669    let value_options = Some(SortOptions {
670        descending: false,
671        nulls_first: options.nulls_first != options.descending,
672    });
673    rank(values, value_options)
674}
675
676// Sort run array and return sorted run array.
677// The output RunArray will be encoded at the same level as input run array.
678// For e.g. an input RunArray { run_ends = [2,4,6,8], values = [1,2,1,2] }
679// will result in output RunArray { run_ends = [2,4,6,8], values = [1,1,2,2] }
680// and not RunArray { run_ends = [4,8], values = [1,2] }
681fn sort_run(
682    values: &dyn Array,
683    options: Option<SortOptions>,
684    limit: Option<usize>,
685) -> Result<ArrayRef, ArrowError> {
686    match values.data_type() {
687        DataType::RunEndEncoded(run_ends_field, _) => match run_ends_field.data_type() {
688            DataType::Int16 => sort_run_downcasted::<Int16Type>(values, options, limit),
689            DataType::Int32 => sort_run_downcasted::<Int32Type>(values, options, limit),
690            DataType::Int64 => sort_run_downcasted::<Int64Type>(values, options, limit),
691            dt => unreachable!("Not valid run ends data type {dt}"),
692        },
693        dt => Err(ArrowError::InvalidArgumentError(format!(
694            "Input is not a run encoded array. Input data type {dt}"
695        ))),
696    }
697}
698
699fn sort_run_downcasted<R: RunEndIndexType>(
700    values: &dyn Array,
701    options: Option<SortOptions>,
702    limit: Option<usize>,
703) -> Result<ArrayRef, ArrowError> {
704    let run_array = values.as_any().downcast_ref::<RunArray<R>>().unwrap();
705
706    // Determine the length of output run array.
707    let output_len = if let Some(limit) = limit {
708        limit.min(run_array.len())
709    } else {
710        run_array.len()
711    };
712
713    let run_ends = run_array.run_ends();
714
715    let mut new_run_ends_builder = BufferBuilder::<R::Native>::new(run_ends.len());
716    let mut new_run_end: usize = 0;
717    let mut new_physical_len: usize = 0;
718
719    let consume_runs = |run_length, _| {
720        new_run_end += run_length;
721        new_physical_len += 1;
722        new_run_ends_builder.append(R::Native::from_usize(new_run_end).unwrap());
723    };
724
725    let (values_indices, run_values) = sort_run_inner(run_array, options, output_len, consume_runs);
726
727    let new_run_ends = unsafe {
728        // Safety:
729        // The function builds a valid run_ends array and hence need not be validated.
730        ArrayDataBuilder::new(R::DATA_TYPE)
731            .len(new_physical_len)
732            .add_buffer(new_run_ends_builder.finish())
733            .build_unchecked()
734    };
735
736    // slice the sorted value indices based on limit.
737    let new_values_indices: PrimitiveArray<UInt32Type> = values_indices
738        .slice(0, new_run_ends.len())
739        .into_data()
740        .into();
741
742    let new_values = take(&run_values, &new_values_indices, None)?;
743
744    // Build sorted run array
745    let builder = ArrayDataBuilder::new(run_array.data_type().clone())
746        .len(new_run_end)
747        .add_child_data(new_run_ends)
748        .add_child_data(new_values.into_data());
749    let array_data: RunArray<R> = unsafe {
750        // Safety:
751        //  This function builds a valid run array and hence can skip validation.
752        builder.build_unchecked().into()
753    };
754    Ok(Arc::new(array_data))
755}
756
757// Sort to indices for run encoded array.
758// This function will be slow for run array as it decodes the physical indices to
759// logical indices and to get the run array back, the logical indices has to be
760// encoded back to run array.
761fn sort_run_to_indices<R: RunEndIndexType>(
762    values: &dyn Array,
763    options: SortOptions,
764    limit: Option<usize>,
765) -> UInt32Array {
766    let run_array = values.as_any().downcast_ref::<RunArray<R>>().unwrap();
767    let output_len = if let Some(limit) = limit {
768        limit.min(run_array.len())
769    } else {
770        run_array.len()
771    };
772    let mut result: Vec<u32> = Vec::with_capacity(output_len);
773
774    //Add all logical indices belonging to a physical index to the output
775    let consume_runs = |run_length, logical_start| {
776        result.extend(logical_start as u32..(logical_start + run_length) as u32);
777    };
778    sort_run_inner(run_array, Some(options), output_len, consume_runs);
779
780    UInt32Array::from(result)
781}
782
783fn sort_run_inner<R: RunEndIndexType, F>(
784    run_array: &RunArray<R>,
785    options: Option<SortOptions>,
786    output_len: usize,
787    mut consume_runs: F,
788) -> (PrimitiveArray<UInt32Type>, ArrayRef)
789where
790    F: FnMut(usize, usize),
791{
792    // slice the run_array.values based on offset and length.
793    let start_physical_index = run_array.get_start_physical_index();
794    let end_physical_index = run_array.get_end_physical_index();
795    let physical_len = end_physical_index - start_physical_index + 1;
796    let run_values = run_array.values().slice(start_physical_index, physical_len);
797
798    // All the values have to be sorted irrespective of input limit.
799    let values_indices = sort_to_indices(&run_values, options, None).unwrap();
800
801    let mut remaining_len = output_len;
802
803    let run_ends = run_array.run_ends().values();
804
805    assert_eq!(
806        0,
807        values_indices.null_count(),
808        "The output of sort_to_indices should not have null values. Its values is {}",
809        values_indices.null_count()
810    );
811
812    // Calculate `run length` of sorted value indices.
813    // Find the `logical index` at which the run starts.
814    // Call the consumer using the run length and starting logical index.
815    for physical_index in values_indices.values() {
816        // As the values were sliced with offset = start_physical_index, it has to be added back
817        // before accessing `RunArray::run_ends`
818        let physical_index = *physical_index as usize + start_physical_index;
819
820        // calculate the run length and logical index of sorted values
821        let (run_length, logical_index_start) = unsafe {
822            // Safety:
823            // The index will be within bounds as its in bounds of start_physical_index
824            // and len, both of which are within bounds of run_array
825            if physical_index == start_physical_index {
826                (
827                    run_ends.get_unchecked(physical_index).as_usize() - run_array.offset(),
828                    0,
829                )
830            } else if physical_index == end_physical_index {
831                let prev_run_end = run_ends.get_unchecked(physical_index - 1).as_usize();
832                (
833                    run_array.offset() + run_array.len() - prev_run_end,
834                    prev_run_end - run_array.offset(),
835                )
836            } else {
837                let prev_run_end = run_ends.get_unchecked(physical_index - 1).as_usize();
838                (
839                    run_ends.get_unchecked(physical_index).as_usize() - prev_run_end,
840                    prev_run_end - run_array.offset(),
841                )
842            }
843        };
844        let new_run_length = run_length.min(remaining_len);
845        consume_runs(new_run_length, logical_index_start);
846        remaining_len -= new_run_length;
847
848        if remaining_len == 0 {
849            break;
850        }
851    }
852
853    if remaining_len > 0 {
854        panic!("Remaining length should be zero its values is {remaining_len}")
855    }
856    (values_indices, run_values)
857}
858
859/// One column to be used in lexicographical sort
860#[derive(Clone, Debug)]
861pub struct SortColumn {
862    /// The column to sort
863    pub values: ArrayRef,
864    /// Sort options for this column
865    pub options: Option<SortOptions>,
866}
867
868/// Sort a list of `ArrayRef` using `SortOptions` provided for each array.
869///
870/// Performs an unstable lexicographical sort on values and indices.
871///
872/// Returns an `ArrowError::ComputeError(String)` if any of the array type is either unsupported by
873/// `lexsort_to_indices` or `take`.
874///
875/// # Example:
876///
877/// ```
878/// # use std::convert::From;
879/// # use std::sync::Arc;
880/// # use arrow_array::{ArrayRef, StringArray, PrimitiveArray};
881/// # use arrow_array::types::Int64Type;
882/// # use arrow_array::cast::AsArray;
883/// # use arrow_ord::sort::{SortColumn, SortOptions, lexsort};
884/// let sorted_columns = lexsort(&vec![
885///     SortColumn {
886///         values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
887///             None,
888///             Some(-2),
889///             Some(89),
890///             Some(-64),
891///             Some(101),
892///         ])) as ArrayRef,
893///         options: None,
894///     },
895///     SortColumn {
896///         values: Arc::new(StringArray::from(vec![
897///             Some("hello"),
898///             Some("world"),
899///             Some(","),
900///             Some("foobar"),
901///             Some("!"),
902///         ])) as ArrayRef,
903///         options: Some(SortOptions {
904///             descending: true,
905///             nulls_first: false,
906///         }),
907///     },
908/// ], None).unwrap();
909///
910/// assert_eq!(sorted_columns[0].as_primitive::<Int64Type>().value(1), -64);
911/// assert!(sorted_columns[0].is_null(0));
912/// ```
913///
914/// Note: for multi-column sorts without a limit, using the [row format](https://docs.rs/arrow-row/latest/arrow_row/)
915/// may be significantly faster
916///
917pub fn lexsort(columns: &[SortColumn], limit: Option<usize>) -> Result<Vec<ArrayRef>, ArrowError> {
918    let indices = lexsort_to_indices(columns, limit)?;
919    columns
920        .iter()
921        .map(|c| take(c.values.as_ref(), &indices, None))
922        .collect()
923}
924
925/// Sort elements lexicographically from a list of `ArrayRef` into an unsigned integer
926/// (`UInt32Array`) of indices.
927///
928/// Note: for multi-column sorts without a limit, using the [row format](https://docs.rs/arrow-row/latest/arrow_row/)
929/// may be significantly faster
930pub fn lexsort_to_indices(
931    columns: &[SortColumn],
932    limit: Option<usize>,
933) -> Result<UInt32Array, ArrowError> {
934    if columns.is_empty() {
935        return Err(ArrowError::InvalidArgumentError(
936            "Sort requires at least one column".to_string(),
937        ));
938    }
939    if columns.len() == 1 && can_sort_to_indices(columns[0].values.data_type()) {
940        // fallback to non-lexical sort
941        let column = &columns[0];
942        return sort_to_indices(&column.values, column.options, limit);
943    }
944
945    let row_count = columns[0].values.len();
946    if columns.iter().any(|item| item.values.len() != row_count) {
947        return Err(ArrowError::ComputeError(
948            "lexical sort columns have different row counts".to_string(),
949        ));
950    };
951
952    let len = limit.unwrap_or(row_count).min(row_count);
953
954    if len == 0 {
955        return Ok(UInt32Array::from(Vec::<u32>::new()));
956    }
957
958    // The heap path avoids allocating and partially sorting all row indices
959    // when the requested limit is a small fraction of the input. For larger
960    // limits, the existing partial-sort path is preferred because heap
961    // maintenance costs grow with the requested limit.
962    let value_indices = match limit {
963        Some(limit) if limit <= row_count / 10 => match columns.len() {
964            2 => lexsort_topk_fixed::<2>(columns, row_count, len)?,
965            3 => lexsort_topk_fixed::<3>(columns, row_count, len)?,
966            4 => lexsort_topk_fixed::<4>(columns, row_count, len)?,
967            5 => lexsort_topk_fixed::<5>(columns, row_count, len)?,
968            _ => {
969                let lexicographical_comparator = LexicographicalComparator::try_new(columns)?;
970                lexsort_topk(row_count, len, |a, b| {
971                    lexicographical_comparator.compare(a, b)
972                })
973            }
974        },
975        _ => {
976            let mut value_indices = (0..row_count).collect::<Vec<usize>>();
977
978            // Instantiate specialized versions of comparisons for small numbers
979            // of columns as it helps the compiler generate better code.
980            match columns.len() {
981                2 => sort_fixed_column::<2>(columns, &mut value_indices, len)?,
982                3 => sort_fixed_column::<3>(columns, &mut value_indices, len)?,
983                4 => sort_fixed_column::<4>(columns, &mut value_indices, len)?,
984                5 => sort_fixed_column::<5>(columns, &mut value_indices, len)?,
985                _ => {
986                    let lexicographical_comparator = LexicographicalComparator::try_new(columns)?;
987                    sort_unstable_by(&mut value_indices, len, |a, b| {
988                        lexicographical_comparator.compare(*a, *b)
989                    });
990                }
991            }
992
993            value_indices.truncate(len);
994            value_indices
995        }
996    };
997
998    Ok(UInt32Array::from(
999        value_indices
1000            .into_iter()
1001            .map(|i| i as u32)
1002            .collect::<Vec<_>>(),
1003    ))
1004}
1005
1006// Sort a fixed number of columns using FixedLexicographicalComparator
1007fn sort_fixed_column<const N: usize>(
1008    columns: &[SortColumn],
1009    value_indices: &mut [usize],
1010    len: usize,
1011) -> Result<(), ArrowError> {
1012    let lexicographical_comparator = FixedLexicographicalComparator::<N>::try_new(columns)?;
1013    sort_unstable_by(value_indices, len, |a, b| {
1014        lexicographical_comparator.compare(*a, *b)
1015    });
1016    Ok(())
1017}
1018
1019// Uses the fixed-column comparator for the bounded heap path.
1020fn lexsort_topk_fixed<const N: usize>(
1021    columns: &[SortColumn],
1022    row_count: usize,
1023    limit: usize,
1024) -> Result<Vec<usize>, ArrowError> {
1025    let lexicographical_comparator = FixedLexicographicalComparator::<N>::try_new(columns)?;
1026    Ok(lexsort_topk(row_count, limit, |a, b| {
1027        lexicographical_comparator.compare(a, b)
1028    }))
1029}
1030
1031// Keeps the smallest `limit` indices in a bounded max-heap.
1032// The root is the largest retained index according to `compare`.
1033fn lexsort_topk(
1034    row_count: usize,
1035    limit: usize,
1036    mut compare: impl FnMut(usize, usize) -> Ordering,
1037) -> Vec<usize> {
1038    let mut heap = Vec::with_capacity(limit);
1039
1040    for idx in 0..row_count {
1041        if heap.len() < limit {
1042            heap.push(idx);
1043            let pos = heap.len() - 1;
1044            sift_up_worst_heap(&mut heap, pos, &mut compare);
1045        } else if compare(idx, heap[0]) == Ordering::Less {
1046            heap[0] = idx;
1047            sift_down_worst_heap(&mut heap, 0, &mut compare);
1048        }
1049    }
1050
1051    heap.sort_unstable_by(|a, b| compare(*a, *b));
1052    heap
1053}
1054
1055// Moves a newly inserted index toward the root while it is larger than its parent.
1056fn sift_up_worst_heap(
1057    heap: &mut [usize],
1058    mut pos: usize,
1059    compare: &mut impl FnMut(usize, usize) -> Ordering,
1060) {
1061    while pos > 0 {
1062        let parent = (pos - 1) / 2;
1063
1064        if compare(heap[parent], heap[pos]) != Ordering::Less {
1065            break;
1066        }
1067
1068        heap.swap(parent, pos);
1069        pos = parent;
1070    }
1071}
1072
1073// Moves the root down until both children are no larger than it.
1074// The larger child is selected at each step so the worst retained row remains
1075// at heap[0].
1076fn sift_down_worst_heap(
1077    heap: &mut [usize],
1078    mut pos: usize,
1079    compare: &mut impl FnMut(usize, usize) -> Ordering,
1080) {
1081    loop {
1082        let left = pos * 2 + 1;
1083        if left >= heap.len() {
1084            break;
1085        }
1086
1087        let right = left + 1;
1088        let mut worst = left;
1089
1090        if right < heap.len() && compare(heap[left], heap[right]) == Ordering::Less {
1091            worst = right;
1092        }
1093
1094        if compare(heap[pos], heap[worst]) != Ordering::Less {
1095            break;
1096        }
1097
1098        heap.swap(pos, worst);
1099        pos = worst;
1100    }
1101}
1102
1103/// It's unstable_sort, may not preserve the order of equal elements
1104pub fn partial_sort<T, F>(v: &mut [T], limit: usize, mut is_less: F)
1105where
1106    F: FnMut(&T, &T) -> Ordering,
1107{
1108    if let Some(n) = limit.checked_sub(1) {
1109        let (before, _mid, _after) = v.select_nth_unstable_by(n, &mut is_less);
1110        before.sort_unstable_by(is_less);
1111    }
1112}
1113
1114/// A lexicographical comparator that wraps given array data (columns) and can lexicographically compare data
1115/// at given two indices. The lifetime is the same at the data wrapped.
1116pub struct LexicographicalComparator {
1117    compare_items: Vec<DynComparator>,
1118}
1119
1120impl LexicographicalComparator {
1121    /// lexicographically compare values at the wrapped columns with given indices.
1122    pub fn compare(&self, a_idx: usize, b_idx: usize) -> Ordering {
1123        for comparator in &self.compare_items {
1124            match comparator(a_idx, b_idx) {
1125                Ordering::Equal => continue,
1126                r => return r,
1127            }
1128        }
1129        Ordering::Equal
1130    }
1131
1132    /// Create a new lex comparator that will wrap the given sort columns and give comparison
1133    /// results with two indices.
1134    pub fn try_new(columns: &[SortColumn]) -> Result<LexicographicalComparator, ArrowError> {
1135        let compare_items = columns
1136            .iter()
1137            .map(|c| {
1138                make_comparator(
1139                    c.values.as_ref(),
1140                    c.values.as_ref(),
1141                    c.options.unwrap_or_default(),
1142                )
1143            })
1144            .collect::<Result<Vec<_>, ArrowError>>()?;
1145        Ok(LexicographicalComparator { compare_items })
1146    }
1147}
1148
1149/// A lexicographical comparator that wraps given array data (columns) and can lexicographically compare data
1150/// at given two indices. This version of the comparator is for compile-time constant number of columns.
1151/// The lifetime is the same at the data wrapped.
1152pub struct FixedLexicographicalComparator<const N: usize> {
1153    compare_items: [DynComparator; N],
1154}
1155
1156impl<const N: usize> FixedLexicographicalComparator<N> {
1157    /// lexicographically compare values at the wrapped columns with given indices.
1158    pub fn compare(&self, a_idx: usize, b_idx: usize) -> Ordering {
1159        for comparator in &self.compare_items {
1160            match comparator(a_idx, b_idx) {
1161                Ordering::Equal => continue,
1162                r => return r,
1163            }
1164        }
1165        Ordering::Equal
1166    }
1167
1168    /// Create a new lex comparator that will wrap the given sort columns and give comparison
1169    /// results with two indices.
1170    /// The number of columns should be equal to the compile-time constant N.
1171    pub fn try_new(
1172        columns: &[SortColumn],
1173    ) -> Result<FixedLexicographicalComparator<N>, ArrowError> {
1174        let compare_items = columns
1175            .iter()
1176            .map(|c| {
1177                make_comparator(
1178                    c.values.as_ref(),
1179                    c.values.as_ref(),
1180                    c.options.unwrap_or_default(),
1181                )
1182            })
1183            .collect::<Result<Vec<_>, ArrowError>>()?
1184            .try_into();
1185        let compare_items: [Box<dyn Fn(usize, usize) -> Ordering + Send + Sync + 'static>; N] =
1186            compare_items.map_err(|_| {
1187                ArrowError::ComputeError("Could not create fixed size array".to_string())
1188            })?;
1189        Ok(FixedLexicographicalComparator { compare_items })
1190    }
1191}
1192
1193#[cfg(test)]
1194mod tests {
1195    use super::*;
1196    use arrow_array::builder::{
1197        BooleanBuilder, FixedSizeListBuilder, GenericListBuilder, Int64Builder, ListBuilder,
1198        PrimitiveRunBuilder,
1199    };
1200    use arrow_buffer::{NullBuffer, i256};
1201    use arrow_schema::Field;
1202    use half::f16;
1203    use rand::rngs::StdRng;
1204    use rand::seq::SliceRandom;
1205    use rand::{Rng, RngCore, SeedableRng};
1206
1207    fn create_decimal_array<T: DecimalType>(
1208        data: Vec<Option<usize>>,
1209        precision: u8,
1210        scale: i8,
1211    ) -> PrimitiveArray<T> {
1212        data.into_iter()
1213            .map(|x| x.and_then(T::Native::from_usize))
1214            .collect::<PrimitiveArray<T>>()
1215            .with_precision_and_scale(precision, scale)
1216            .unwrap()
1217    }
1218
1219    fn create_decimal256_array(data: Vec<Option<i256>>) -> Decimal256Array {
1220        data.into_iter()
1221            .collect::<Decimal256Array>()
1222            .with_precision_and_scale(53, 6)
1223            .unwrap()
1224    }
1225
1226    fn test_sort_to_indices_decimal_array<T: DecimalType>(
1227        data: Vec<Option<usize>>,
1228        options: Option<SortOptions>,
1229        limit: Option<usize>,
1230        expected_data: Vec<u32>,
1231        precision: u8,
1232        scale: i8,
1233    ) {
1234        let output = create_decimal_array::<T>(data, precision, scale);
1235        let expected = UInt32Array::from(expected_data);
1236        let output = sort_to_indices(&output, options, limit).unwrap();
1237        assert_eq!(output, expected)
1238    }
1239
1240    fn test_sort_to_indices_decimal256_array(
1241        data: Vec<Option<i256>>,
1242        options: Option<SortOptions>,
1243        limit: Option<usize>,
1244        expected_data: Vec<u32>,
1245    ) {
1246        let output = create_decimal256_array(data);
1247        let expected = UInt32Array::from(expected_data);
1248        let output = sort_to_indices(&output, options, limit).unwrap();
1249        assert_eq!(output, expected)
1250    }
1251
1252    fn test_sort_decimal_array<T: DecimalType>(
1253        data: Vec<Option<usize>>,
1254        options: Option<SortOptions>,
1255        limit: Option<usize>,
1256        expected_data: Vec<Option<usize>>,
1257        p: u8,
1258        s: i8,
1259    ) {
1260        let output = create_decimal_array::<T>(data, p, s);
1261        let expected = Arc::new(create_decimal_array::<T>(expected_data, p, s)) as ArrayRef;
1262        let output = match limit {
1263            Some(_) => sort_limit(&output, options, limit).unwrap(),
1264            _ => sort(&output, options).unwrap(),
1265        };
1266        assert_eq!(&output, &expected)
1267    }
1268
1269    fn test_sort_decimal256_array(
1270        data: Vec<Option<i256>>,
1271        options: Option<SortOptions>,
1272        limit: Option<usize>,
1273        expected_data: Vec<Option<i256>>,
1274    ) {
1275        let output = create_decimal256_array(data);
1276        let expected = Arc::new(create_decimal256_array(expected_data)) as ArrayRef;
1277        let output = match limit {
1278            Some(_) => sort_limit(&output, options, limit).unwrap(),
1279            _ => sort(&output, options).unwrap(),
1280        };
1281        assert_eq!(&output, &expected)
1282    }
1283
1284    fn test_sort_to_indices_boolean_arrays(
1285        data: Vec<Option<bool>>,
1286        options: Option<SortOptions>,
1287        limit: Option<usize>,
1288        expected_data: Vec<u32>,
1289    ) {
1290        let output = BooleanArray::from(data);
1291        let expected = UInt32Array::from(expected_data);
1292        let output = sort_to_indices(&output, options, limit).unwrap();
1293        assert_eq!(output, expected)
1294    }
1295
1296    fn test_sort_to_indices_primitive_arrays<T>(
1297        data: Vec<Option<T::Native>>,
1298        options: Option<SortOptions>,
1299        limit: Option<usize>,
1300        expected_data: Vec<u32>,
1301    ) where
1302        T: ArrowPrimitiveType,
1303        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1304    {
1305        let output = PrimitiveArray::<T>::from(data);
1306        let expected = UInt32Array::from(expected_data);
1307        let output = sort_to_indices(&output, options, limit).unwrap();
1308        assert_eq!(output, expected)
1309    }
1310
1311    fn test_sort_primitive_arrays<T>(
1312        data: Vec<Option<T::Native>>,
1313        options: Option<SortOptions>,
1314        limit: Option<usize>,
1315        expected_data: Vec<Option<T::Native>>,
1316    ) where
1317        T: ArrowPrimitiveType,
1318        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1319    {
1320        let output = PrimitiveArray::<T>::from(data);
1321        let expected = Arc::new(PrimitiveArray::<T>::from(expected_data)) as ArrayRef;
1322        let output = match limit {
1323            Some(_) => sort_limit(&output, options, limit).unwrap(),
1324            _ => sort(&output, options).unwrap(),
1325        };
1326        assert_eq!(&output, &expected)
1327    }
1328
1329    fn test_sort_to_indices_string_arrays(
1330        data: Vec<Option<&str>>,
1331        options: Option<SortOptions>,
1332        limit: Option<usize>,
1333        expected_data: Vec<u32>,
1334    ) {
1335        let output = StringArray::from(data);
1336        let expected = UInt32Array::from(expected_data);
1337        let output = sort_to_indices(&output, options, limit).unwrap();
1338        assert_eq!(output, expected)
1339    }
1340
1341    /// Tests both Utf8 and LargeUtf8
1342    fn test_sort_string_arrays(
1343        data: Vec<Option<&str>>,
1344        options: Option<SortOptions>,
1345        limit: Option<usize>,
1346        expected_data: Vec<Option<&str>>,
1347    ) {
1348        let output = StringArray::from(data.clone());
1349        let expected = Arc::new(StringArray::from(expected_data.clone())) as ArrayRef;
1350        let output = match limit {
1351            Some(_) => sort_limit(&output, options, limit).unwrap(),
1352            _ => sort(&output, options).unwrap(),
1353        };
1354        assert_eq!(&output, &expected);
1355
1356        let output = LargeStringArray::from(data.clone());
1357        let expected = Arc::new(LargeStringArray::from(expected_data.clone())) as ArrayRef;
1358        let output = match limit {
1359            Some(_) => sort_limit(&output, options, limit).unwrap(),
1360            _ => sort(&output, options).unwrap(),
1361        };
1362        assert_eq!(&output, &expected);
1363
1364        let output = StringViewArray::from(data);
1365        let expected = Arc::new(StringViewArray::from(expected_data)) as ArrayRef;
1366        let output = match limit {
1367            Some(_) => sort_limit(&output, options, limit).unwrap(),
1368            _ => sort(&output, options).unwrap(),
1369        };
1370        assert_eq!(&output, &expected);
1371    }
1372
1373    fn test_sort_string_dict_arrays<T: ArrowDictionaryKeyType>(
1374        data: Vec<Option<&str>>,
1375        options: Option<SortOptions>,
1376        limit: Option<usize>,
1377        expected_data: Vec<Option<&str>>,
1378    ) {
1379        let array = data.into_iter().collect::<DictionaryArray<T>>();
1380        let array_values = array.values().clone();
1381        let dict = array_values
1382            .as_any()
1383            .downcast_ref::<StringArray>()
1384            .expect("Unable to get dictionary values");
1385
1386        let sorted = match limit {
1387            Some(_) => sort_limit(&array, options, limit).unwrap(),
1388            _ => sort(&array, options).unwrap(),
1389        };
1390        let sorted = sorted
1391            .as_any()
1392            .downcast_ref::<DictionaryArray<T>>()
1393            .unwrap();
1394        let sorted_values = sorted.values();
1395        let sorted_dict = sorted_values
1396            .as_any()
1397            .downcast_ref::<StringArray>()
1398            .expect("Unable to get dictionary values");
1399        let sorted_keys = sorted.keys();
1400
1401        assert_eq!(sorted_dict, dict);
1402
1403        let sorted_strings = StringArray::from_iter((0..sorted.len()).map(|i| {
1404            if sorted.is_valid(i) {
1405                Some(sorted_dict.value(sorted_keys.value(i).as_usize()))
1406            } else {
1407                None
1408            }
1409        }));
1410        let expected = StringArray::from(expected_data);
1411
1412        assert_eq!(sorted_strings, expected)
1413    }
1414
1415    fn test_sort_primitive_dict_arrays<K: ArrowDictionaryKeyType, T: ArrowPrimitiveType>(
1416        keys: PrimitiveArray<K>,
1417        values: PrimitiveArray<T>,
1418        options: Option<SortOptions>,
1419        limit: Option<usize>,
1420        expected_data: Vec<Option<T::Native>>,
1421    ) where
1422        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1423    {
1424        let array = DictionaryArray::<K>::new(keys, Arc::new(values));
1425        let array_values = array.values().clone();
1426        let dict = array_values.as_primitive::<T>();
1427
1428        let sorted = match limit {
1429            Some(_) => sort_limit(&array, options, limit).unwrap(),
1430            _ => sort(&array, options).unwrap(),
1431        };
1432        let sorted = sorted
1433            .as_any()
1434            .downcast_ref::<DictionaryArray<K>>()
1435            .unwrap();
1436        let sorted_values = sorted.values();
1437        let sorted_dict = sorted_values
1438            .as_any()
1439            .downcast_ref::<PrimitiveArray<T>>()
1440            .expect("Unable to get dictionary values");
1441        let sorted_keys = sorted.keys();
1442
1443        assert_eq!(sorted_dict, dict);
1444
1445        let sorted_values: PrimitiveArray<T> = From::<Vec<Option<T::Native>>>::from(
1446            (0..sorted.len())
1447                .map(|i| {
1448                    let key = sorted_keys.value(i).as_usize();
1449                    if sorted.is_valid(i) && sorted_dict.is_valid(key) {
1450                        Some(sorted_dict.value(key))
1451                    } else {
1452                        None
1453                    }
1454                })
1455                .collect::<Vec<Option<T::Native>>>(),
1456        );
1457        let expected: PrimitiveArray<T> = From::<Vec<Option<T::Native>>>::from(expected_data);
1458
1459        assert_eq!(sorted_values, expected)
1460    }
1461
1462    fn test_sort_list_arrays<T>(
1463        data: Vec<Option<Vec<Option<T::Native>>>>,
1464        options: Option<SortOptions>,
1465        limit: Option<usize>,
1466        expected_data: Vec<Option<Vec<Option<T::Native>>>>,
1467        fixed_length: Option<i32>,
1468    ) where
1469        T: ArrowPrimitiveType,
1470        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1471    {
1472        // for FixedSizedList
1473        if let Some(length) = fixed_length {
1474            let input = Arc::new(FixedSizeListArray::from_iter_primitive::<T, _, _>(
1475                data.clone(),
1476                length,
1477            ));
1478            let sorted = match limit {
1479                Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1480                _ => sort(&(input as ArrayRef), options).unwrap(),
1481            };
1482            let expected = Arc::new(FixedSizeListArray::from_iter_primitive::<T, _, _>(
1483                expected_data.clone(),
1484                length,
1485            )) as ArrayRef;
1486
1487            assert_eq!(&sorted, &expected);
1488        }
1489
1490        // for List
1491        let input = Arc::new(ListArray::from_iter_primitive::<T, _, _>(data.clone()));
1492        let sorted = match limit {
1493            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1494            _ => sort(&(input as ArrayRef), options).unwrap(),
1495        };
1496        let expected = Arc::new(ListArray::from_iter_primitive::<T, _, _>(
1497            expected_data.clone(),
1498        )) as ArrayRef;
1499
1500        assert_eq!(&sorted, &expected);
1501
1502        // for ListView
1503        let input = Arc::new(ListViewArray::from_iter_primitive::<T, _, _>(data.clone()));
1504        let sorted = match limit {
1505            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1506            _ => sort(&(input as ArrayRef), options).unwrap(),
1507        };
1508        let expected = Arc::new(ListViewArray::from_iter_primitive::<T, _, _>(
1509            expected_data.clone(),
1510        )) as ArrayRef;
1511        assert_eq!(&sorted, &expected);
1512
1513        // for LargeList
1514        let input = Arc::new(LargeListArray::from_iter_primitive::<T, _, _>(data.clone()));
1515        let sorted = match limit {
1516            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1517            _ => sort(&(input as ArrayRef), options).unwrap(),
1518        };
1519        let expected = Arc::new(LargeListArray::from_iter_primitive::<T, _, _>(
1520            expected_data.clone(),
1521        )) as ArrayRef;
1522        assert_eq!(&sorted, &expected);
1523
1524        // for LargeListView
1525        let input = Arc::new(LargeListViewArray::from_iter_primitive::<T, _, _>(data));
1526        let sorted = match limit {
1527            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1528            _ => sort(&(input as ArrayRef), options).unwrap(),
1529        };
1530        let expected = Arc::new(LargeListViewArray::from_iter_primitive::<T, _, _>(
1531            expected_data,
1532        )) as ArrayRef;
1533        assert_eq!(&sorted, &expected);
1534    }
1535
1536    fn test_lex_sort_arrays(
1537        input: Vec<SortColumn>,
1538        expected_output: Vec<ArrayRef>,
1539        limit: Option<usize>,
1540    ) {
1541        let sorted = lexsort(&input, limit).unwrap();
1542
1543        for (result, expected) in sorted.iter().zip(expected_output.iter()) {
1544            assert_eq!(result, expected);
1545        }
1546    }
1547
1548    /// slice all arrays in expected_output to offset/length
1549    fn slice_arrays(expected_output: Vec<ArrayRef>, offset: usize, length: usize) -> Vec<ArrayRef> {
1550        expected_output
1551            .into_iter()
1552            .map(|array| array.slice(offset, length))
1553            .collect()
1554    }
1555
1556    fn test_sort_binary_arrays(
1557        data: Vec<Option<Vec<u8>>>,
1558        options: Option<SortOptions>,
1559        limit: Option<usize>,
1560        expected_data: Vec<Option<Vec<u8>>>,
1561        fixed_length: Option<i32>,
1562    ) {
1563        // Fixed size binary array
1564        if let Some(length) = fixed_length {
1565            let input = Arc::new(
1566                FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.iter().cloned(), length)
1567                    .unwrap(),
1568            );
1569            let sorted = match limit {
1570                Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1571                None => sort(&(input as ArrayRef), options).unwrap(),
1572            };
1573            let expected = Arc::new(
1574                FixedSizeBinaryArray::try_from_sparse_iter_with_size(
1575                    expected_data.iter().cloned(),
1576                    length,
1577                )
1578                .unwrap(),
1579            ) as ArrayRef;
1580
1581            assert_eq!(&sorted, &expected);
1582        }
1583
1584        // Generic size binary array
1585        fn make_generic_binary_array<S: OffsetSizeTrait>(
1586            data: &[Option<Vec<u8>>],
1587        ) -> Arc<GenericBinaryArray<S>> {
1588            Arc::new(GenericBinaryArray::<S>::from_opt_vec(
1589                data.iter()
1590                    .map(|binary| binary.as_ref().map(Vec::as_slice))
1591                    .collect(),
1592            ))
1593        }
1594
1595        // BinaryArray
1596        let input = make_generic_binary_array::<i32>(&data);
1597        let sorted = match limit {
1598            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1599            None => sort(&(input as ArrayRef), options).unwrap(),
1600        };
1601        let expected = make_generic_binary_array::<i32>(&expected_data) as ArrayRef;
1602        assert_eq!(&sorted, &expected);
1603
1604        // LargeBinaryArray
1605        let input = make_generic_binary_array::<i64>(&data);
1606        let sorted = match limit {
1607            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
1608            None => sort(&(input as ArrayRef), options).unwrap(),
1609        };
1610        let expected = make_generic_binary_array::<i64>(&expected_data) as ArrayRef;
1611        assert_eq!(&sorted, &expected);
1612    }
1613
1614    #[test]
1615    fn test_sort_to_indices_primitives() {
1616        test_sort_to_indices_primitive_arrays::<Int8Type>(
1617            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1618            None,
1619            None,
1620            vec![0, 5, 3, 1, 4, 2],
1621        );
1622        test_sort_to_indices_primitive_arrays::<Int16Type>(
1623            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1624            None,
1625            None,
1626            vec![0, 5, 3, 1, 4, 2],
1627        );
1628        test_sort_to_indices_primitive_arrays::<Int32Type>(
1629            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1630            None,
1631            None,
1632            vec![0, 5, 3, 1, 4, 2],
1633        );
1634        test_sort_to_indices_primitive_arrays::<Int64Type>(
1635            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1636            None,
1637            None,
1638            vec![0, 5, 3, 1, 4, 2],
1639        );
1640        test_sort_to_indices_primitive_arrays::<Float16Type>(
1641            vec![
1642                None,
1643                Some(f16::from_f32(-0.05)),
1644                Some(f16::from_f32(2.225)),
1645                Some(f16::from_f32(-1.01)),
1646                Some(f16::from_f32(-0.05)),
1647                None,
1648            ],
1649            None,
1650            None,
1651            vec![0, 5, 3, 1, 4, 2],
1652        );
1653        test_sort_to_indices_primitive_arrays::<Float32Type>(
1654            vec![
1655                None,
1656                Some(-0.05),
1657                Some(2.225),
1658                Some(-1.01),
1659                Some(-0.05),
1660                None,
1661            ],
1662            None,
1663            None,
1664            vec![0, 5, 3, 1, 4, 2],
1665        );
1666        test_sort_to_indices_primitive_arrays::<Float64Type>(
1667            vec![
1668                None,
1669                Some(-0.05),
1670                Some(2.225),
1671                Some(-1.01),
1672                Some(-0.05),
1673                None,
1674            ],
1675            None,
1676            None,
1677            vec![0, 5, 3, 1, 4, 2],
1678        );
1679
1680        // descending
1681        test_sort_to_indices_primitive_arrays::<Int8Type>(
1682            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1683            Some(SortOptions {
1684                descending: true,
1685                nulls_first: false,
1686            }),
1687            None,
1688            vec![2, 1, 4, 3, 0, 5],
1689        );
1690
1691        test_sort_to_indices_primitive_arrays::<Int16Type>(
1692            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1693            Some(SortOptions {
1694                descending: true,
1695                nulls_first: false,
1696            }),
1697            None,
1698            vec![2, 1, 4, 3, 0, 5],
1699        );
1700
1701        test_sort_to_indices_primitive_arrays::<Int32Type>(
1702            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1703            Some(SortOptions {
1704                descending: true,
1705                nulls_first: false,
1706            }),
1707            None,
1708            vec![2, 1, 4, 3, 0, 5],
1709        );
1710
1711        test_sort_to_indices_primitive_arrays::<Int64Type>(
1712            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1713            Some(SortOptions {
1714                descending: true,
1715                nulls_first: false,
1716            }),
1717            None,
1718            vec![2, 1, 4, 3, 0, 5],
1719        );
1720
1721        test_sort_to_indices_primitive_arrays::<Float16Type>(
1722            vec![
1723                None,
1724                Some(f16::from_f32(0.005)),
1725                Some(f16::from_f32(20.22)),
1726                Some(f16::from_f32(-10.3)),
1727                Some(f16::from_f32(0.005)),
1728                None,
1729            ],
1730            Some(SortOptions {
1731                descending: true,
1732                nulls_first: false,
1733            }),
1734            None,
1735            vec![2, 1, 4, 3, 0, 5],
1736        );
1737
1738        test_sort_to_indices_primitive_arrays::<Float32Type>(
1739            vec![
1740                None,
1741                Some(0.005),
1742                Some(20.22),
1743                Some(-10.3),
1744                Some(0.005),
1745                None,
1746            ],
1747            Some(SortOptions {
1748                descending: true,
1749                nulls_first: false,
1750            }),
1751            None,
1752            vec![2, 1, 4, 3, 0, 5],
1753        );
1754
1755        test_sort_to_indices_primitive_arrays::<Float64Type>(
1756            vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(0.0), None],
1757            Some(SortOptions {
1758                descending: true,
1759                nulls_first: false,
1760            }),
1761            None,
1762            vec![2, 1, 4, 3, 0, 5],
1763        );
1764
1765        // descending, nulls first
1766        test_sort_to_indices_primitive_arrays::<Int8Type>(
1767            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1768            Some(SortOptions {
1769                descending: true,
1770                nulls_first: true,
1771            }),
1772            None,
1773            vec![0, 5, 2, 1, 4, 3], // [5, 0, 2, 4, 1, 3]
1774        );
1775
1776        test_sort_to_indices_primitive_arrays::<Int16Type>(
1777            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1778            Some(SortOptions {
1779                descending: true,
1780                nulls_first: true,
1781            }),
1782            None,
1783            vec![0, 5, 2, 1, 4, 3], // [5, 0, 2, 4, 1, 3]
1784        );
1785
1786        test_sort_to_indices_primitive_arrays::<Int32Type>(
1787            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1788            Some(SortOptions {
1789                descending: true,
1790                nulls_first: true,
1791            }),
1792            None,
1793            vec![0, 5, 2, 1, 4, 3],
1794        );
1795
1796        test_sort_to_indices_primitive_arrays::<Int64Type>(
1797            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
1798            Some(SortOptions {
1799                descending: true,
1800                nulls_first: true,
1801            }),
1802            None,
1803            vec![0, 5, 2, 1, 4, 3],
1804        );
1805
1806        test_sort_to_indices_primitive_arrays::<Float16Type>(
1807            vec![
1808                None,
1809                Some(f16::from_f32(0.1)),
1810                Some(f16::from_f32(0.2)),
1811                Some(f16::from_f32(-1.3)),
1812                Some(f16::from_f32(0.01)),
1813                None,
1814            ],
1815            Some(SortOptions {
1816                descending: true,
1817                nulls_first: true,
1818            }),
1819            None,
1820            vec![0, 5, 2, 1, 4, 3],
1821        );
1822
1823        test_sort_to_indices_primitive_arrays::<Float32Type>(
1824            vec![None, Some(0.1), Some(0.2), Some(-1.3), Some(0.01), None],
1825            Some(SortOptions {
1826                descending: true,
1827                nulls_first: true,
1828            }),
1829            None,
1830            vec![0, 5, 2, 1, 4, 3],
1831        );
1832
1833        test_sort_to_indices_primitive_arrays::<Float64Type>(
1834            vec![None, Some(10.1), Some(100.2), Some(-1.3), Some(10.01), None],
1835            Some(SortOptions {
1836                descending: true,
1837                nulls_first: true,
1838            }),
1839            None,
1840            vec![0, 5, 2, 1, 4, 3],
1841        );
1842
1843        // valid values less than limit with extra nulls
1844        test_sort_to_indices_primitive_arrays::<Float64Type>(
1845            vec![Some(2.0), None, None, Some(1.0)],
1846            Some(SortOptions {
1847                descending: false,
1848                nulls_first: false,
1849            }),
1850            Some(3),
1851            vec![3, 0, 1],
1852        );
1853
1854        test_sort_to_indices_primitive_arrays::<Float64Type>(
1855            vec![Some(2.0), None, None, Some(1.0)],
1856            Some(SortOptions {
1857                descending: false,
1858                nulls_first: true,
1859            }),
1860            Some(3),
1861            vec![1, 2, 3],
1862        );
1863
1864        // more nulls than limit
1865        test_sort_to_indices_primitive_arrays::<Float64Type>(
1866            vec![Some(1.0), None, None, None],
1867            Some(SortOptions {
1868                descending: false,
1869                nulls_first: true,
1870            }),
1871            Some(2),
1872            vec![1, 2],
1873        );
1874
1875        test_sort_to_indices_primitive_arrays::<Float64Type>(
1876            vec![Some(1.0), None, None, None],
1877            Some(SortOptions {
1878                descending: false,
1879                nulls_first: false,
1880            }),
1881            Some(2),
1882            vec![0, 1],
1883        );
1884    }
1885
1886    #[test]
1887    fn test_sort_to_indices_primitive_more_nulls_than_limit() {
1888        test_sort_to_indices_primitive_arrays::<Int32Type>(
1889            vec![None, None, Some(3), None, Some(1), None, Some(2)],
1890            Some(SortOptions {
1891                descending: false,
1892                nulls_first: false,
1893            }),
1894            Some(2),
1895            vec![4, 6],
1896        );
1897    }
1898
1899    #[test]
1900    fn test_sort_boolean() {
1901        // boolean
1902        test_sort_to_indices_boolean_arrays(
1903            vec![None, Some(false), Some(true), Some(true), Some(false), None],
1904            None,
1905            None,
1906            vec![0, 5, 1, 4, 2, 3],
1907        );
1908
1909        // boolean, descending
1910        test_sort_to_indices_boolean_arrays(
1911            vec![None, Some(false), Some(true), Some(true), Some(false), None],
1912            Some(SortOptions {
1913                descending: true,
1914                nulls_first: false,
1915            }),
1916            None,
1917            vec![2, 3, 1, 4, 0, 5],
1918        );
1919
1920        // boolean, descending, nulls first
1921        test_sort_to_indices_boolean_arrays(
1922            vec![None, Some(false), Some(true), Some(true), Some(false), None],
1923            Some(SortOptions {
1924                descending: true,
1925                nulls_first: true,
1926            }),
1927            None,
1928            vec![0, 5, 2, 3, 1, 4],
1929        );
1930
1931        // boolean, descending, nulls first, limit
1932        test_sort_to_indices_boolean_arrays(
1933            vec![None, Some(false), Some(true), Some(true), Some(false), None],
1934            Some(SortOptions {
1935                descending: true,
1936                nulls_first: true,
1937            }),
1938            Some(3),
1939            vec![0, 5, 2],
1940        );
1941
1942        // valid values less than limit with extra nulls
1943        test_sort_to_indices_boolean_arrays(
1944            vec![Some(true), None, None, Some(false)],
1945            Some(SortOptions {
1946                descending: false,
1947                nulls_first: false,
1948            }),
1949            Some(3),
1950            vec![3, 0, 1],
1951        );
1952
1953        test_sort_to_indices_boolean_arrays(
1954            vec![Some(true), None, None, Some(false)],
1955            Some(SortOptions {
1956                descending: false,
1957                nulls_first: true,
1958            }),
1959            Some(3),
1960            vec![1, 2, 3],
1961        );
1962
1963        // more nulls than limit
1964        test_sort_to_indices_boolean_arrays(
1965            vec![Some(true), None, None, None],
1966            Some(SortOptions {
1967                descending: false,
1968                nulls_first: true,
1969            }),
1970            Some(2),
1971            vec![1, 2],
1972        );
1973
1974        test_sort_to_indices_boolean_arrays(
1975            vec![Some(true), None, None, None],
1976            Some(SortOptions {
1977                descending: false,
1978                nulls_first: false,
1979            }),
1980            Some(2),
1981            vec![0, 1],
1982        );
1983    }
1984
1985    /// Test sort boolean on each permutation of with/without limit and GenericListArray/FixedSizeListArray
1986    ///
1987    /// The input data must have the same length for all list items so that we can test FixedSizeListArray
1988    ///
1989    fn test_every_config_sort_boolean_list_arrays(
1990        data: Vec<Option<Vec<Option<bool>>>>,
1991        options: Option<SortOptions>,
1992        expected_data: Vec<Option<Vec<Option<bool>>>>,
1993    ) {
1994        let first_length = data
1995            .iter()
1996            .find_map(|x| x.as_ref().map(|x| x.len()))
1997            .unwrap_or(0);
1998        let first_non_match_length = data
1999            .iter()
2000            .map(|x| x.as_ref().map(|x| x.len()).unwrap_or(first_length))
2001            .position(|x| x != first_length);
2002
2003        assert_eq!(
2004            first_non_match_length, None,
2005            "All list items should have the same length {first_length}, input data is invalid"
2006        );
2007
2008        let first_non_match_length = expected_data
2009            .iter()
2010            .map(|x| x.as_ref().map(|x| x.len()).unwrap_or(first_length))
2011            .position(|x| x != first_length);
2012
2013        assert_eq!(
2014            first_non_match_length, None,
2015            "All list items should have the same length {first_length}, expected data is invalid"
2016        );
2017
2018        let limit = expected_data.len().saturating_div(2);
2019
2020        for &with_limit in &[false, true] {
2021            let (limit, expected_data) = if with_limit {
2022                (
2023                    Some(limit),
2024                    expected_data.iter().take(limit).cloned().collect(),
2025                )
2026            } else {
2027                (None, expected_data.clone())
2028            };
2029
2030            for &fixed_length in &[None, Some(first_length as i32)] {
2031                test_sort_boolean_list_arrays(
2032                    data.clone(),
2033                    options,
2034                    limit,
2035                    expected_data.clone(),
2036                    fixed_length,
2037                );
2038            }
2039        }
2040    }
2041
2042    fn test_sort_boolean_list_arrays(
2043        data: Vec<Option<Vec<Option<bool>>>>,
2044        options: Option<SortOptions>,
2045        limit: Option<usize>,
2046        expected_data: Vec<Option<Vec<Option<bool>>>>,
2047        fixed_length: Option<i32>,
2048    ) {
2049        fn build_fixed_boolean_list_array(
2050            data: Vec<Option<Vec<Option<bool>>>>,
2051            fixed_length: i32,
2052        ) -> ArrayRef {
2053            let mut builder = FixedSizeListBuilder::new(
2054                BooleanBuilder::with_capacity(fixed_length as usize),
2055                fixed_length,
2056            );
2057            for sublist in data {
2058                match sublist {
2059                    Some(sublist) => {
2060                        builder.values().extend(sublist);
2061                        builder.append(true);
2062                    }
2063                    None => {
2064                        builder
2065                            .values()
2066                            .extend(std::iter::repeat_n(None, fixed_length as usize));
2067                        builder.append(false);
2068                    }
2069                }
2070            }
2071            Arc::new(builder.finish()) as ArrayRef
2072        }
2073
2074        fn build_generic_boolean_list_array<OffsetSize: OffsetSizeTrait>(
2075            data: Vec<Option<Vec<Option<bool>>>>,
2076        ) -> ArrayRef {
2077            let mut builder = GenericListBuilder::<OffsetSize, _>::new(BooleanBuilder::new());
2078            builder.extend(data);
2079            Arc::new(builder.finish()) as ArrayRef
2080        }
2081
2082        // for FixedSizedList
2083        if let Some(length) = fixed_length {
2084            let input = build_fixed_boolean_list_array(data.clone(), length);
2085            let sorted = match limit {
2086                Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
2087                _ => sort(&(input as ArrayRef), options).unwrap(),
2088            };
2089            let expected = build_fixed_boolean_list_array(expected_data.clone(), length);
2090
2091            assert_eq!(&sorted, &expected);
2092        }
2093
2094        // for List
2095        let input = build_generic_boolean_list_array::<i32>(data.clone());
2096        let sorted = match limit {
2097            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
2098            _ => sort(&(input as ArrayRef), options).unwrap(),
2099        };
2100        let expected = build_generic_boolean_list_array::<i32>(expected_data.clone());
2101
2102        assert_eq!(&sorted, &expected);
2103
2104        // for LargeList
2105        let input = build_generic_boolean_list_array::<i64>(data.clone());
2106        let sorted = match limit {
2107            Some(_) => sort_limit(&(input as ArrayRef), options, limit).unwrap(),
2108            _ => sort(&(input as ArrayRef), options).unwrap(),
2109        };
2110        let expected = build_generic_boolean_list_array::<i64>(expected_data.clone());
2111
2112        assert_eq!(&sorted, &expected);
2113    }
2114
2115    #[test]
2116    fn test_sort_list_of_booleans() {
2117        // These are all the possible combinations of boolean values
2118        // There are 3^3 + 1 = 28 possible combinations (3 values to permutate - [true, false, null] and 1 None value)
2119        #[rustfmt::skip]
2120        let mut cases = vec![
2121            Some(vec![Some(true),  Some(true),  Some(true)]),
2122            Some(vec![Some(true),  Some(true),  Some(false)]),
2123            Some(vec![Some(true),  Some(true),  None]),
2124
2125            Some(vec![Some(true),  Some(false), Some(true)]),
2126            Some(vec![Some(true),  Some(false), Some(false)]),
2127            Some(vec![Some(true),  Some(false), None]),
2128
2129            Some(vec![Some(true),  None,        Some(true)]),
2130            Some(vec![Some(true),  None,        Some(false)]),
2131            Some(vec![Some(true),  None,        None]),
2132
2133            Some(vec![Some(false), Some(true),  Some(true)]),
2134            Some(vec![Some(false), Some(true),  Some(false)]),
2135            Some(vec![Some(false), Some(true),  None]),
2136
2137            Some(vec![Some(false), Some(false), Some(true)]),
2138            Some(vec![Some(false), Some(false), Some(false)]),
2139            Some(vec![Some(false), Some(false), None]),
2140
2141            Some(vec![Some(false), None,        Some(true)]),
2142            Some(vec![Some(false), None,        Some(false)]),
2143            Some(vec![Some(false), None,        None]),
2144
2145            Some(vec![None,        Some(true),  Some(true)]),
2146            Some(vec![None,        Some(true),  Some(false)]),
2147            Some(vec![None,        Some(true),  None]),
2148
2149            Some(vec![None,        Some(false), Some(true)]),
2150            Some(vec![None,        Some(false), Some(false)]),
2151            Some(vec![None,        Some(false), None]),
2152
2153            Some(vec![None,        None,        Some(true)]),
2154            Some(vec![None,        None,        Some(false)]),
2155            Some(vec![None,        None,        None]),
2156            None,
2157        ];
2158
2159        cases.shuffle(&mut StdRng::seed_from_u64(42));
2160
2161        // The order is false, true, null
2162        #[rustfmt::skip]
2163        let expected_descending_false_nulls_first_false = vec![
2164            Some(vec![Some(false), Some(false), Some(false)]),
2165            Some(vec![Some(false), Some(false), Some(true)]),
2166            Some(vec![Some(false), Some(false), None]),
2167
2168            Some(vec![Some(false), Some(true),  Some(false)]),
2169            Some(vec![Some(false), Some(true),  Some(true)]),
2170            Some(vec![Some(false), Some(true),  None]),
2171
2172            Some(vec![Some(false), None,        Some(false)]),
2173            Some(vec![Some(false), None,        Some(true)]),
2174            Some(vec![Some(false), None,        None]),
2175
2176            Some(vec![Some(true),  Some(false), Some(false)]),
2177            Some(vec![Some(true),  Some(false), Some(true)]),
2178            Some(vec![Some(true),  Some(false), None]),
2179
2180            Some(vec![Some(true),  Some(true),  Some(false)]),
2181            Some(vec![Some(true),  Some(true),  Some(true)]),
2182            Some(vec![Some(true),  Some(true),  None]),
2183
2184            Some(vec![Some(true),  None,        Some(false)]),
2185            Some(vec![Some(true),  None,        Some(true)]),
2186            Some(vec![Some(true),  None,        None]),
2187
2188            Some(vec![None,        Some(false), Some(false)]),
2189            Some(vec![None,        Some(false), Some(true)]),
2190            Some(vec![None,        Some(false), None]),
2191
2192            Some(vec![None,        Some(true),  Some(false)]),
2193            Some(vec![None,        Some(true),  Some(true)]),
2194            Some(vec![None,        Some(true),  None]),
2195
2196            Some(vec![None,        None,        Some(false)]),
2197            Some(vec![None,        None,        Some(true)]),
2198            Some(vec![None,        None,        None]),
2199            None,
2200        ];
2201        test_every_config_sort_boolean_list_arrays(
2202            cases.clone(),
2203            Some(SortOptions {
2204                descending: false,
2205                nulls_first: false,
2206            }),
2207            expected_descending_false_nulls_first_false,
2208        );
2209
2210        // The order is null, false, true
2211        #[rustfmt::skip]
2212        let expected_descending_false_nulls_first_true = vec![
2213            None,
2214
2215            Some(vec![None,        None,        None]),
2216            Some(vec![None,        None,        Some(false)]),
2217            Some(vec![None,        None,        Some(true)]),
2218
2219            Some(vec![None,        Some(false), None]),
2220            Some(vec![None,        Some(false), Some(false)]),
2221            Some(vec![None,        Some(false), Some(true)]),
2222
2223            Some(vec![None,        Some(true),  None]),
2224            Some(vec![None,        Some(true),  Some(false)]),
2225            Some(vec![None,        Some(true),  Some(true)]),
2226
2227            Some(vec![Some(false), None,        None]),
2228            Some(vec![Some(false), None,        Some(false)]),
2229            Some(vec![Some(false), None,        Some(true)]),
2230
2231            Some(vec![Some(false), Some(false), None]),
2232            Some(vec![Some(false), Some(false), Some(false)]),
2233            Some(vec![Some(false), Some(false), Some(true)]),
2234
2235            Some(vec![Some(false), Some(true),  None]),
2236            Some(vec![Some(false), Some(true),  Some(false)]),
2237            Some(vec![Some(false), Some(true),  Some(true)]),
2238
2239            Some(vec![Some(true),  None,        None]),
2240            Some(vec![Some(true),  None,        Some(false)]),
2241            Some(vec![Some(true),  None,        Some(true)]),
2242
2243            Some(vec![Some(true),  Some(false), None]),
2244            Some(vec![Some(true),  Some(false), Some(false)]),
2245            Some(vec![Some(true),  Some(false), Some(true)]),
2246
2247            Some(vec![Some(true),  Some(true),  None]),
2248            Some(vec![Some(true),  Some(true),  Some(false)]),
2249            Some(vec![Some(true),  Some(true),  Some(true)]),
2250        ];
2251
2252        test_every_config_sort_boolean_list_arrays(
2253            cases.clone(),
2254            Some(SortOptions {
2255                descending: false,
2256                nulls_first: true,
2257            }),
2258            expected_descending_false_nulls_first_true,
2259        );
2260
2261        // The order is true, false, null
2262        #[rustfmt::skip]
2263        let expected_descending_true_nulls_first_false = vec![
2264            Some(vec![Some(true),  Some(true),  Some(true)]),
2265            Some(vec![Some(true),  Some(true),  Some(false)]),
2266            Some(vec![Some(true),  Some(true),  None]),
2267
2268            Some(vec![Some(true),  Some(false), Some(true)]),
2269            Some(vec![Some(true),  Some(false), Some(false)]),
2270            Some(vec![Some(true),  Some(false), None]),
2271
2272            Some(vec![Some(true),  None,        Some(true)]),
2273            Some(vec![Some(true),  None,        Some(false)]),
2274            Some(vec![Some(true),  None,        None]),
2275
2276            Some(vec![Some(false), Some(true),  Some(true)]),
2277            Some(vec![Some(false), Some(true),  Some(false)]),
2278            Some(vec![Some(false), Some(true),  None]),
2279
2280            Some(vec![Some(false), Some(false), Some(true)]),
2281            Some(vec![Some(false), Some(false), Some(false)]),
2282            Some(vec![Some(false), Some(false), None]),
2283
2284            Some(vec![Some(false), None,        Some(true)]),
2285            Some(vec![Some(false), None,        Some(false)]),
2286            Some(vec![Some(false), None,        None]),
2287
2288            Some(vec![None,        Some(true),  Some(true)]),
2289            Some(vec![None,        Some(true),  Some(false)]),
2290            Some(vec![None,        Some(true),  None]),
2291
2292            Some(vec![None,        Some(false), Some(true)]),
2293            Some(vec![None,        Some(false), Some(false)]),
2294            Some(vec![None,        Some(false), None]),
2295
2296            Some(vec![None,        None,        Some(true)]),
2297            Some(vec![None,        None,        Some(false)]),
2298            Some(vec![None,        None,        None]),
2299
2300            None,
2301        ];
2302        test_every_config_sort_boolean_list_arrays(
2303            cases.clone(),
2304            Some(SortOptions {
2305                descending: true,
2306                nulls_first: false,
2307            }),
2308            expected_descending_true_nulls_first_false,
2309        );
2310
2311        // The order is null, true, false
2312        #[rustfmt::skip]
2313        let expected_descending_true_nulls_first_true = vec![
2314            None,
2315
2316            Some(vec![None,        None,        None]),
2317            Some(vec![None,        None,        Some(true)]),
2318            Some(vec![None,        None,        Some(false)]),
2319
2320            Some(vec![None,        Some(true),  None]),
2321            Some(vec![None,        Some(true),  Some(true)]),
2322            Some(vec![None,        Some(true),  Some(false)]),
2323
2324            Some(vec![None,        Some(false), None]),
2325            Some(vec![None,        Some(false), Some(true)]),
2326            Some(vec![None,        Some(false), Some(false)]),
2327
2328            Some(vec![Some(true),  None,        None]),
2329            Some(vec![Some(true),  None,        Some(true)]),
2330            Some(vec![Some(true),  None,        Some(false)]),
2331
2332            Some(vec![Some(true),  Some(true),  None]),
2333            Some(vec![Some(true),  Some(true),  Some(true)]),
2334            Some(vec![Some(true),  Some(true),  Some(false)]),
2335
2336            Some(vec![Some(true),  Some(false), None]),
2337            Some(vec![Some(true),  Some(false), Some(true)]),
2338            Some(vec![Some(true),  Some(false), Some(false)]),
2339
2340            Some(vec![Some(false), None,        None]),
2341            Some(vec![Some(false), None,        Some(true)]),
2342            Some(vec![Some(false), None,        Some(false)]),
2343
2344            Some(vec![Some(false), Some(true),  None]),
2345            Some(vec![Some(false), Some(true),  Some(true)]),
2346            Some(vec![Some(false), Some(true),  Some(false)]),
2347
2348            Some(vec![Some(false), Some(false), None]),
2349            Some(vec![Some(false), Some(false), Some(true)]),
2350            Some(vec![Some(false), Some(false), Some(false)]),
2351        ];
2352        // Testing with limit false and fixed_length None
2353        test_every_config_sort_boolean_list_arrays(
2354            cases.clone(),
2355            Some(SortOptions {
2356                descending: true,
2357                nulls_first: true,
2358            }),
2359            expected_descending_true_nulls_first_true,
2360        );
2361    }
2362
2363    fn test_sort_indices_decimal<T: DecimalType>(precision: u8, scale: i8) {
2364        // decimal default
2365        test_sort_to_indices_decimal_array::<T>(
2366            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2367            None,
2368            None,
2369            vec![0, 6, 4, 2, 3, 5, 1],
2370            precision,
2371            scale,
2372        );
2373        // decimal descending
2374        test_sort_to_indices_decimal_array::<T>(
2375            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2376            Some(SortOptions {
2377                descending: true,
2378                nulls_first: false,
2379            }),
2380            None,
2381            vec![1, 5, 3, 2, 4, 0, 6],
2382            precision,
2383            scale,
2384        );
2385        // decimal null_first and descending
2386        test_sort_to_indices_decimal_array::<T>(
2387            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2388            Some(SortOptions {
2389                descending: true,
2390                nulls_first: true,
2391            }),
2392            None,
2393            vec![0, 6, 1, 5, 3, 2, 4],
2394            precision,
2395            scale,
2396        );
2397        // decimal null_first
2398        test_sort_to_indices_decimal_array::<T>(
2399            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2400            Some(SortOptions {
2401                descending: false,
2402                nulls_first: true,
2403            }),
2404            None,
2405            vec![0, 6, 4, 2, 3, 5, 1],
2406            precision,
2407            scale,
2408        );
2409        // limit
2410        test_sort_to_indices_decimal_array::<T>(
2411            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2412            None,
2413            Some(3),
2414            vec![0, 6, 4],
2415            precision,
2416            scale,
2417        );
2418        // limit descending
2419        test_sort_to_indices_decimal_array::<T>(
2420            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2421            Some(SortOptions {
2422                descending: true,
2423                nulls_first: false,
2424            }),
2425            Some(3),
2426            vec![1, 5, 3],
2427            precision,
2428            scale,
2429        );
2430        // limit descending null_first
2431        test_sort_to_indices_decimal_array::<T>(
2432            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2433            Some(SortOptions {
2434                descending: true,
2435                nulls_first: true,
2436            }),
2437            Some(3),
2438            vec![0, 6, 1],
2439            precision,
2440            scale,
2441        );
2442        // limit null_first
2443        test_sort_to_indices_decimal_array::<T>(
2444            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2445            Some(SortOptions {
2446                descending: false,
2447                nulls_first: true,
2448            }),
2449            Some(3),
2450            vec![0, 6, 4],
2451            precision,
2452            scale,
2453        );
2454    }
2455
2456    #[test]
2457    fn test_sort_indices_decimal32() {
2458        test_sort_indices_decimal::<Decimal32Type>(8, 3);
2459    }
2460
2461    #[test]
2462    fn test_sort_indices_decimal64() {
2463        test_sort_indices_decimal::<Decimal64Type>(17, 5);
2464    }
2465
2466    #[test]
2467    fn test_sort_indices_decimal128() {
2468        test_sort_indices_decimal::<Decimal128Type>(23, 6);
2469    }
2470
2471    #[test]
2472    fn test_sort_indices_decimal256() {
2473        test_sort_indices_decimal::<Decimal256Type>(53, 6);
2474    }
2475
2476    #[test]
2477    fn test_sort_indices_decimal256_max_min() {
2478        let data = vec![
2479            None,
2480            Some(i256::MIN),
2481            Some(i256::from_i128(1)),
2482            Some(i256::MAX),
2483            Some(i256::from_i128(-1)),
2484        ];
2485        test_sort_to_indices_decimal256_array(
2486            data.clone(),
2487            Some(SortOptions {
2488                descending: false,
2489                nulls_first: true,
2490            }),
2491            None,
2492            vec![0, 1, 4, 2, 3],
2493        );
2494
2495        test_sort_to_indices_decimal256_array(
2496            data.clone(),
2497            Some(SortOptions {
2498                descending: true,
2499                nulls_first: true,
2500            }),
2501            None,
2502            vec![0, 3, 2, 4, 1],
2503        );
2504
2505        test_sort_to_indices_decimal256_array(
2506            data.clone(),
2507            Some(SortOptions {
2508                descending: false,
2509                nulls_first: true,
2510            }),
2511            Some(4),
2512            vec![0, 1, 4, 2],
2513        );
2514
2515        test_sort_to_indices_decimal256_array(
2516            data.clone(),
2517            Some(SortOptions {
2518                descending: true,
2519                nulls_first: true,
2520            }),
2521            Some(4),
2522            vec![0, 3, 2, 4],
2523        );
2524    }
2525
2526    fn test_sort_decimal<T: DecimalType>(precision: u8, scale: i8) {
2527        // decimal default
2528        test_sort_decimal_array::<T>(
2529            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2530            None,
2531            None,
2532            vec![None, None, Some(1), Some(2), Some(3), Some(4), Some(5)],
2533            precision,
2534            scale,
2535        );
2536        // decimal descending
2537        test_sort_decimal_array::<T>(
2538            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2539            Some(SortOptions {
2540                descending: true,
2541                nulls_first: false,
2542            }),
2543            None,
2544            vec![Some(5), Some(4), Some(3), Some(2), Some(1), None, None],
2545            precision,
2546            scale,
2547        );
2548        // decimal null_first and descending
2549        test_sort_decimal_array::<T>(
2550            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2551            Some(SortOptions {
2552                descending: true,
2553                nulls_first: true,
2554            }),
2555            None,
2556            vec![None, None, Some(5), Some(4), Some(3), Some(2), Some(1)],
2557            precision,
2558            scale,
2559        );
2560        // decimal null_first
2561        test_sort_decimal_array::<T>(
2562            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2563            Some(SortOptions {
2564                descending: false,
2565                nulls_first: true,
2566            }),
2567            None,
2568            vec![None, None, Some(1), Some(2), Some(3), Some(4), Some(5)],
2569            precision,
2570            scale,
2571        );
2572        // limit
2573        test_sort_decimal_array::<T>(
2574            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2575            None,
2576            Some(3),
2577            vec![None, None, Some(1)],
2578            precision,
2579            scale,
2580        );
2581        // limit descending
2582        test_sort_decimal_array::<T>(
2583            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2584            Some(SortOptions {
2585                descending: true,
2586                nulls_first: false,
2587            }),
2588            Some(3),
2589            vec![Some(5), Some(4), Some(3)],
2590            precision,
2591            scale,
2592        );
2593        // limit descending null_first
2594        test_sort_decimal_array::<T>(
2595            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2596            Some(SortOptions {
2597                descending: true,
2598                nulls_first: true,
2599            }),
2600            Some(3),
2601            vec![None, None, Some(5)],
2602            precision,
2603            scale,
2604        );
2605        // limit null_first
2606        test_sort_decimal_array::<T>(
2607            vec![None, Some(5), Some(2), Some(3), Some(1), Some(4), None],
2608            Some(SortOptions {
2609                descending: false,
2610                nulls_first: true,
2611            }),
2612            Some(3),
2613            vec![None, None, Some(1)],
2614            precision,
2615            scale,
2616        );
2617    }
2618
2619    #[test]
2620    fn test_sort_decimal32() {
2621        test_sort_decimal::<Decimal32Type>(8, 3);
2622    }
2623
2624    #[test]
2625    fn test_sort_decimal64() {
2626        test_sort_decimal::<Decimal64Type>(17, 5);
2627    }
2628
2629    #[test]
2630    fn test_sort_decimal128() {
2631        test_sort_decimal::<Decimal128Type>(23, 6);
2632    }
2633
2634    #[test]
2635    fn test_sort_decimal256() {
2636        test_sort_decimal::<Decimal256Type>(53, 6);
2637    }
2638
2639    #[test]
2640    fn test_sort_decimal256_max_min() {
2641        test_sort_decimal256_array(
2642            vec![
2643                None,
2644                Some(i256::MIN),
2645                Some(i256::from_i128(1)),
2646                Some(i256::MAX),
2647                Some(i256::from_i128(-1)),
2648                None,
2649            ],
2650            Some(SortOptions {
2651                descending: false,
2652                nulls_first: true,
2653            }),
2654            None,
2655            vec![
2656                None,
2657                None,
2658                Some(i256::MIN),
2659                Some(i256::from_i128(-1)),
2660                Some(i256::from_i128(1)),
2661                Some(i256::MAX),
2662            ],
2663        );
2664
2665        test_sort_decimal256_array(
2666            vec![
2667                None,
2668                Some(i256::MIN),
2669                Some(i256::from_i128(1)),
2670                Some(i256::MAX),
2671                Some(i256::from_i128(-1)),
2672                None,
2673            ],
2674            Some(SortOptions {
2675                descending: true,
2676                nulls_first: true,
2677            }),
2678            None,
2679            vec![
2680                None,
2681                None,
2682                Some(i256::MAX),
2683                Some(i256::from_i128(1)),
2684                Some(i256::from_i128(-1)),
2685                Some(i256::MIN),
2686            ],
2687        );
2688
2689        test_sort_decimal256_array(
2690            vec![
2691                None,
2692                Some(i256::MIN),
2693                Some(i256::from_i128(1)),
2694                Some(i256::MAX),
2695                Some(i256::from_i128(-1)),
2696                None,
2697            ],
2698            Some(SortOptions {
2699                descending: false,
2700                nulls_first: true,
2701            }),
2702            Some(4),
2703            vec![None, None, Some(i256::MIN), Some(i256::from_i128(-1))],
2704        );
2705
2706        test_sort_decimal256_array(
2707            vec![
2708                None,
2709                Some(i256::MIN),
2710                Some(i256::from_i128(1)),
2711                Some(i256::MAX),
2712                Some(i256::from_i128(-1)),
2713                None,
2714            ],
2715            Some(SortOptions {
2716                descending: true,
2717                nulls_first: true,
2718            }),
2719            Some(4),
2720            vec![None, None, Some(i256::MAX), Some(i256::from_i128(1))],
2721        );
2722    }
2723
2724    #[test]
2725    fn test_sort_primitives() {
2726        // default case
2727        test_sort_primitive_arrays::<UInt8Type>(
2728            vec![None, Some(3), Some(5), Some(2), Some(3), None],
2729            None,
2730            None,
2731            vec![None, None, Some(2), Some(3), Some(3), Some(5)],
2732        );
2733        test_sort_primitive_arrays::<UInt16Type>(
2734            vec![None, Some(3), Some(5), Some(2), Some(3), None],
2735            None,
2736            None,
2737            vec![None, None, Some(2), Some(3), Some(3), Some(5)],
2738        );
2739        test_sort_primitive_arrays::<UInt32Type>(
2740            vec![None, Some(3), Some(5), Some(2), Some(3), None],
2741            None,
2742            None,
2743            vec![None, None, Some(2), Some(3), Some(3), Some(5)],
2744        );
2745        test_sort_primitive_arrays::<UInt64Type>(
2746            vec![None, Some(3), Some(5), Some(2), Some(3), None],
2747            None,
2748            None,
2749            vec![None, None, Some(2), Some(3), Some(3), Some(5)],
2750        );
2751
2752        // descending
2753        test_sort_primitive_arrays::<Int8Type>(
2754            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2755            Some(SortOptions {
2756                descending: true,
2757                nulls_first: false,
2758            }),
2759            None,
2760            vec![Some(2), Some(0), Some(0), Some(-1), None, None],
2761        );
2762        test_sort_primitive_arrays::<Int16Type>(
2763            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2764            Some(SortOptions {
2765                descending: true,
2766                nulls_first: false,
2767            }),
2768            None,
2769            vec![Some(2), Some(0), Some(0), Some(-1), None, None],
2770        );
2771        test_sort_primitive_arrays::<Int32Type>(
2772            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2773            Some(SortOptions {
2774                descending: true,
2775                nulls_first: false,
2776            }),
2777            None,
2778            vec![Some(2), Some(0), Some(0), Some(-1), None, None],
2779        );
2780        test_sort_primitive_arrays::<Int16Type>(
2781            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2782            Some(SortOptions {
2783                descending: true,
2784                nulls_first: false,
2785            }),
2786            None,
2787            vec![Some(2), Some(0), Some(0), Some(-1), None, None],
2788        );
2789
2790        // descending, nulls first
2791        test_sort_primitive_arrays::<Int8Type>(
2792            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2793            Some(SortOptions {
2794                descending: true,
2795                nulls_first: true,
2796            }),
2797            None,
2798            vec![None, None, Some(2), Some(0), Some(0), Some(-1)],
2799        );
2800        test_sort_primitive_arrays::<Int16Type>(
2801            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2802            Some(SortOptions {
2803                descending: true,
2804                nulls_first: true,
2805            }),
2806            None,
2807            vec![None, None, Some(2), Some(0), Some(0), Some(-1)],
2808        );
2809        test_sort_primitive_arrays::<Int32Type>(
2810            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2811            Some(SortOptions {
2812                descending: true,
2813                nulls_first: true,
2814            }),
2815            None,
2816            vec![None, None, Some(2), Some(0), Some(0), Some(-1)],
2817        );
2818        test_sort_primitive_arrays::<Int64Type>(
2819            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2820            Some(SortOptions {
2821                descending: true,
2822                nulls_first: true,
2823            }),
2824            None,
2825            vec![None, None, Some(2), Some(0), Some(0), Some(-1)],
2826        );
2827
2828        test_sort_primitive_arrays::<Int64Type>(
2829            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2830            Some(SortOptions {
2831                descending: true,
2832                nulls_first: true,
2833            }),
2834            Some(3),
2835            vec![None, None, Some(2)],
2836        );
2837
2838        test_sort_primitive_arrays::<Float16Type>(
2839            vec![
2840                None,
2841                Some(f16::from_f32(0.0)),
2842                Some(f16::from_f32(2.0)),
2843                Some(f16::from_f32(-1.0)),
2844                Some(f16::from_f32(0.0)),
2845                None,
2846            ],
2847            Some(SortOptions {
2848                descending: true,
2849                nulls_first: true,
2850            }),
2851            None,
2852            vec![
2853                None,
2854                None,
2855                Some(f16::from_f32(2.0)),
2856                Some(f16::from_f32(0.0)),
2857                Some(f16::from_f32(0.0)),
2858                Some(f16::from_f32(-1.0)),
2859            ],
2860        );
2861
2862        test_sort_primitive_arrays::<Float32Type>(
2863            vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(0.0), None],
2864            Some(SortOptions {
2865                descending: true,
2866                nulls_first: true,
2867            }),
2868            None,
2869            vec![None, None, Some(2.0), Some(0.0), Some(0.0), Some(-1.0)],
2870        );
2871        test_sort_primitive_arrays::<Float64Type>(
2872            vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(f64::NAN), None],
2873            Some(SortOptions {
2874                descending: true,
2875                nulls_first: true,
2876            }),
2877            None,
2878            vec![None, None, Some(f64::NAN), Some(2.0), Some(0.0), Some(-1.0)],
2879        );
2880        test_sort_primitive_arrays::<Float64Type>(
2881            vec![Some(f64::NAN), Some(f64::NAN), Some(f64::NAN), Some(1.0)],
2882            Some(SortOptions {
2883                descending: true,
2884                nulls_first: true,
2885            }),
2886            None,
2887            vec![Some(f64::NAN), Some(f64::NAN), Some(f64::NAN), Some(1.0)],
2888        );
2889
2890        // int8 nulls first
2891        test_sort_primitive_arrays::<Int8Type>(
2892            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2893            Some(SortOptions {
2894                descending: false,
2895                nulls_first: true,
2896            }),
2897            None,
2898            vec![None, None, Some(-1), Some(0), Some(0), Some(2)],
2899        );
2900        test_sort_primitive_arrays::<Int16Type>(
2901            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2902            Some(SortOptions {
2903                descending: false,
2904                nulls_first: true,
2905            }),
2906            None,
2907            vec![None, None, Some(-1), Some(0), Some(0), Some(2)],
2908        );
2909        test_sort_primitive_arrays::<Int32Type>(
2910            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2911            Some(SortOptions {
2912                descending: false,
2913                nulls_first: true,
2914            }),
2915            None,
2916            vec![None, None, Some(-1), Some(0), Some(0), Some(2)],
2917        );
2918        test_sort_primitive_arrays::<Int64Type>(
2919            vec![None, Some(0), Some(2), Some(-1), Some(0), None],
2920            Some(SortOptions {
2921                descending: false,
2922                nulls_first: true,
2923            }),
2924            None,
2925            vec![None, None, Some(-1), Some(0), Some(0), Some(2)],
2926        );
2927        test_sort_primitive_arrays::<Float16Type>(
2928            vec![
2929                None,
2930                Some(f16::from_f32(0.0)),
2931                Some(f16::from_f32(2.0)),
2932                Some(f16::from_f32(-1.0)),
2933                Some(f16::from_f32(0.0)),
2934                None,
2935            ],
2936            Some(SortOptions {
2937                descending: false,
2938                nulls_first: true,
2939            }),
2940            None,
2941            vec![
2942                None,
2943                None,
2944                Some(f16::from_f32(-1.0)),
2945                Some(f16::from_f32(0.0)),
2946                Some(f16::from_f32(0.0)),
2947                Some(f16::from_f32(2.0)),
2948            ],
2949        );
2950        test_sort_primitive_arrays::<Float32Type>(
2951            vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(0.0), None],
2952            Some(SortOptions {
2953                descending: false,
2954                nulls_first: true,
2955            }),
2956            None,
2957            vec![None, None, Some(-1.0), Some(0.0), Some(0.0), Some(2.0)],
2958        );
2959        test_sort_primitive_arrays::<Float64Type>(
2960            vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(f64::NAN), None],
2961            Some(SortOptions {
2962                descending: false,
2963                nulls_first: true,
2964            }),
2965            None,
2966            vec![None, None, Some(-1.0), Some(0.0), Some(2.0), Some(f64::NAN)],
2967        );
2968        test_sort_primitive_arrays::<Float64Type>(
2969            vec![Some(f64::NAN), Some(f64::NAN), Some(f64::NAN), Some(1.0)],
2970            Some(SortOptions {
2971                descending: false,
2972                nulls_first: true,
2973            }),
2974            None,
2975            vec![Some(1.0), Some(f64::NAN), Some(f64::NAN), Some(f64::NAN)],
2976        );
2977
2978        // limit
2979        test_sort_primitive_arrays::<Float64Type>(
2980            vec![Some(f64::NAN), Some(f64::NAN), Some(f64::NAN), Some(1.0)],
2981            Some(SortOptions {
2982                descending: false,
2983                nulls_first: true,
2984            }),
2985            Some(2),
2986            vec![Some(1.0), Some(f64::NAN)],
2987        );
2988
2989        // limit with actual value
2990        test_sort_primitive_arrays::<Float64Type>(
2991            vec![Some(2.0), Some(4.0), Some(3.0), Some(1.0)],
2992            Some(SortOptions {
2993                descending: false,
2994                nulls_first: true,
2995            }),
2996            Some(3),
2997            vec![Some(1.0), Some(2.0), Some(3.0)],
2998        );
2999
3000        // valid values less than limit with extra nulls
3001        test_sort_primitive_arrays::<Float64Type>(
3002            vec![Some(2.0), None, None, Some(1.0)],
3003            Some(SortOptions {
3004                descending: false,
3005                nulls_first: false,
3006            }),
3007            Some(3),
3008            vec![Some(1.0), Some(2.0), None],
3009        );
3010
3011        test_sort_primitive_arrays::<Float64Type>(
3012            vec![Some(2.0), None, None, Some(1.0)],
3013            Some(SortOptions {
3014                descending: false,
3015                nulls_first: true,
3016            }),
3017            Some(3),
3018            vec![None, None, Some(1.0)],
3019        );
3020
3021        // more nulls than limit
3022        test_sort_primitive_arrays::<Float64Type>(
3023            vec![Some(2.0), None, None, None],
3024            Some(SortOptions {
3025                descending: false,
3026                nulls_first: true,
3027            }),
3028            Some(2),
3029            vec![None, None],
3030        );
3031
3032        test_sort_primitive_arrays::<Float64Type>(
3033            vec![Some(2.0), None, None, None],
3034            Some(SortOptions {
3035                descending: false,
3036                nulls_first: false,
3037            }),
3038            Some(2),
3039            vec![Some(2.0), None],
3040        );
3041    }
3042
3043    #[test]
3044    fn test_sort_to_indices_strings() {
3045        test_sort_to_indices_string_arrays(
3046            vec![
3047                None,
3048                Some("bad"),
3049                Some("sad"),
3050                None,
3051                Some("glad"),
3052                Some("-ad"),
3053            ],
3054            None,
3055            None,
3056            vec![0, 3, 5, 1, 4, 2],
3057        );
3058
3059        test_sort_to_indices_string_arrays(
3060            vec![
3061                None,
3062                Some("bad"),
3063                Some("sad"),
3064                None,
3065                Some("glad"),
3066                Some("-ad"),
3067            ],
3068            Some(SortOptions {
3069                descending: true,
3070                nulls_first: false,
3071            }),
3072            None,
3073            vec![2, 4, 1, 5, 0, 3],
3074        );
3075
3076        test_sort_to_indices_string_arrays(
3077            vec![
3078                None,
3079                Some("bad"),
3080                Some("sad"),
3081                None,
3082                Some("glad"),
3083                Some("-ad"),
3084            ],
3085            Some(SortOptions {
3086                descending: false,
3087                nulls_first: true,
3088            }),
3089            None,
3090            vec![0, 3, 5, 1, 4, 2],
3091        );
3092
3093        test_sort_to_indices_string_arrays(
3094            vec![
3095                None,
3096                Some("bad"),
3097                Some("sad"),
3098                None,
3099                Some("glad"),
3100                Some("-ad"),
3101            ],
3102            Some(SortOptions {
3103                descending: true,
3104                nulls_first: true,
3105            }),
3106            None,
3107            vec![0, 3, 2, 4, 1, 5],
3108        );
3109
3110        test_sort_to_indices_string_arrays(
3111            vec![
3112                None,
3113                Some("bad"),
3114                Some("sad"),
3115                None,
3116                Some("glad"),
3117                Some("-ad"),
3118            ],
3119            Some(SortOptions {
3120                descending: true,
3121                nulls_first: true,
3122            }),
3123            Some(3),
3124            vec![0, 3, 2],
3125        );
3126
3127        // valid values less than limit with extra nulls
3128        test_sort_to_indices_string_arrays(
3129            vec![Some("def"), None, None, Some("abc")],
3130            Some(SortOptions {
3131                descending: false,
3132                nulls_first: false,
3133            }),
3134            Some(3),
3135            vec![3, 0, 1],
3136        );
3137
3138        test_sort_to_indices_string_arrays(
3139            vec![Some("def"), None, None, Some("abc")],
3140            Some(SortOptions {
3141                descending: false,
3142                nulls_first: true,
3143            }),
3144            Some(3),
3145            vec![1, 2, 3],
3146        );
3147
3148        // more nulls than limit
3149        test_sort_to_indices_string_arrays(
3150            vec![Some("def"), None, None, None],
3151            Some(SortOptions {
3152                descending: false,
3153                nulls_first: true,
3154            }),
3155            Some(2),
3156            vec![1, 2],
3157        );
3158
3159        test_sort_to_indices_string_arrays(
3160            vec![Some("def"), None, None, None],
3161            Some(SortOptions {
3162                descending: false,
3163                nulls_first: false,
3164            }),
3165            Some(2),
3166            vec![0, 1],
3167        );
3168    }
3169
3170    #[test]
3171    fn test_sort_strings() {
3172        test_sort_string_arrays(
3173            vec![
3174                None,
3175                Some("bad"),
3176                Some("sad"),
3177                Some("long string longer than 12 bytes"),
3178                None,
3179                Some("glad"),
3180                Some("lang string longer than 12 bytes"),
3181                Some("-ad"),
3182            ],
3183            None,
3184            None,
3185            vec![
3186                None,
3187                None,
3188                Some("-ad"),
3189                Some("bad"),
3190                Some("glad"),
3191                Some("lang string longer than 12 bytes"),
3192                Some("long string longer than 12 bytes"),
3193                Some("sad"),
3194            ],
3195        );
3196
3197        test_sort_string_arrays(
3198            vec![
3199                None,
3200                Some("bad"),
3201                Some("sad"),
3202                Some("long string longer than 12 bytes"),
3203                None,
3204                Some("glad"),
3205                Some("lang string longer than 12 bytes"),
3206                Some("-ad"),
3207            ],
3208            Some(SortOptions {
3209                descending: true,
3210                nulls_first: false,
3211            }),
3212            None,
3213            vec![
3214                Some("sad"),
3215                Some("long string longer than 12 bytes"),
3216                Some("lang string longer than 12 bytes"),
3217                Some("glad"),
3218                Some("bad"),
3219                Some("-ad"),
3220                None,
3221                None,
3222            ],
3223        );
3224
3225        test_sort_string_arrays(
3226            vec![
3227                None,
3228                Some("bad"),
3229                Some("long string longer than 12 bytes"),
3230                Some("sad"),
3231                None,
3232                Some("glad"),
3233                Some("lang string longer than 12 bytes"),
3234                Some("-ad"),
3235            ],
3236            Some(SortOptions {
3237                descending: false,
3238                nulls_first: true,
3239            }),
3240            None,
3241            vec![
3242                None,
3243                None,
3244                Some("-ad"),
3245                Some("bad"),
3246                Some("glad"),
3247                Some("lang string longer than 12 bytes"),
3248                Some("long string longer than 12 bytes"),
3249                Some("sad"),
3250            ],
3251        );
3252
3253        test_sort_string_arrays(
3254            vec![
3255                None,
3256                Some("bad"),
3257                Some("long string longer than 12 bytes"),
3258                Some("sad"),
3259                None,
3260                Some("glad"),
3261                Some("lang string longer than 12 bytes"),
3262                Some("-ad"),
3263            ],
3264            Some(SortOptions {
3265                descending: true,
3266                nulls_first: true,
3267            }),
3268            None,
3269            vec![
3270                None,
3271                None,
3272                Some("sad"),
3273                Some("long string longer than 12 bytes"),
3274                Some("lang string longer than 12 bytes"),
3275                Some("glad"),
3276                Some("bad"),
3277                Some("-ad"),
3278            ],
3279        );
3280
3281        test_sort_string_arrays(
3282            vec![
3283                None,
3284                Some("bad"),
3285                Some("long string longer than 12 bytes"),
3286                Some("sad"),
3287                None,
3288                Some("glad"),
3289                Some("lang string longer than 12 bytes"),
3290                Some("-ad"),
3291            ],
3292            Some(SortOptions {
3293                descending: true,
3294                nulls_first: true,
3295            }),
3296            Some(3),
3297            vec![None, None, Some("sad")],
3298        );
3299
3300        // valid values less than limit with extra nulls
3301        test_sort_string_arrays(
3302            vec![
3303                Some("def long string longer than 12"),
3304                None,
3305                None,
3306                Some("abc"),
3307            ],
3308            Some(SortOptions {
3309                descending: false,
3310                nulls_first: false,
3311            }),
3312            Some(3),
3313            vec![Some("abc"), Some("def long string longer than 12"), None],
3314        );
3315
3316        test_sort_string_arrays(
3317            vec![
3318                Some("def long string longer than 12"),
3319                None,
3320                None,
3321                Some("abc"),
3322            ],
3323            Some(SortOptions {
3324                descending: false,
3325                nulls_first: true,
3326            }),
3327            Some(3),
3328            vec![None, None, Some("abc")],
3329        );
3330
3331        // more nulls than limit
3332        test_sort_string_arrays(
3333            vec![Some("def long string longer than 12"), None, None, None],
3334            Some(SortOptions {
3335                descending: false,
3336                nulls_first: true,
3337            }),
3338            Some(2),
3339            vec![None, None],
3340        );
3341
3342        test_sort_string_arrays(
3343            vec![Some("def long string longer than 12"), None, None, None],
3344            Some(SortOptions {
3345                descending: false,
3346                nulls_first: false,
3347            }),
3348            Some(2),
3349            vec![Some("def long string longer than 12"), None],
3350        );
3351    }
3352
3353    #[test]
3354    fn test_sort_run_to_run() {
3355        test_sort_run_inner(|array, sort_options, limit| sort_run(array, sort_options, limit));
3356    }
3357
3358    #[test]
3359    fn test_sort_run_to_indices() {
3360        test_sort_run_inner(|array, sort_options, limit| {
3361            let indices = sort_to_indices(array, sort_options, limit).unwrap();
3362            take(array, &indices, None)
3363        });
3364    }
3365
3366    fn test_sort_run_inner<F>(sort_fn: F)
3367    where
3368        F: Fn(&dyn Array, Option<SortOptions>, Option<usize>) -> Result<ArrayRef, ArrowError>,
3369    {
3370        // Create an input array for testing
3371        let total_len = 80;
3372        let vals: Vec<Option<i32>> = vec![Some(1), None, Some(2), Some(3), Some(4), None, Some(5)];
3373        let repeats: Vec<usize> = vec![1, 3, 2, 4];
3374        let mut input_array: Vec<Option<i32>> = Vec::with_capacity(total_len);
3375        for ix in 0_usize..32 {
3376            let repeat: usize = repeats[ix % repeats.len()];
3377            let val: Option<i32> = vals[ix % vals.len()];
3378            input_array.resize(input_array.len() + repeat, val);
3379        }
3380
3381        // create run array using input_array
3382        // Encode the input_array to run array
3383        let mut builder =
3384            PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
3385        builder.extend(input_array.iter().copied());
3386        let run_array = builder.finish();
3387
3388        // slice lengths that are tested
3389        let slice_lens = [
3390            1, 2, 3, 4, 5, 6, 7, 37, 38, 39, 40, 41, 42, 43, 74, 75, 76, 77, 78, 79, 80,
3391        ];
3392        for slice_len in slice_lens {
3393            test_sort_run_inner2(
3394                input_array.as_slice(),
3395                &run_array,
3396                0,
3397                slice_len,
3398                None,
3399                &sort_fn,
3400            );
3401            test_sort_run_inner2(
3402                input_array.as_slice(),
3403                &run_array,
3404                total_len - slice_len,
3405                slice_len,
3406                None,
3407                &sort_fn,
3408            );
3409            // Test with non zero limit
3410            if slice_len > 1 {
3411                test_sort_run_inner2(
3412                    input_array.as_slice(),
3413                    &run_array,
3414                    0,
3415                    slice_len,
3416                    Some(slice_len / 2),
3417                    &sort_fn,
3418                );
3419                test_sort_run_inner2(
3420                    input_array.as_slice(),
3421                    &run_array,
3422                    total_len - slice_len,
3423                    slice_len,
3424                    Some(slice_len / 2),
3425                    &sort_fn,
3426                );
3427            }
3428        }
3429    }
3430
3431    fn test_sort_run_inner2<F>(
3432        input_array: &[Option<i32>],
3433        run_array: &RunArray<Int16Type>,
3434        offset: usize,
3435        length: usize,
3436        limit: Option<usize>,
3437        sort_fn: &F,
3438    ) where
3439        F: Fn(&dyn Array, Option<SortOptions>, Option<usize>) -> Result<ArrayRef, ArrowError>,
3440    {
3441        // Run the sort and build actual result
3442        let sliced_array = run_array.slice(offset, length);
3443        let sorted_sliced_array = sort_fn(&sliced_array, None, limit).unwrap();
3444        let sorted_run_array = sorted_sliced_array
3445            .as_any()
3446            .downcast_ref::<RunArray<Int16Type>>()
3447            .unwrap();
3448        let typed_run_array = sorted_run_array
3449            .downcast::<PrimitiveArray<Int32Type>>()
3450            .unwrap();
3451        let actual: Vec<Option<i32>> = typed_run_array.into_iter().collect();
3452
3453        // build expected result.
3454        let mut sliced_input = input_array[offset..(offset + length)].to_owned();
3455        sliced_input.sort();
3456        let expected = if let Some(limit) = limit {
3457            sliced_input.iter().take(limit).copied().collect()
3458        } else {
3459            sliced_input
3460        };
3461
3462        assert_eq!(expected, actual)
3463    }
3464
3465    #[test]
3466    fn test_sort_string_dicts() {
3467        test_sort_string_dict_arrays::<Int8Type>(
3468            vec![
3469                None,
3470                Some("bad"),
3471                Some("sad"),
3472                None,
3473                Some("glad"),
3474                Some("-ad"),
3475            ],
3476            None,
3477            None,
3478            vec![
3479                None,
3480                None,
3481                Some("-ad"),
3482                Some("bad"),
3483                Some("glad"),
3484                Some("sad"),
3485            ],
3486        );
3487
3488        test_sort_string_dict_arrays::<Int16Type>(
3489            vec![
3490                None,
3491                Some("bad"),
3492                Some("sad"),
3493                None,
3494                Some("glad"),
3495                Some("-ad"),
3496            ],
3497            Some(SortOptions {
3498                descending: true,
3499                nulls_first: false,
3500            }),
3501            None,
3502            vec![
3503                Some("sad"),
3504                Some("glad"),
3505                Some("bad"),
3506                Some("-ad"),
3507                None,
3508                None,
3509            ],
3510        );
3511
3512        test_sort_string_dict_arrays::<Int32Type>(
3513            vec![
3514                None,
3515                Some("bad"),
3516                Some("sad"),
3517                None,
3518                Some("glad"),
3519                Some("-ad"),
3520            ],
3521            Some(SortOptions {
3522                descending: false,
3523                nulls_first: true,
3524            }),
3525            None,
3526            vec![
3527                None,
3528                None,
3529                Some("-ad"),
3530                Some("bad"),
3531                Some("glad"),
3532                Some("sad"),
3533            ],
3534        );
3535
3536        test_sort_string_dict_arrays::<Int16Type>(
3537            vec![
3538                None,
3539                Some("bad"),
3540                Some("sad"),
3541                None,
3542                Some("glad"),
3543                Some("-ad"),
3544            ],
3545            Some(SortOptions {
3546                descending: true,
3547                nulls_first: true,
3548            }),
3549            None,
3550            vec![
3551                None,
3552                None,
3553                Some("sad"),
3554                Some("glad"),
3555                Some("bad"),
3556                Some("-ad"),
3557            ],
3558        );
3559
3560        test_sort_string_dict_arrays::<Int16Type>(
3561            vec![
3562                None,
3563                Some("bad"),
3564                Some("sad"),
3565                None,
3566                Some("glad"),
3567                Some("-ad"),
3568            ],
3569            Some(SortOptions {
3570                descending: true,
3571                nulls_first: true,
3572            }),
3573            Some(3),
3574            vec![None, None, Some("sad")],
3575        );
3576
3577        // valid values less than limit with extra nulls
3578        test_sort_string_dict_arrays::<Int16Type>(
3579            vec![Some("def"), None, None, Some("abc")],
3580            Some(SortOptions {
3581                descending: false,
3582                nulls_first: false,
3583            }),
3584            Some(3),
3585            vec![Some("abc"), Some("def"), None],
3586        );
3587
3588        test_sort_string_dict_arrays::<Int16Type>(
3589            vec![Some("def"), None, None, Some("abc")],
3590            Some(SortOptions {
3591                descending: false,
3592                nulls_first: true,
3593            }),
3594            Some(3),
3595            vec![None, None, Some("abc")],
3596        );
3597
3598        // more nulls than limit
3599        test_sort_string_dict_arrays::<Int16Type>(
3600            vec![Some("def"), None, None, None],
3601            Some(SortOptions {
3602                descending: false,
3603                nulls_first: true,
3604            }),
3605            Some(2),
3606            vec![None, None],
3607        );
3608
3609        test_sort_string_dict_arrays::<Int16Type>(
3610            vec![Some("def"), None, None, None],
3611            Some(SortOptions {
3612                descending: false,
3613                nulls_first: false,
3614            }),
3615            Some(2),
3616            vec![Some("def"), None],
3617        );
3618    }
3619
3620    #[test]
3621    fn test_sort_list() {
3622        test_sort_list_arrays::<Int8Type>(
3623            vec![
3624                Some(vec![Some(1)]),
3625                Some(vec![Some(4)]),
3626                Some(vec![Some(2)]),
3627                Some(vec![Some(3)]),
3628            ],
3629            Some(SortOptions {
3630                descending: false,
3631                nulls_first: false,
3632            }),
3633            None,
3634            vec![
3635                Some(vec![Some(1)]),
3636                Some(vec![Some(2)]),
3637                Some(vec![Some(3)]),
3638                Some(vec![Some(4)]),
3639            ],
3640            Some(1),
3641        );
3642
3643        test_sort_list_arrays::<Float16Type>(
3644            vec![
3645                Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(0.0))]),
3646                Some(vec![
3647                    Some(f16::from_f32(4.0)),
3648                    Some(f16::from_f32(3.0)),
3649                    Some(f16::from_f32(2.0)),
3650                    Some(f16::from_f32(1.0)),
3651                ]),
3652                Some(vec![
3653                    Some(f16::from_f32(2.0)),
3654                    Some(f16::from_f32(3.0)),
3655                    Some(f16::from_f32(4.0)),
3656                ]),
3657                Some(vec![
3658                    Some(f16::from_f32(3.0)),
3659                    Some(f16::from_f32(3.0)),
3660                    Some(f16::from_f32(3.0)),
3661                    Some(f16::from_f32(3.0)),
3662                ]),
3663                Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(1.0))]),
3664            ],
3665            Some(SortOptions {
3666                descending: false,
3667                nulls_first: false,
3668            }),
3669            None,
3670            vec![
3671                Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(0.0))]),
3672                Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(1.0))]),
3673                Some(vec![
3674                    Some(f16::from_f32(2.0)),
3675                    Some(f16::from_f32(3.0)),
3676                    Some(f16::from_f32(4.0)),
3677                ]),
3678                Some(vec![
3679                    Some(f16::from_f32(3.0)),
3680                    Some(f16::from_f32(3.0)),
3681                    Some(f16::from_f32(3.0)),
3682                    Some(f16::from_f32(3.0)),
3683                ]),
3684                Some(vec![
3685                    Some(f16::from_f32(4.0)),
3686                    Some(f16::from_f32(3.0)),
3687                    Some(f16::from_f32(2.0)),
3688                    Some(f16::from_f32(1.0)),
3689                ]),
3690            ],
3691            None,
3692        );
3693
3694        test_sort_list_arrays::<Float32Type>(
3695            vec![
3696                Some(vec![Some(1.0), Some(0.0)]),
3697                Some(vec![Some(4.0), Some(3.0), Some(2.0), Some(1.0)]),
3698                Some(vec![Some(2.0), Some(3.0), Some(4.0)]),
3699                Some(vec![Some(3.0), Some(3.0), Some(3.0), Some(3.0)]),
3700                Some(vec![Some(1.0), Some(1.0)]),
3701            ],
3702            Some(SortOptions {
3703                descending: false,
3704                nulls_first: false,
3705            }),
3706            None,
3707            vec![
3708                Some(vec![Some(1.0), Some(0.0)]),
3709                Some(vec![Some(1.0), Some(1.0)]),
3710                Some(vec![Some(2.0), Some(3.0), Some(4.0)]),
3711                Some(vec![Some(3.0), Some(3.0), Some(3.0), Some(3.0)]),
3712                Some(vec![Some(4.0), Some(3.0), Some(2.0), Some(1.0)]),
3713            ],
3714            None,
3715        );
3716
3717        test_sort_list_arrays::<Float64Type>(
3718            vec![
3719                Some(vec![Some(1.0), Some(0.0)]),
3720                Some(vec![Some(4.0), Some(3.0), Some(2.0), Some(1.0)]),
3721                Some(vec![Some(2.0), Some(3.0), Some(4.0)]),
3722                Some(vec![Some(3.0), Some(3.0), Some(3.0), Some(3.0)]),
3723                Some(vec![Some(1.0), Some(1.0)]),
3724            ],
3725            Some(SortOptions {
3726                descending: false,
3727                nulls_first: false,
3728            }),
3729            None,
3730            vec![
3731                Some(vec![Some(1.0), Some(0.0)]),
3732                Some(vec![Some(1.0), Some(1.0)]),
3733                Some(vec![Some(2.0), Some(3.0), Some(4.0)]),
3734                Some(vec![Some(3.0), Some(3.0), Some(3.0), Some(3.0)]),
3735                Some(vec![Some(4.0), Some(3.0), Some(2.0), Some(1.0)]),
3736            ],
3737            None,
3738        );
3739
3740        test_sort_list_arrays::<Int32Type>(
3741            vec![
3742                Some(vec![Some(1), Some(0)]),
3743                Some(vec![Some(4), Some(3), Some(2), Some(1)]),
3744                Some(vec![Some(2), Some(3), Some(4)]),
3745                Some(vec![Some(3), Some(3), Some(3), Some(3)]),
3746                Some(vec![Some(1), Some(1)]),
3747            ],
3748            Some(SortOptions {
3749                descending: false,
3750                nulls_first: false,
3751            }),
3752            None,
3753            vec![
3754                Some(vec![Some(1), Some(0)]),
3755                Some(vec![Some(1), Some(1)]),
3756                Some(vec![Some(2), Some(3), Some(4)]),
3757                Some(vec![Some(3), Some(3), Some(3), Some(3)]),
3758                Some(vec![Some(4), Some(3), Some(2), Some(1)]),
3759            ],
3760            None,
3761        );
3762
3763        test_sort_list_arrays::<Int32Type>(
3764            vec![
3765                None,
3766                Some(vec![Some(4), None, Some(2)]),
3767                Some(vec![Some(2), Some(3), Some(4)]),
3768                None,
3769                Some(vec![Some(3), Some(3), None]),
3770            ],
3771            Some(SortOptions {
3772                descending: false,
3773                nulls_first: false,
3774            }),
3775            None,
3776            vec![
3777                Some(vec![Some(2), Some(3), Some(4)]),
3778                Some(vec![Some(3), Some(3), None]),
3779                Some(vec![Some(4), None, Some(2)]),
3780                None,
3781                None,
3782            ],
3783            Some(3),
3784        );
3785
3786        test_sort_list_arrays::<Int32Type>(
3787            vec![
3788                Some(vec![Some(1), Some(0)]),
3789                Some(vec![Some(4), Some(3), Some(2), Some(1)]),
3790                Some(vec![Some(2), Some(3), Some(4)]),
3791                Some(vec![Some(3), Some(3), Some(3), Some(3)]),
3792                Some(vec![Some(1), Some(1)]),
3793            ],
3794            Some(SortOptions {
3795                descending: false,
3796                nulls_first: false,
3797            }),
3798            Some(2),
3799            vec![Some(vec![Some(1), Some(0)]), Some(vec![Some(1), Some(1)])],
3800            None,
3801        );
3802
3803        // valid values less than limit with extra nulls
3804        test_sort_list_arrays::<Int32Type>(
3805            vec![Some(vec![Some(1)]), None, None, Some(vec![Some(2)])],
3806            Some(SortOptions {
3807                descending: false,
3808                nulls_first: false,
3809            }),
3810            Some(3),
3811            vec![Some(vec![Some(1)]), Some(vec![Some(2)]), None],
3812            None,
3813        );
3814
3815        test_sort_list_arrays::<Int32Type>(
3816            vec![Some(vec![Some(1)]), None, None, Some(vec![Some(2)])],
3817            Some(SortOptions {
3818                descending: false,
3819                nulls_first: true,
3820            }),
3821            Some(3),
3822            vec![None, None, Some(vec![Some(1)])],
3823            None,
3824        );
3825
3826        // more nulls than limit
3827        test_sort_list_arrays::<Int32Type>(
3828            vec![Some(vec![Some(1)]), None, None, None],
3829            Some(SortOptions {
3830                descending: false,
3831                nulls_first: true,
3832            }),
3833            Some(2),
3834            vec![None, None],
3835            None,
3836        );
3837
3838        test_sort_list_arrays::<Int32Type>(
3839            vec![Some(vec![Some(1)]), None, None, None],
3840            Some(SortOptions {
3841                descending: false,
3842                nulls_first: false,
3843            }),
3844            Some(2),
3845            vec![Some(vec![Some(1)]), None],
3846            None,
3847        );
3848    }
3849
3850    #[test]
3851    fn test_sort_binary() {
3852        test_sort_binary_arrays(
3853            vec![
3854                Some(vec![0, 0, 0]),
3855                Some(vec![0, 0, 5]),
3856                Some(vec![0, 0, 3]),
3857                Some(vec![0, 0, 7]),
3858                Some(vec![0, 0, 1]),
3859            ],
3860            Some(SortOptions {
3861                descending: false,
3862                nulls_first: false,
3863            }),
3864            None,
3865            vec![
3866                Some(vec![0, 0, 0]),
3867                Some(vec![0, 0, 1]),
3868                Some(vec![0, 0, 3]),
3869                Some(vec![0, 0, 5]),
3870                Some(vec![0, 0, 7]),
3871            ],
3872            Some(3),
3873        );
3874
3875        // with nulls
3876        test_sort_binary_arrays(
3877            vec![
3878                Some(vec![0, 0, 0]),
3879                None,
3880                Some(vec![0, 0, 3]),
3881                Some(vec![0, 0, 7]),
3882                Some(vec![0, 0, 1]),
3883                None,
3884            ],
3885            Some(SortOptions {
3886                descending: false,
3887                nulls_first: false,
3888            }),
3889            None,
3890            vec![
3891                Some(vec![0, 0, 0]),
3892                Some(vec![0, 0, 1]),
3893                Some(vec![0, 0, 3]),
3894                Some(vec![0, 0, 7]),
3895                None,
3896                None,
3897            ],
3898            Some(3),
3899        );
3900
3901        test_sort_binary_arrays(
3902            vec![
3903                Some(vec![3, 5, 7]),
3904                None,
3905                Some(vec![1, 7, 1]),
3906                Some(vec![2, 7, 3]),
3907                None,
3908                Some(vec![1, 4, 3]),
3909            ],
3910            Some(SortOptions {
3911                descending: false,
3912                nulls_first: false,
3913            }),
3914            None,
3915            vec![
3916                Some(vec![1, 4, 3]),
3917                Some(vec![1, 7, 1]),
3918                Some(vec![2, 7, 3]),
3919                Some(vec![3, 5, 7]),
3920                None,
3921                None,
3922            ],
3923            Some(3),
3924        );
3925
3926        // descending
3927        test_sort_binary_arrays(
3928            vec![
3929                Some(vec![0, 0, 0]),
3930                None,
3931                Some(vec![0, 0, 3]),
3932                Some(vec![0, 0, 7]),
3933                Some(vec![0, 0, 1]),
3934                None,
3935            ],
3936            Some(SortOptions {
3937                descending: true,
3938                nulls_first: false,
3939            }),
3940            None,
3941            vec![
3942                Some(vec![0, 0, 7]),
3943                Some(vec![0, 0, 3]),
3944                Some(vec![0, 0, 1]),
3945                Some(vec![0, 0, 0]),
3946                None,
3947                None,
3948            ],
3949            Some(3),
3950        );
3951
3952        // nulls first
3953        test_sort_binary_arrays(
3954            vec![
3955                Some(vec![0, 0, 0]),
3956                None,
3957                Some(vec![0, 0, 3]),
3958                Some(vec![0, 0, 7]),
3959                Some(vec![0, 0, 1]),
3960                None,
3961            ],
3962            Some(SortOptions {
3963                descending: false,
3964                nulls_first: true,
3965            }),
3966            None,
3967            vec![
3968                None,
3969                None,
3970                Some(vec![0, 0, 0]),
3971                Some(vec![0, 0, 1]),
3972                Some(vec![0, 0, 3]),
3973                Some(vec![0, 0, 7]),
3974            ],
3975            Some(3),
3976        );
3977
3978        // limit
3979        test_sort_binary_arrays(
3980            vec![
3981                Some(vec![0, 0, 0]),
3982                None,
3983                Some(vec![0, 0, 3]),
3984                Some(vec![0, 0, 7]),
3985                Some(vec![0, 0, 1]),
3986                None,
3987            ],
3988            Some(SortOptions {
3989                descending: false,
3990                nulls_first: true,
3991            }),
3992            Some(4),
3993            vec![None, None, Some(vec![0, 0, 0]), Some(vec![0, 0, 1])],
3994            Some(3),
3995        );
3996
3997        // var length
3998        test_sort_binary_arrays(
3999            vec![
4000                Some(b"Hello".to_vec()),
4001                None,
4002                Some(b"from".to_vec()),
4003                Some(b"Apache".to_vec()),
4004                Some(b"Arrow-rs".to_vec()),
4005                None,
4006            ],
4007            Some(SortOptions {
4008                descending: false,
4009                nulls_first: false,
4010            }),
4011            None,
4012            vec![
4013                Some(b"Apache".to_vec()),
4014                Some(b"Arrow-rs".to_vec()),
4015                Some(b"Hello".to_vec()),
4016                Some(b"from".to_vec()),
4017                None,
4018                None,
4019            ],
4020            None,
4021        );
4022
4023        // limit
4024        test_sort_binary_arrays(
4025            vec![
4026                Some(b"Hello".to_vec()),
4027                None,
4028                Some(b"from".to_vec()),
4029                Some(b"Apache".to_vec()),
4030                Some(b"Arrow-rs".to_vec()),
4031                None,
4032            ],
4033            Some(SortOptions {
4034                descending: false,
4035                nulls_first: true,
4036            }),
4037            Some(4),
4038            vec![
4039                None,
4040                None,
4041                Some(b"Apache".to_vec()),
4042                Some(b"Arrow-rs".to_vec()),
4043            ],
4044            None,
4045        );
4046    }
4047
4048    #[test]
4049    fn test_lex_sort_single_column() {
4050        let input = vec![SortColumn {
4051            values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4052                Some(17),
4053                Some(2),
4054                Some(-1),
4055                Some(0),
4056            ])) as ArrayRef,
4057            options: None,
4058        }];
4059        let expected = vec![Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4060            Some(-1),
4061            Some(0),
4062            Some(2),
4063            Some(17),
4064        ])) as ArrayRef];
4065        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4066        test_lex_sort_arrays(input.clone(), slice_arrays(expected, 0, 2), Some(2));
4067
4068        // Explicitly test a limit on the sort as a demonstration
4069        let expected = vec![Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4070            Some(-1),
4071            Some(0),
4072            Some(2),
4073        ])) as ArrayRef];
4074        test_lex_sort_arrays(input, expected, Some(3));
4075    }
4076
4077    #[test]
4078    fn test_lex_sort_unaligned_rows() {
4079        let input = vec![
4080            SortColumn {
4081                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![None, Some(-1)]))
4082                    as ArrayRef,
4083                options: None,
4084            },
4085            SortColumn {
4086                values: Arc::new(StringArray::from(vec![Some("foo")])) as ArrayRef,
4087                options: None,
4088            },
4089        ];
4090        assert!(
4091            lexsort(&input, None).is_err(),
4092            "lexsort should reject columns with different row counts"
4093        );
4094    }
4095
4096    #[test]
4097    fn test_lex_sort_mixed_types() {
4098        let input = vec![
4099            SortColumn {
4100                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4101                    Some(0),
4102                    Some(2),
4103                    Some(-1),
4104                    Some(0),
4105                ])) as ArrayRef,
4106                options: None,
4107            },
4108            SortColumn {
4109                values: Arc::new(PrimitiveArray::<UInt32Type>::from(vec![
4110                    Some(101),
4111                    Some(8),
4112                    Some(7),
4113                    Some(102),
4114                ])) as ArrayRef,
4115                options: None,
4116            },
4117            SortColumn {
4118                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4119                    Some(-1),
4120                    Some(-2),
4121                    Some(-3),
4122                    Some(-4),
4123                ])) as ArrayRef,
4124                options: None,
4125            },
4126        ];
4127        let expected = vec![
4128            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4129                Some(-1),
4130                Some(0),
4131                Some(0),
4132                Some(2),
4133            ])) as ArrayRef,
4134            Arc::new(PrimitiveArray::<UInt32Type>::from(vec![
4135                Some(7),
4136                Some(101),
4137                Some(102),
4138                Some(8),
4139            ])) as ArrayRef,
4140            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4141                Some(-3),
4142                Some(-1),
4143                Some(-4),
4144                Some(-2),
4145            ])) as ArrayRef,
4146        ];
4147        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4148        test_lex_sort_arrays(input, slice_arrays(expected, 0, 2), Some(2));
4149
4150        // test mix of string and in64 with option
4151        let input = vec![
4152            SortColumn {
4153                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4154                    Some(0),
4155                    Some(2),
4156                    Some(-1),
4157                    Some(0),
4158                ])) as ArrayRef,
4159                options: Some(SortOptions {
4160                    descending: true,
4161                    nulls_first: true,
4162                }),
4163            },
4164            SortColumn {
4165                values: Arc::new(StringArray::from(vec![
4166                    Some("foo"),
4167                    Some("9"),
4168                    Some("7"),
4169                    Some("bar"),
4170                ])) as ArrayRef,
4171                options: Some(SortOptions {
4172                    descending: true,
4173                    nulls_first: true,
4174                }),
4175            },
4176        ];
4177        let expected = vec![
4178            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4179                Some(2),
4180                Some(0),
4181                Some(0),
4182                Some(-1),
4183            ])) as ArrayRef,
4184            Arc::new(StringArray::from(vec![
4185                Some("9"),
4186                Some("foo"),
4187                Some("bar"),
4188                Some("7"),
4189            ])) as ArrayRef,
4190        ];
4191        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4192        test_lex_sort_arrays(input, slice_arrays(expected, 0, 3), Some(3));
4193
4194        // test sort with nulls first
4195        let input = vec![
4196            SortColumn {
4197                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4198                    None,
4199                    Some(-1),
4200                    Some(2),
4201                    None,
4202                ])) as ArrayRef,
4203                options: Some(SortOptions {
4204                    descending: true,
4205                    nulls_first: true,
4206                }),
4207            },
4208            SortColumn {
4209                values: Arc::new(StringArray::from(vec![
4210                    Some("foo"),
4211                    Some("world"),
4212                    Some("hello"),
4213                    None,
4214                ])) as ArrayRef,
4215                options: Some(SortOptions {
4216                    descending: true,
4217                    nulls_first: true,
4218                }),
4219            },
4220        ];
4221        let expected = vec![
4222            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4223                None,
4224                None,
4225                Some(2),
4226                Some(-1),
4227            ])) as ArrayRef,
4228            Arc::new(StringArray::from(vec![
4229                None,
4230                Some("foo"),
4231                Some("hello"),
4232                Some("world"),
4233            ])) as ArrayRef,
4234        ];
4235        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4236        test_lex_sort_arrays(input, slice_arrays(expected, 0, 1), Some(1));
4237
4238        // test sort with nulls last
4239        let input = vec![
4240            SortColumn {
4241                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4242                    None,
4243                    Some(-1),
4244                    Some(2),
4245                    None,
4246                ])) as ArrayRef,
4247                options: Some(SortOptions {
4248                    descending: true,
4249                    nulls_first: false,
4250                }),
4251            },
4252            SortColumn {
4253                values: Arc::new(StringArray::from(vec![
4254                    Some("foo"),
4255                    Some("world"),
4256                    Some("hello"),
4257                    None,
4258                ])) as ArrayRef,
4259                options: Some(SortOptions {
4260                    descending: true,
4261                    nulls_first: false,
4262                }),
4263            },
4264        ];
4265        let expected = vec![
4266            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4267                Some(2),
4268                Some(-1),
4269                None,
4270                None,
4271            ])) as ArrayRef,
4272            Arc::new(StringArray::from(vec![
4273                Some("hello"),
4274                Some("world"),
4275                Some("foo"),
4276                None,
4277            ])) as ArrayRef,
4278        ];
4279        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4280        test_lex_sort_arrays(input, slice_arrays(expected, 0, 2), Some(2));
4281
4282        // test sort with opposite options
4283        let input = vec![
4284            SortColumn {
4285                values: Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4286                    None,
4287                    Some(-1),
4288                    Some(2),
4289                    Some(-1),
4290                    None,
4291                ])) as ArrayRef,
4292                options: Some(SortOptions {
4293                    descending: false,
4294                    nulls_first: false,
4295                }),
4296            },
4297            SortColumn {
4298                values: Arc::new(StringArray::from(vec![
4299                    Some("foo"),
4300                    Some("bar"),
4301                    Some("world"),
4302                    Some("hello"),
4303                    None,
4304                ])) as ArrayRef,
4305                options: Some(SortOptions {
4306                    descending: true,
4307                    nulls_first: true,
4308                }),
4309            },
4310        ];
4311        let expected = vec![
4312            Arc::new(PrimitiveArray::<Int64Type>::from(vec![
4313                Some(-1),
4314                Some(-1),
4315                Some(2),
4316                None,
4317                None,
4318            ])) as ArrayRef,
4319            Arc::new(StringArray::from(vec![
4320                Some("hello"),
4321                Some("bar"),
4322                Some("world"),
4323                None,
4324                Some("foo"),
4325            ])) as ArrayRef,
4326        ];
4327        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4328        test_lex_sort_arrays(input.clone(), slice_arrays(expected.clone(), 0, 5), Some(5));
4329
4330        // Limiting by more rows than present is ok
4331        test_lex_sort_arrays(input, slice_arrays(expected, 0, 5), Some(10));
4332
4333        // test with FixedSizeListArray, arrays order: [UInt32, FixedSizeList(UInt32, 1)]
4334
4335        // case1
4336        let primitive_array_data = vec![
4337            Some(2),
4338            Some(3),
4339            Some(2),
4340            Some(0),
4341            None,
4342            Some(2),
4343            Some(1),
4344            Some(2),
4345        ];
4346        let list_array_data = vec![
4347            None,
4348            Some(vec![Some(4)]),
4349            Some(vec![Some(3)]),
4350            Some(vec![Some(1)]),
4351            Some(vec![Some(5)]),
4352            Some(vec![Some(0)]),
4353            Some(vec![Some(2)]),
4354            Some(vec![None]),
4355        ];
4356
4357        let expected_primitive_array_data = vec![
4358            None,
4359            Some(0),
4360            Some(1),
4361            Some(2),
4362            Some(2),
4363            Some(2),
4364            Some(2),
4365            Some(3),
4366        ];
4367        let expected_list_array_data = vec![
4368            Some(vec![Some(5)]),
4369            Some(vec![Some(1)]),
4370            Some(vec![Some(2)]),
4371            None, // <-
4372            Some(vec![None]),
4373            Some(vec![Some(0)]),
4374            Some(vec![Some(3)]), // <-
4375            Some(vec![Some(4)]),
4376        ];
4377        test_lex_sort_mixed_types_with_fixed_size_list::<Int32Type>(
4378            primitive_array_data.clone(),
4379            list_array_data.clone(),
4380            expected_primitive_array_data.clone(),
4381            expected_list_array_data,
4382            None,
4383            None,
4384        );
4385
4386        // case2
4387        let primitive_array_options = SortOptions {
4388            descending: false,
4389            nulls_first: true,
4390        };
4391        let list_array_options = SortOptions {
4392            descending: false,
4393            nulls_first: false, // has been modified
4394        };
4395        let expected_list_array_data = vec![
4396            Some(vec![Some(5)]),
4397            Some(vec![Some(1)]),
4398            Some(vec![Some(2)]),
4399            Some(vec![Some(0)]), // <-
4400            Some(vec![Some(3)]),
4401            Some(vec![None]),
4402            None, // <-
4403            Some(vec![Some(4)]),
4404        ];
4405        test_lex_sort_mixed_types_with_fixed_size_list::<Int32Type>(
4406            primitive_array_data.clone(),
4407            list_array_data.clone(),
4408            expected_primitive_array_data.clone(),
4409            expected_list_array_data,
4410            Some(primitive_array_options),
4411            Some(list_array_options),
4412        );
4413
4414        // case3
4415        let primitive_array_options = SortOptions {
4416            descending: false,
4417            nulls_first: true,
4418        };
4419        let list_array_options = SortOptions {
4420            descending: true, // has been modified
4421            nulls_first: true,
4422        };
4423        let expected_list_array_data = vec![
4424            Some(vec![Some(5)]),
4425            Some(vec![Some(1)]),
4426            Some(vec![Some(2)]),
4427            None, // <-
4428            Some(vec![None]),
4429            Some(vec![Some(3)]),
4430            Some(vec![Some(0)]), // <-
4431            Some(vec![Some(4)]),
4432        ];
4433        test_lex_sort_mixed_types_with_fixed_size_list::<Int32Type>(
4434            primitive_array_data.clone(),
4435            list_array_data.clone(),
4436            expected_primitive_array_data,
4437            expected_list_array_data,
4438            Some(primitive_array_options),
4439            Some(list_array_options),
4440        );
4441
4442        // test with ListArray/LargeListArray, arrays order: [List<UInt32>/LargeList<UInt32>, UInt32]
4443
4444        let list_array_data = vec![
4445            Some(vec![Some(2), Some(1)]), // 0
4446            None,                         // 10
4447            Some(vec![Some(3)]),          // 1
4448            Some(vec![Some(2), Some(0)]), // 2
4449            Some(vec![None, Some(2)]),    // 3
4450            Some(vec![Some(0)]),          // none
4451            None,                         // 11
4452            Some(vec![Some(2), None]),    // 4
4453            Some(vec![None]),             // 5
4454            Some(vec![Some(2), Some(1)]), // 6
4455        ];
4456        let primitive_array_data = vec![
4457            Some(0),
4458            Some(10),
4459            Some(1),
4460            Some(2),
4461            Some(3),
4462            None,
4463            Some(11),
4464            Some(4),
4465            Some(5),
4466            Some(6),
4467        ];
4468        let expected_list_array_data = vec![
4469            None,
4470            None,
4471            Some(vec![None]),
4472            Some(vec![None, Some(2)]),
4473            Some(vec![Some(0)]),
4474            Some(vec![Some(2), None]),
4475            Some(vec![Some(2), Some(0)]),
4476            Some(vec![Some(2), Some(1)]),
4477            Some(vec![Some(2), Some(1)]),
4478            Some(vec![Some(3)]),
4479        ];
4480        let expected_primitive_array_data = vec![
4481            Some(10),
4482            Some(11),
4483            Some(5),
4484            Some(3),
4485            None,
4486            Some(4),
4487            Some(2),
4488            Some(0),
4489            Some(6),
4490            Some(1),
4491        ];
4492        test_lex_sort_mixed_types_with_list::<Int32Type>(
4493            list_array_data.clone(),
4494            primitive_array_data.clone(),
4495            expected_list_array_data,
4496            expected_primitive_array_data,
4497            None,
4498            None,
4499        );
4500    }
4501
4502    fn test_lex_sort_mixed_types_with_fixed_size_list<T>(
4503        primitive_array_data: Vec<Option<T::Native>>,
4504        list_array_data: Vec<Option<Vec<Option<T::Native>>>>,
4505        expected_primitive_array_data: Vec<Option<T::Native>>,
4506        expected_list_array_data: Vec<Option<Vec<Option<T::Native>>>>,
4507        primitive_array_options: Option<SortOptions>,
4508        list_array_options: Option<SortOptions>,
4509    ) where
4510        T: ArrowPrimitiveType,
4511        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
4512    {
4513        let input = vec![
4514            SortColumn {
4515                values: Arc::new(PrimitiveArray::<T>::from(primitive_array_data.clone()))
4516                    as ArrayRef,
4517                options: primitive_array_options,
4518            },
4519            SortColumn {
4520                values: Arc::new(FixedSizeListArray::from_iter_primitive::<T, _, _>(
4521                    list_array_data.clone(),
4522                    1,
4523                )) as ArrayRef,
4524                options: list_array_options,
4525            },
4526        ];
4527
4528        let expected = vec![
4529            Arc::new(PrimitiveArray::<T>::from(
4530                expected_primitive_array_data.clone(),
4531            )) as ArrayRef,
4532            Arc::new(FixedSizeListArray::from_iter_primitive::<T, _, _>(
4533                expected_list_array_data.clone(),
4534                1,
4535            )) as ArrayRef,
4536        ];
4537
4538        test_lex_sort_arrays(input.clone(), expected.clone(), None);
4539        test_lex_sort_arrays(input.clone(), slice_arrays(expected.clone(), 0, 5), Some(5));
4540    }
4541
4542    fn test_lex_sort_mixed_types_with_list<T>(
4543        list_array_data: Vec<Option<Vec<Option<T::Native>>>>,
4544        primitive_array_data: Vec<Option<T::Native>>,
4545        expected_list_array_data: Vec<Option<Vec<Option<T::Native>>>>,
4546        expected_primitive_array_data: Vec<Option<T::Native>>,
4547        list_array_options: Option<SortOptions>,
4548        primitive_array_options: Option<SortOptions>,
4549    ) where
4550        T: ArrowPrimitiveType,
4551        PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
4552    {
4553        macro_rules! run_test {
4554            ($ARRAY_TYPE:ident) => {
4555                let input = vec![
4556                    SortColumn {
4557                        values: Arc::new(<$ARRAY_TYPE>::from_iter_primitive::<T, _, _>(
4558                            list_array_data.clone(),
4559                        )) as ArrayRef,
4560                        options: list_array_options.clone(),
4561                    },
4562                    SortColumn {
4563                        values: Arc::new(PrimitiveArray::<T>::from(primitive_array_data.clone()))
4564                            as ArrayRef,
4565                        options: primitive_array_options.clone(),
4566                    },
4567                ];
4568
4569                let expected = vec![
4570                    Arc::new(<$ARRAY_TYPE>::from_iter_primitive::<T, _, _>(
4571                        expected_list_array_data.clone(),
4572                    )) as ArrayRef,
4573                    Arc::new(PrimitiveArray::<T>::from(
4574                        expected_primitive_array_data.clone(),
4575                    )) as ArrayRef,
4576                ];
4577
4578                test_lex_sort_arrays(input.clone(), expected.clone(), None);
4579                test_lex_sort_arrays(input.clone(), slice_arrays(expected.clone(), 0, 5), Some(5));
4580            };
4581        }
4582        run_test!(ListArray);
4583        run_test!(LargeListArray);
4584    }
4585
4586    #[test]
4587    fn test_lex_sort_limit_paths() {
4588        let input = vec![
4589            SortColumn {
4590                values: Arc::new(Int32Array::from_iter_values((0..100).rev())) as ArrayRef,
4591                options: None,
4592            },
4593            SortColumn {
4594                values: Arc::new(Int32Array::from_iter_values(0..100)) as ArrayRef,
4595                options: None,
4596            },
4597        ];
4598
4599        // Exercise the bounded heap path.
4600        let indices = lexsort_to_indices(&input, Some(10)).unwrap();
4601        let expected = UInt32Array::from_iter_values((90..100).rev());
4602        assert_eq!(indices, expected);
4603
4604        // Exercise the existing partial-sort path.
4605        let indices = lexsort_to_indices(&input, Some(11)).unwrap();
4606        let expected = UInt32Array::from_iter_values((89..100).rev());
4607        assert_eq!(indices, expected);
4608    }
4609
4610    #[test]
4611    fn test_partial_sort() {
4612        let mut before: Vec<&str> = vec![
4613            "a", "cat", "mat", "on", "sat", "the", "xxx", "xxxx", "fdadfdsf",
4614        ];
4615        let mut d = before.clone();
4616        d.sort_unstable();
4617
4618        for last in 0..before.len() {
4619            partial_sort(&mut before, last, |a, b| a.cmp(b));
4620            assert_eq!(&d[0..last], &before.as_slice()[0..last]);
4621        }
4622    }
4623
4624    #[test]
4625    fn test_partial_rand_sort() {
4626        let size = 1000u32;
4627        let mut rng = StdRng::seed_from_u64(42);
4628        let mut before: Vec<u32> = (0..size).map(|_| rng.random::<u32>()).collect();
4629        let mut d = before.clone();
4630        let last = (rng.next_u32() % size) as usize;
4631        d.sort_unstable();
4632
4633        partial_sort(&mut before, last, |a, b| a.cmp(b));
4634        assert_eq!(&d[0..last], &before[0..last]);
4635    }
4636
4637    #[test]
4638    fn test_sort_int8_dicts() {
4639        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4640        let values = Int8Array::from(vec![1, 3, 5]);
4641        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4642            keys,
4643            values,
4644            None,
4645            None,
4646            vec![None, None, Some(1), Some(3), Some(5), Some(5)],
4647        );
4648
4649        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4650        let values = Int8Array::from(vec![1, 3, 5]);
4651        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4652            keys,
4653            values,
4654            Some(SortOptions {
4655                descending: true,
4656                nulls_first: false,
4657            }),
4658            None,
4659            vec![Some(5), Some(5), Some(3), Some(1), None, None],
4660        );
4661
4662        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4663        let values = Int8Array::from(vec![1, 3, 5]);
4664        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4665            keys,
4666            values,
4667            Some(SortOptions {
4668                descending: false,
4669                nulls_first: false,
4670            }),
4671            None,
4672            vec![Some(1), Some(3), Some(5), Some(5), None, None],
4673        );
4674
4675        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4676        let values = Int8Array::from(vec![1, 3, 5]);
4677        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4678            keys,
4679            values,
4680            Some(SortOptions {
4681                descending: true,
4682                nulls_first: true,
4683            }),
4684            Some(3),
4685            vec![None, None, Some(5)],
4686        );
4687
4688        // Values have `None`.
4689        let keys = Int8Array::from(vec![
4690            Some(1_i8),
4691            None,
4692            Some(3),
4693            None,
4694            Some(2),
4695            Some(3),
4696            Some(0),
4697        ]);
4698        let values = Int8Array::from(vec![Some(1), Some(3), None, Some(5)]);
4699        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4700            keys,
4701            values,
4702            None,
4703            None,
4704            vec![None, None, None, Some(1), Some(3), Some(5), Some(5)],
4705        );
4706
4707        let keys = Int8Array::from(vec![
4708            Some(1_i8),
4709            None,
4710            Some(3),
4711            None,
4712            Some(2),
4713            Some(3),
4714            Some(0),
4715        ]);
4716        let values = Int8Array::from(vec![Some(1), Some(3), None, Some(5)]);
4717        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4718            keys,
4719            values,
4720            Some(SortOptions {
4721                descending: false,
4722                nulls_first: false,
4723            }),
4724            None,
4725            vec![Some(1), Some(3), Some(5), Some(5), None, None, None],
4726        );
4727
4728        let keys = Int8Array::from(vec![
4729            Some(1_i8),
4730            None,
4731            Some(3),
4732            None,
4733            Some(2),
4734            Some(3),
4735            Some(0),
4736        ]);
4737        let values = Int8Array::from(vec![Some(1), Some(3), None, Some(5)]);
4738        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4739            keys,
4740            values,
4741            Some(SortOptions {
4742                descending: true,
4743                nulls_first: false,
4744            }),
4745            None,
4746            vec![Some(5), Some(5), Some(3), Some(1), None, None, None],
4747        );
4748
4749        let keys = Int8Array::from(vec![
4750            Some(1_i8),
4751            None,
4752            Some(3),
4753            None,
4754            Some(2),
4755            Some(3),
4756            Some(0),
4757        ]);
4758        let values = Int8Array::from(vec![Some(1), Some(3), None, Some(5)]);
4759        test_sort_primitive_dict_arrays::<Int8Type, Int8Type>(
4760            keys,
4761            values,
4762            Some(SortOptions {
4763                descending: true,
4764                nulls_first: true,
4765            }),
4766            None,
4767            vec![None, None, None, Some(5), Some(5), Some(3), Some(1)],
4768        );
4769    }
4770
4771    #[test]
4772    fn test_sort_f32_dicts() {
4773        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4774        let values = Float32Array::from(vec![1.2, 3.0, 5.1]);
4775        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4776            keys,
4777            values,
4778            None,
4779            None,
4780            vec![None, None, Some(1.2), Some(3.0), Some(5.1), Some(5.1)],
4781        );
4782
4783        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4784        let values = Float32Array::from(vec![1.2, 3.0, 5.1]);
4785        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4786            keys,
4787            values,
4788            Some(SortOptions {
4789                descending: true,
4790                nulls_first: false,
4791            }),
4792            None,
4793            vec![Some(5.1), Some(5.1), Some(3.0), Some(1.2), None, None],
4794        );
4795
4796        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4797        let values = Float32Array::from(vec![1.2, 3.0, 5.1]);
4798        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4799            keys,
4800            values,
4801            Some(SortOptions {
4802                descending: false,
4803                nulls_first: false,
4804            }),
4805            None,
4806            vec![Some(1.2), Some(3.0), Some(5.1), Some(5.1), None, None],
4807        );
4808
4809        let keys = Int8Array::from(vec![Some(1_i8), None, Some(2), None, Some(2), Some(0)]);
4810        let values = Float32Array::from(vec![1.2, 3.0, 5.1]);
4811        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4812            keys,
4813            values,
4814            Some(SortOptions {
4815                descending: true,
4816                nulls_first: true,
4817            }),
4818            Some(3),
4819            vec![None, None, Some(5.1)],
4820        );
4821
4822        // Values have `None`.
4823        let keys = Int8Array::from(vec![
4824            Some(1_i8),
4825            None,
4826            Some(3),
4827            None,
4828            Some(2),
4829            Some(3),
4830            Some(0),
4831        ]);
4832        let values = Float32Array::from(vec![Some(1.2), Some(3.0), None, Some(5.1)]);
4833        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4834            keys,
4835            values,
4836            None,
4837            None,
4838            vec![None, None, None, Some(1.2), Some(3.0), Some(5.1), Some(5.1)],
4839        );
4840
4841        let keys = Int8Array::from(vec![
4842            Some(1_i8),
4843            None,
4844            Some(3),
4845            None,
4846            Some(2),
4847            Some(3),
4848            Some(0),
4849        ]);
4850        let values = Float32Array::from(vec![Some(1.2), Some(3.0), None, Some(5.1)]);
4851        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4852            keys,
4853            values,
4854            Some(SortOptions {
4855                descending: false,
4856                nulls_first: false,
4857            }),
4858            None,
4859            vec![Some(1.2), Some(3.0), Some(5.1), Some(5.1), None, None, None],
4860        );
4861
4862        let keys = Int8Array::from(vec![
4863            Some(1_i8),
4864            None,
4865            Some(3),
4866            None,
4867            Some(2),
4868            Some(3),
4869            Some(0),
4870        ]);
4871        let values = Float32Array::from(vec![Some(1.2), Some(3.0), None, Some(5.1)]);
4872        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4873            keys,
4874            values,
4875            Some(SortOptions {
4876                descending: true,
4877                nulls_first: false,
4878            }),
4879            None,
4880            vec![Some(5.1), Some(5.1), Some(3.0), Some(1.2), None, None, None],
4881        );
4882
4883        let keys = Int8Array::from(vec![
4884            Some(1_i8),
4885            None,
4886            Some(3),
4887            None,
4888            Some(2),
4889            Some(3),
4890            Some(0),
4891        ]);
4892        let values = Float32Array::from(vec![Some(1.2), Some(3.0), None, Some(5.1)]);
4893        test_sort_primitive_dict_arrays::<Int8Type, Float32Type>(
4894            keys,
4895            values,
4896            Some(SortOptions {
4897                descending: true,
4898                nulls_first: true,
4899            }),
4900            None,
4901            vec![None, None, None, Some(5.1), Some(5.1), Some(3.0), Some(1.2)],
4902        );
4903    }
4904
4905    #[test]
4906    fn test_lexicographic_comparator_null_dict_values() {
4907        let values = Int32Array::new(
4908            vec![1, 2, 3, 4].into(),
4909            Some(NullBuffer::from(vec![true, false, false, true])),
4910        );
4911        let keys = Int32Array::new(
4912            vec![0, 1, 53, 3].into(),
4913            Some(NullBuffer::from(vec![true, true, false, true])),
4914        );
4915        // [1, NULL, NULL, 4]
4916        let dict = DictionaryArray::new(keys, Arc::new(values));
4917
4918        let comparator = LexicographicalComparator::try_new(&[SortColumn {
4919            values: Arc::new(dict),
4920            options: None,
4921        }])
4922        .unwrap();
4923        // 1.cmp(NULL)
4924        assert_eq!(comparator.compare(0, 1), Ordering::Greater);
4925        // NULL.cmp(NULL)
4926        assert_eq!(comparator.compare(2, 1), Ordering::Equal);
4927        // NULL.cmp(4)
4928        assert_eq!(comparator.compare(2, 3), Ordering::Less);
4929    }
4930
4931    #[test]
4932    fn sort_list_equal() {
4933        let a = {
4934            let mut builder = FixedSizeListBuilder::new(Int64Builder::new(), 2);
4935            for value in [[1, 5], [0, 3], [1, 3]] {
4936                builder.values().append_slice(&value);
4937                builder.append(true);
4938            }
4939            builder.finish()
4940        };
4941
4942        let sort_indices = sort_to_indices(&a, None, None).unwrap();
4943        assert_eq!(sort_indices.values(), &[1, 2, 0]);
4944
4945        let a = {
4946            let mut builder = ListBuilder::new(Int64Builder::new());
4947            for value in [[1, 5], [0, 3], [1, 3]] {
4948                builder.values().append_slice(&value);
4949                builder.append(true);
4950            }
4951            builder.finish()
4952        };
4953
4954        let sort_indices = sort_to_indices(&a, None, None).unwrap();
4955        assert_eq!(sort_indices.values(), &[1, 2, 0]);
4956    }
4957
4958    #[test]
4959    fn sort_struct_fallback_to_lexsort() {
4960        let float = Arc::new(Float32Array::from(vec![1.0, -0.1, 3.5, 1.0]));
4961        let int = Arc::new(Int32Array::from(vec![42, 28, 19, 31]));
4962
4963        let struct_array = StructArray::from(vec![
4964            (
4965                Arc::new(Field::new("b", DataType::Float32, false)),
4966                float.clone() as ArrayRef,
4967            ),
4968            (
4969                Arc::new(Field::new("c", DataType::Int32, false)),
4970                int.clone() as ArrayRef,
4971            ),
4972        ]);
4973
4974        assert!(!can_sort_to_indices(struct_array.data_type()));
4975        assert!(
4976            sort_to_indices(&struct_array, None, None)
4977                .err()
4978                .unwrap()
4979                .to_string()
4980                .contains("Sort not supported for data type")
4981        );
4982
4983        let sort_columns = vec![SortColumn {
4984            values: Arc::new(struct_array.clone()) as ArrayRef,
4985            options: None,
4986        }];
4987        let sorted = lexsort(&sort_columns, None).unwrap();
4988
4989        let expected_struct_array = Arc::new(StructArray::from(vec![
4990            (
4991                Arc::new(Field::new("b", DataType::Float32, false)),
4992                Arc::new(Float32Array::from(vec![-0.1, 1.0, 1.0, 3.5])) as ArrayRef,
4993            ),
4994            (
4995                Arc::new(Field::new("c", DataType::Int32, false)),
4996                Arc::new(Int32Array::from(vec![28, 31, 42, 19])) as ArrayRef,
4997            ),
4998        ])) as ArrayRef;
4999
5000        assert_eq!(&sorted[0], &expected_struct_array);
5001    }
5002
5003    /// A simple, correct but slower reference implementation.
5004    fn naive_partition(array: &BooleanArray) -> (Vec<u32>, Vec<u32>) {
5005        let len = array.len();
5006        let mut valid = Vec::with_capacity(len);
5007        let mut nulls = Vec::with_capacity(len);
5008        for i in 0..len {
5009            if array.is_valid(i) {
5010                valid.push(i as u32);
5011            } else {
5012                nulls.push(i as u32);
5013            }
5014        }
5015        (valid, nulls)
5016    }
5017
5018    #[test]
5019    #[cfg_attr(miri, ignore)] // Takes too long
5020    fn fuzz_partition_validity() {
5021        let mut rng = StdRng::seed_from_u64(0xF00D_CAFE);
5022        for _ in 0..1_000 {
5023            // build a random BooleanArray with some nulls
5024            let len = rng.random_range(0..512);
5025            let mut builder = BooleanBuilder::new();
5026            for _ in 0..len {
5027                if rng.random_bool(0.2) {
5028                    builder.append_null();
5029                } else {
5030                    builder.append_value(rng.random_bool(0.5));
5031                }
5032            }
5033            let array = builder.finish();
5034
5035            // Test both implementations on the full array
5036            let (v1, n1) = partition_validity(&array);
5037            let (v2, n2) = naive_partition(&array);
5038            assert_eq!(v1, v2, "valid mismatch on full array");
5039            assert_eq!(n1, n2, "null  mismatch on full array");
5040
5041            if len >= 8 {
5042                // 1) Random slice within the array
5043                let max_offset = len - 4;
5044                let offset = rng.random_range(0..=max_offset);
5045                let max_slice_len = len - offset;
5046                let slice_len = rng.random_range(1..=max_slice_len);
5047
5048                // Bind the sliced ArrayRef to keep it alive
5049                let sliced = array.slice(offset, slice_len);
5050                let slice = sliced
5051                    .as_any()
5052                    .downcast_ref::<BooleanArray>()
5053                    .expect("slice should be a BooleanArray");
5054
5055                let (sv1, sn1) = partition_validity(slice);
5056                let (sv2, sn2) = naive_partition(slice);
5057                assert_eq!(
5058                    sv1, sv2,
5059                    "valid mismatch on random slice at offset {offset} length {slice_len}",
5060                );
5061                assert_eq!(
5062                    sn1, sn2,
5063                    "null mismatch on random slice at offset {offset} length {slice_len}",
5064                );
5065
5066                // 2) Ensure we test slices that start beyond one 64-bit chunk boundary
5067                if len > 68 {
5068                    let offset2 = rng.random_range(65..(len - 3));
5069                    let len2 = rng.random_range(1..=(len - offset2));
5070
5071                    let sliced2 = array.slice(offset2, len2);
5072                    let slice2 = sliced2
5073                        .as_any()
5074                        .downcast_ref::<BooleanArray>()
5075                        .expect("slice2 should be a BooleanArray");
5076
5077                    let (sv3, sn3) = partition_validity(slice2);
5078                    let (sv4, sn4) = naive_partition(slice2);
5079                    assert_eq!(
5080                        sv3, sv4,
5081                        "valid mismatch on chunk-crossing slice at offset {offset2} length {len2}",
5082                    );
5083                    assert_eq!(
5084                        sn3, sn4,
5085                        "null mismatch on chunk-crossing slice at offset {offset2} length {len2}",
5086                    );
5087                }
5088            }
5089        }
5090    }
5091
5092    // A few small deterministic checks
5093    #[test]
5094    fn test_partition_edge_cases() {
5095        // all valid
5096        let array = BooleanArray::from(vec![Some(true), Some(false), Some(true)]);
5097        let (valid, nulls) = partition_validity(&array);
5098        assert_eq!(valid, vec![0, 1, 2]);
5099        assert!(nulls.is_empty());
5100
5101        // all null
5102        let array = BooleanArray::from(vec![None, None, None]);
5103        let (valid, nulls) = partition_validity(&array);
5104        assert!(valid.is_empty());
5105        assert_eq!(nulls, vec![0, 1, 2]);
5106
5107        // alternating
5108        let array = BooleanArray::from(vec![Some(true), None, Some(true), None]);
5109        let (valid, nulls) = partition_validity(&array);
5110        assert_eq!(valid, vec![0, 2]);
5111        assert_eq!(nulls, vec![1, 3]);
5112    }
5113
5114    // Test specific edge case strings that exercise the 4-byte prefix logic
5115    #[test]
5116    fn test_specific_edge_cases() {
5117        let test_cases = vec![
5118            // Key test cases for lengths 1-4 that test prefix padding
5119            "a", "ab", "ba", "baa", "abba", "abbc", "abc", "cda",
5120            // Test cases where first 4 bytes are same but subsequent bytes differ
5121            "abcd", "abcde", "abcdf", "abcdaaa", "abcdbbb",
5122            // Test cases with length < 4 that require padding
5123            "z", "za", "zaa", "zaaa", "zaaab", // Empty string
5124            "",      // Test various length combinations with same prefix
5125            "test", "test1", "test12", "test123", "test1234",
5126        ];
5127
5128        // Use standard library sort as reference
5129        let mut expected = test_cases.clone();
5130        expected.sort();
5131
5132        // Use our sorting algorithm
5133        let string_array = StringArray::from(test_cases.clone());
5134        let indices: Vec<u32> = (0..test_cases.len() as u32).collect();
5135        let result = sort_bytes(
5136            &string_array,
5137            indices,
5138            vec![], // no nulls
5139            SortOptions::default(),
5140            None,
5141        );
5142
5143        // Verify results
5144        let sorted_strings: Vec<&str> = result
5145            .values()
5146            .iter()
5147            .map(|&idx| test_cases[idx as usize])
5148            .collect();
5149
5150        assert_eq!(sorted_strings, expected);
5151    }
5152
5153    // Test sorting correctness for different length combinations
5154    #[test]
5155    fn test_length_combinations() {
5156        let test_cases = vec![
5157            // Focus on testing strings of length 1-4, as these affect padding logic
5158            ("", 0),
5159            ("a", 1),
5160            ("ab", 2),
5161            ("abc", 3),
5162            ("abcd", 4),
5163            ("abcde", 5),
5164            ("b", 1),
5165            ("ba", 2),
5166            ("bab", 3),
5167            ("babc", 4),
5168            ("babcd", 5),
5169            // Test same prefix with different lengths
5170            ("test", 4),
5171            ("test1", 5),
5172            ("test12", 6),
5173            ("test123", 7),
5174        ];
5175
5176        let strings: Vec<&str> = test_cases.iter().map(|(s, _)| *s).collect();
5177        let mut expected = strings.clone();
5178        expected.sort();
5179
5180        let string_array = StringArray::from(strings.clone());
5181        let indices: Vec<u32> = (0..strings.len() as u32).collect();
5182        let result = sort_bytes(&string_array, indices, vec![], SortOptions::default(), None);
5183
5184        let sorted_strings: Vec<&str> = result
5185            .values()
5186            .iter()
5187            .map(|&idx| strings[idx as usize])
5188            .collect();
5189
5190        assert_eq!(sorted_strings, expected);
5191    }
5192
5193    // Test UTF-8 string handling
5194    #[test]
5195    fn test_utf8_strings() {
5196        let test_cases = vec![
5197            "a",
5198            "你",       // 3-byte UTF-8 character
5199            "你好",     // 6 bytes
5200            "你好世界", // 12 bytes
5201            "🎉",       // 4-byte emoji
5202            "🎉🎊",     // 8 bytes
5203            "café",     // Contains accent character
5204            "naïve",
5205            "Москва", // Cyrillic script
5206            "東京",   // Japanese kanji
5207            "한국",   // Korean
5208        ];
5209
5210        let mut expected = test_cases.clone();
5211        expected.sort();
5212
5213        let string_array = StringArray::from(test_cases.clone());
5214        let indices: Vec<u32> = (0..test_cases.len() as u32).collect();
5215        let result = sort_bytes(&string_array, indices, vec![], SortOptions::default(), None);
5216
5217        let sorted_strings: Vec<&str> = result
5218            .values()
5219            .iter()
5220            .map(|&idx| test_cases[idx as usize])
5221            .collect();
5222
5223        assert_eq!(sorted_strings, expected);
5224    }
5225
5226    // Fuzz testing: generate random UTF-8 strings and verify sort correctness
5227    #[test]
5228    #[cfg_attr(miri, ignore)] // Takes too long
5229    fn test_fuzz_random_strings() {
5230        let mut rng = StdRng::seed_from_u64(42); // Fixed seed for reproducibility
5231
5232        for _ in 0..100 {
5233            // Run 100 rounds of fuzz testing
5234            let mut test_strings = Vec::new();
5235
5236            // Generate 20-50 random strings
5237            let num_strings = rng.random_range(20..=50);
5238
5239            for _ in 0..num_strings {
5240                let string = generate_random_string(&mut rng);
5241                test_strings.push(string);
5242            }
5243
5244            // Use standard library sort as reference
5245            let mut expected = test_strings.clone();
5246            expected.sort();
5247
5248            // Use our sorting algorithm
5249            let string_array = StringArray::from(test_strings.clone());
5250            let indices: Vec<u32> = (0..test_strings.len() as u32).collect();
5251            let result = sort_bytes(&string_array, indices, vec![], SortOptions::default(), None);
5252
5253            let sorted_strings: Vec<String> = result
5254                .values()
5255                .iter()
5256                .map(|&idx| test_strings[idx as usize].clone())
5257                .collect();
5258
5259            assert_eq!(
5260                sorted_strings, expected,
5261                "Fuzz test failed with input: {test_strings:?}"
5262            );
5263        }
5264    }
5265
5266    // Helper function to generate random UTF-8 strings
5267    fn generate_random_string(rng: &mut StdRng) -> String {
5268        // Bias towards generating short strings, especially length 1-4
5269        let length = if rng.random_bool(0.6) {
5270            rng.random_range(0..=4) // 60% probability for 0-4 length strings
5271        } else {
5272            rng.random_range(5..=20) // 40% probability for longer strings
5273        };
5274
5275        if length == 0 {
5276            return String::new();
5277        }
5278
5279        let mut result = String::new();
5280        let mut current_len = 0;
5281
5282        while current_len < length {
5283            let c = generate_random_char(rng);
5284            let char_len = c.len_utf8();
5285
5286            // Ensure we don't exceed target length
5287            if current_len + char_len <= length {
5288                result.push(c);
5289                current_len += char_len;
5290            } else {
5291                // If adding this character would exceed length, fill with ASCII
5292                let remaining = length - current_len;
5293                for _ in 0..remaining {
5294                    result.push(rng.random_range('a'..='z'));
5295                }
5296                break;
5297            }
5298        }
5299
5300        result
5301    }
5302
5303    // Generate random characters (including various UTF-8 characters)
5304    fn generate_random_char(rng: &mut StdRng) -> char {
5305        match rng.random_range(0..10) {
5306            0..=5 => rng.random_range('a'..='z'), // 60% ASCII lowercase
5307            6 => rng.random_range('A'..='Z'),     // 10% ASCII uppercase
5308            7 => rng.random_range('0'..='9'),     // 10% digits
5309            8 => {
5310                // 10% Chinese characters
5311                let chinese_chars = ['你', '好', '世', '界', '测', '试', '中', '文'];
5312                chinese_chars[rng.random_range(0..chinese_chars.len())]
5313            }
5314            9 => {
5315                // 10% other Unicode characters (single `char`s)
5316                let special_chars = ['é', 'ï', '🎉', '🎊', 'α', 'β', 'γ'];
5317                special_chars[rng.random_range(0..special_chars.len())]
5318            }
5319            _ => unreachable!(),
5320        }
5321    }
5322
5323    // Test descending sort order
5324    #[test]
5325    fn test_descending_sort() {
5326        let test_cases = vec!["a", "ab", "ba", "baa", "abba", "abbc", "abc", "cda"];
5327
5328        let mut expected = test_cases.clone();
5329        expected.sort();
5330        expected.reverse(); // Descending order
5331
5332        let string_array = StringArray::from(test_cases.clone());
5333        let indices: Vec<u32> = (0..test_cases.len() as u32).collect();
5334        let result = sort_bytes(
5335            &string_array,
5336            indices,
5337            vec![],
5338            SortOptions {
5339                descending: true,
5340                nulls_first: false,
5341            },
5342            None,
5343        );
5344
5345        let sorted_strings: Vec<&str> = result
5346            .values()
5347            .iter()
5348            .map(|&idx| test_cases[idx as usize])
5349            .collect();
5350
5351        assert_eq!(sorted_strings, expected);
5352    }
5353
5354    // Stress test: large number of strings with same prefix
5355    #[test]
5356    fn test_same_prefix_stress() {
5357        let mut test_cases = Vec::new();
5358        let prefix = "same";
5359
5360        // Generate many strings with the same prefix
5361        for i in 0..1000 {
5362            test_cases.push(format!("{prefix}{i:04}"));
5363        }
5364
5365        let mut expected = test_cases.clone();
5366        expected.sort();
5367
5368        let string_array = StringArray::from(test_cases.clone());
5369        let indices: Vec<u32> = (0..test_cases.len() as u32).collect();
5370        let result = sort_bytes(&string_array, indices, vec![], SortOptions::default(), None);
5371
5372        let sorted_strings: Vec<String> = result
5373            .values()
5374            .iter()
5375            .map(|&idx| test_cases[idx as usize].clone())
5376            .collect();
5377
5378        assert_eq!(sorted_strings, expected);
5379    }
5380
5381    // Test limit parameter
5382    #[test]
5383    fn test_with_limit() {
5384        let test_cases = vec!["z", "y", "x", "w", "v", "u", "t", "s"];
5385        let limit = 3;
5386
5387        let mut expected = test_cases.clone();
5388        expected.sort();
5389        expected.truncate(limit);
5390
5391        let string_array = StringArray::from(test_cases.clone());
5392        let indices: Vec<u32> = (0..test_cases.len() as u32).collect();
5393        let result = sort_bytes(
5394            &string_array,
5395            indices,
5396            vec![],
5397            SortOptions::default(),
5398            Some(limit),
5399        );
5400
5401        let sorted_strings: Vec<&str> = result
5402            .values()
5403            .iter()
5404            .map(|&idx| test_cases[idx as usize])
5405            .collect();
5406
5407        assert_eq!(sorted_strings, expected);
5408        assert_eq!(sorted_strings.len(), limit);
5409    }
5410}