Skip to main content

arrow_ord/
sort.rs

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