Skip to main content

arrow_ord/
sort.rs

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