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