Skip to main content

arrow_ord/
sort.rs

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