1#![deny(clippy::allow_attributes)]
33#![deny(rustdoc::broken_intra_doc_links)]
34#![warn(missing_docs)]
35
36use arrow_array::cast::AsArray;
37use arrow_array::types::*;
38use arrow_array::*;
39use arrow_buffer::{ArrowNativeType, NullBuffer};
40use arrow_schema::{ArrowError, DataType, SortOptions};
41use std::{cmp::Ordering, collections::HashMap};
42
43fn compare_run_end_encoded<R: RunEndIndexType>(
44 left: &dyn Array,
45 right: &dyn Array,
46 opts: SortOptions,
47) -> Result<DynComparator, ArrowError> {
48 let left = left.as_run::<R>();
49 let right = right.as_run::<R>();
50
51 let c_opts = child_opts(opts);
52 let cmp = make_comparator(left.values().as_ref(), right.values().as_ref(), c_opts)?;
53
54 let l_run_ends = left.run_ends().clone();
55 let r_run_ends = right.run_ends().clone();
56
57 let f = compare(left, right, opts, move |i, j| {
58 let l_physical = l_run_ends.get_physical_index(i);
59 let r_physical = r_run_ends.get_physical_index(j);
60 cmp(l_physical, r_physical)
61 });
62 Ok(f)
63}
64
65pub type DynComparator = Box<dyn Fn(usize, usize) -> Ordering + Send + Sync>;
67
68fn child_opts(opts: SortOptions) -> SortOptions {
71 SortOptions {
72 descending: false,
73 nulls_first: opts.nulls_first != opts.descending,
74 }
75}
76
77fn compare<A, F>(l: &A, r: &A, opts: SortOptions, cmp: F) -> DynComparator
78where
79 A: Array + Clone,
80 F: Fn(usize, usize) -> Ordering + Send + Sync + 'static,
81{
82 let l = l.logical_nulls().filter(|x| x.null_count() > 0);
83 let r = r.logical_nulls().filter(|x| x.null_count() > 0);
84 match (opts.nulls_first, opts.descending) {
85 (true, true) => compare_impl::<true, true, _>(l, r, cmp),
86 (true, false) => compare_impl::<true, false, _>(l, r, cmp),
87 (false, true) => compare_impl::<false, true, _>(l, r, cmp),
88 (false, false) => compare_impl::<false, false, _>(l, r, cmp),
89 }
90}
91
92fn compare_impl<const NULLS_FIRST: bool, const DESCENDING: bool, F>(
93 l: Option<NullBuffer>,
94 r: Option<NullBuffer>,
95 cmp: F,
96) -> DynComparator
97where
98 F: Fn(usize, usize) -> Ordering + Send + Sync + 'static,
99{
100 let cmp = move |i, j| match DESCENDING {
101 true => cmp(i, j).reverse(),
102 false => cmp(i, j),
103 };
104
105 let (left_null, right_null) = match NULLS_FIRST {
106 true => (Ordering::Less, Ordering::Greater),
107 false => (Ordering::Greater, Ordering::Less),
108 };
109
110 match (l, r) {
111 (None, None) => Box::new(cmp),
112 (Some(l), None) => Box::new(move |i, j| match l.is_null(i) {
113 true => left_null,
114 false => cmp(i, j),
115 }),
116 (None, Some(r)) => Box::new(move |i, j| match r.is_null(j) {
117 true => right_null,
118 false => cmp(i, j),
119 }),
120 (Some(l), Some(r)) => Box::new(move |i, j| match (l.is_null(i), r.is_null(j)) {
121 (true, true) => Ordering::Equal,
122 (true, false) => left_null,
123 (false, true) => right_null,
124 (false, false) => cmp(i, j),
125 }),
126 }
127}
128
129fn compare_primitive<T: ArrowPrimitiveType>(
130 left: &dyn Array,
131 right: &dyn Array,
132 opts: SortOptions,
133) -> DynComparator
134where
135 T::Native: ArrowNativeTypeOp,
136{
137 let left = left.as_primitive::<T>();
138 let right = right.as_primitive::<T>();
139 let l_values = left.values().clone();
140 let r_values = right.values().clone();
141
142 compare(&left, &right, opts, move |i, j| {
143 l_values[i].compare(r_values[j])
144 })
145}
146
147fn compare_boolean(left: &dyn Array, right: &dyn Array, opts: SortOptions) -> DynComparator {
148 let left = left.as_boolean();
149 let right = right.as_boolean();
150
151 let l_values = left.values().clone();
152 let r_values = right.values().clone();
153
154 compare(left, right, opts, move |i, j| {
155 l_values.value(i).cmp(&r_values.value(j))
156 })
157}
158
159fn compare_bytes<T: ByteArrayType>(
160 left: &dyn Array,
161 right: &dyn Array,
162 opts: SortOptions,
163) -> DynComparator {
164 let left = left.as_bytes::<T>();
165 let right = right.as_bytes::<T>();
166
167 let l = left.clone();
168 let r = right.clone();
169 compare(left, right, opts, move |i, j| {
170 let l: &[u8] = l.value(i).as_ref();
171 let r: &[u8] = r.value(j).as_ref();
172 l.cmp(r)
173 })
174}
175
176fn compare_byte_view<T: ByteViewType>(
177 left: &dyn Array,
178 right: &dyn Array,
179 opts: SortOptions,
180) -> DynComparator {
181 let left = left.as_byte_view::<T>();
182 let right = right.as_byte_view::<T>();
183
184 let l = left.clone();
185 let r = right.clone();
186 compare(left, right, opts, move |i, j| {
187 compare_byte_view_values(&l, i, &r, j)
188 })
189}
190
191fn compare_byte_view_values<T: ByteViewType>(
192 left: &GenericByteViewArray<T>,
193 left_idx: usize,
194 right: &GenericByteViewArray<T>,
195 right_idx: usize,
196) -> Ordering {
197 assert!(left_idx < left.len());
198 assert!(right_idx < right.len());
199
200 if left.data_buffers().is_empty() && right.data_buffers().is_empty() {
201 let l_view = unsafe { left.views().get_unchecked(left_idx) };
202 let r_view = unsafe { right.views().get_unchecked(right_idx) };
203 return GenericByteViewArray::<T>::inline_key_fast(*l_view)
204 .cmp(&GenericByteViewArray::<T>::inline_key_fast(*r_view));
205 }
206
207 unsafe { GenericByteViewArray::compare_unchecked(left, left_idx, right, right_idx) }
208}
209
210fn compare_dict<K: ArrowDictionaryKeyType>(
211 left: &dyn Array,
212 right: &dyn Array,
213 opts: SortOptions,
214) -> Result<DynComparator, ArrowError> {
215 let left = left.as_dictionary::<K>();
216 let right = right.as_dictionary::<K>();
217
218 let c_opts = child_opts(opts);
219 let cmp = make_comparator(left.values().as_ref(), right.values().as_ref(), c_opts)?;
220 let left_keys = left.keys().values().clone();
221 let right_keys = right.keys().values().clone();
222
223 let f = compare(left, right, opts, move |i, j| {
224 let l = left_keys[i].as_usize();
225 let r = right_keys[j].as_usize();
226 cmp(l, r)
227 });
228 Ok(f)
229}
230
231fn compare_list<O: OffsetSizeTrait>(
232 left: &dyn Array,
233 right: &dyn Array,
234 opts: SortOptions,
235) -> Result<DynComparator, ArrowError> {
236 let left = left.as_list::<O>();
237 let right = right.as_list::<O>();
238
239 let c_opts = child_opts(opts);
240 let cmp = make_comparator(left.values().as_ref(), right.values().as_ref(), c_opts)?;
241
242 let l_o = left.offsets().clone();
243 let r_o = right.offsets().clone();
244 let f = compare(left, right, opts, move |i, j| {
245 let l_end = l_o[i + 1].as_usize();
246 let l_start = l_o[i].as_usize();
247
248 let r_end = r_o[j + 1].as_usize();
249 let r_start = r_o[j].as_usize();
250
251 for (i, j) in (l_start..l_end).zip(r_start..r_end) {
252 match cmp(i, j) {
253 Ordering::Equal => continue,
254 r => return r,
255 }
256 }
257 (l_end - l_start).cmp(&(r_end - r_start))
258 });
259 Ok(f)
260}
261
262fn compare_fixed_list(
263 left: &dyn Array,
264 right: &dyn Array,
265 opts: SortOptions,
266) -> Result<DynComparator, ArrowError> {
267 let left = left.as_fixed_size_list();
268 let right = right.as_fixed_size_list();
269
270 let c_opts = child_opts(opts);
271 let cmp = make_comparator(left.values().as_ref(), right.values().as_ref(), c_opts)?;
272
273 let l_size = left.value_length().to_usize().unwrap();
274 let r_size = right.value_length().to_usize().unwrap();
275 let size_cmp = l_size.cmp(&r_size);
276
277 let f = compare(left, right, opts, move |i, j| {
278 let l_start = i * l_size;
279 let l_end = l_start + l_size;
280 let r_start = j * r_size;
281 let r_end = r_start + r_size;
282 for (i, j) in (l_start..l_end).zip(r_start..r_end) {
283 match cmp(i, j) {
284 Ordering::Equal => continue,
285 r => return r,
286 }
287 }
288 size_cmp
289 });
290 Ok(f)
291}
292
293fn compare_list_view<O: OffsetSizeTrait>(
294 left: &dyn Array,
295 right: &dyn Array,
296 opts: SortOptions,
297) -> Result<DynComparator, ArrowError> {
298 let left = left.as_list_view::<O>();
299 let right = right.as_list_view::<O>();
300
301 let c_opts = child_opts(opts);
302 let cmp = make_comparator(left.values().as_ref(), right.values().as_ref(), c_opts)?;
303
304 let l_offsets = left.offsets().clone();
305 let l_sizes = left.sizes().clone();
306 let r_offsets = right.offsets().clone();
307 let r_sizes = right.sizes().clone();
308
309 let f = compare(left, right, opts, move |i, j| {
310 let l_start = l_offsets[i].as_usize();
311 let l_len = l_sizes[i].as_usize();
312 let l_end = l_start + l_len;
313
314 let r_start = r_offsets[j].as_usize();
315 let r_len = r_sizes[j].as_usize();
316 let r_end = r_start + r_len;
317
318 for (i, j) in (l_start..l_end).zip(r_start..r_end) {
319 match cmp(i, j) {
320 Ordering::Equal => continue,
321 r => return r,
322 }
323 }
324 l_len.cmp(&r_len)
325 });
326 Ok(f)
327}
328
329fn compare_map(
330 left: &dyn Array,
331 right: &dyn Array,
332 opts: SortOptions,
333) -> Result<DynComparator, ArrowError> {
334 let left = left.as_map();
335 let right = right.as_map();
336
337 let c_opts = child_opts(opts);
338 let cmp = make_comparator(left.entries(), right.entries(), c_opts)?;
339
340 let l_o = left.offsets().clone();
341 let r_o = right.offsets().clone();
342 let f = compare(left, right, opts, move |i, j| {
343 let l_end = l_o[i + 1].as_usize();
344 let l_start = l_o[i].as_usize();
345
346 let r_end = r_o[j + 1].as_usize();
347 let r_start = r_o[j].as_usize();
348
349 for (i, j) in (l_start..l_end).zip(r_start..r_end) {
350 match cmp(i, j) {
351 Ordering::Equal => continue,
352 r => return r,
353 }
354 }
355 (l_end - l_start).cmp(&(r_end - r_start))
356 });
357 Ok(f)
358}
359
360fn compare_struct(
361 left: &dyn Array,
362 right: &dyn Array,
363 opts: SortOptions,
364) -> Result<DynComparator, ArrowError> {
365 let left = left.as_struct();
366 let right = right.as_struct();
367
368 if left.columns().len() != right.columns().len() {
369 return Err(ArrowError::InvalidArgumentError(
370 "Cannot compare StructArray with different number of columns".to_string(),
371 ));
372 }
373
374 let c_opts = child_opts(opts);
375 let columns = left.columns().iter().zip(right.columns());
376 let comparators = columns
377 .map(|(l, r)| make_comparator(l, r, c_opts))
378 .collect::<Result<Vec<_>, _>>()?;
379
380 let f = compare(left, right, opts, move |i, j| {
381 for cmp in &comparators {
382 match cmp(i, j) {
383 Ordering::Equal => continue,
384 r => return r,
385 }
386 }
387 Ordering::Equal
388 });
389 Ok(f)
390}
391
392fn compare_union(
393 left: &dyn Array,
394 right: &dyn Array,
395 opts: SortOptions,
396) -> Result<DynComparator, ArrowError> {
397 let left = left.as_union();
398 let right = right.as_union();
399
400 let (left_fields, left_mode) = match left.data_type() {
401 DataType::Union(fields, mode) => (fields, mode),
402 _ => unreachable!(),
403 };
404 let (right_fields, right_mode) = match right.data_type() {
405 DataType::Union(fields, mode) => (fields, mode),
406 _ => unreachable!(),
407 };
408
409 if left_fields != right_fields {
410 return Err(ArrowError::InvalidArgumentError(format!(
411 "Cannot compare UnionArrays with different fields: left={left_fields:?}, right={right_fields:?}"
412 )));
413 }
414
415 if left_mode != right_mode {
416 return Err(ArrowError::InvalidArgumentError(format!(
417 "Cannot compare UnionArrays with different modes: left={left_mode:?}, right={right_mode:?}"
418 )));
419 }
420
421 let c_opts = child_opts(opts);
422
423 let mut field_comparators = HashMap::with_capacity(left_fields.len());
424
425 for (type_id, _field) in left_fields.iter() {
426 let left_child = left.child(type_id);
427 let right_child = right.child(type_id);
428 let cmp = make_comparator(left_child.as_ref(), right_child.as_ref(), c_opts)?;
429
430 field_comparators.insert(type_id, cmp);
431 }
432
433 let left_type_ids = left.type_ids().clone();
434 let right_type_ids = right.type_ids().clone();
435
436 let left_offsets = left.offsets().cloned();
437 let right_offsets = right.offsets().cloned();
438
439 let f = compare(left, right, opts, move |i, j| {
440 let left_type_id = left_type_ids[i];
441 let right_type_id = right_type_ids[j];
442
443 match left_type_id.cmp(&right_type_id) {
444 Ordering::Equal => {
445 let left_offset = left_offsets.as_ref().map(|o| o[i] as usize).unwrap_or(i);
446 let right_offset = right_offsets.as_ref().map(|o| o[j] as usize).unwrap_or(j);
447
448 let cmp = field_comparators
449 .get(&left_type_id)
450 .expect("type id not found in field_comparators");
451
452 cmp(left_offset, right_offset)
453 }
454 other => other,
455 }
456 });
457 Ok(f)
458}
459
460pub fn make_comparator(
466 left: &dyn Array,
467 right: &dyn Array,
468 opts: SortOptions,
469) -> Result<DynComparator, ArrowError> {
470 use arrow_schema::DataType::*;
471
472 macro_rules! primitive_helper {
473 ($t:ty, $left:expr, $right:expr, $nulls_first:expr) => {
474 Ok(compare_primitive::<$t>($left, $right, $nulls_first))
475 };
476 }
477 downcast_primitive! {
478 left.data_type(), right.data_type() => (primitive_helper, left, right, opts),
479 (Boolean, Boolean) => Ok(compare_boolean(left, right, opts)),
480 (Utf8, Utf8) => Ok(compare_bytes::<Utf8Type>(left, right, opts)),
481 (LargeUtf8, LargeUtf8) => Ok(compare_bytes::<LargeUtf8Type>(left, right, opts)),
482 (Utf8View, Utf8View) => Ok(compare_byte_view::<StringViewType>(left, right, opts)),
483 (Binary, Binary) => Ok(compare_bytes::<BinaryType>(left, right, opts)),
484 (LargeBinary, LargeBinary) => Ok(compare_bytes::<LargeBinaryType>(left, right, opts)),
485 (BinaryView, BinaryView) => Ok(compare_byte_view::<BinaryViewType>(left, right, opts)),
486 (FixedSizeBinary(_), FixedSizeBinary(_)) => {
487 let left = left.as_fixed_size_binary();
488 let right = right.as_fixed_size_binary();
489
490 let l = left.clone();
491 let r = right.clone();
492 Ok(compare(left, right, opts, move |i, j| {
493 l.value(i).cmp(r.value(j))
494 }))
495 },
496 (List(_), List(_)) => compare_list::<i32>(left, right, opts),
497 (LargeList(_), LargeList(_)) => compare_list::<i64>(left, right, opts),
498 (ListView(_), ListView(_)) => compare_list_view::<i32>(left, right, opts),
499 (LargeListView(_), LargeListView(_)) => compare_list_view::<i64>(left, right, opts),
500 (FixedSizeList(_, _), FixedSizeList(_, _)) => compare_fixed_list(left, right, opts),
501 (Struct(_), Struct(_)) => compare_struct(left, right, opts),
502 (Dictionary(l_key, _), Dictionary(r_key, _)) => {
503 macro_rules! dict_helper {
504 ($t:ty, $left:expr, $right:expr, $opts: expr) => {
505 compare_dict::<$t>($left, $right, $opts)
506 };
507 }
508 downcast_integer! {
509 l_key.as_ref(), r_key.as_ref() => (dict_helper, left, right, opts),
510 _ => unreachable!()
511 }
512 },
513 (RunEndEncoded(l_run_ends, _), RunEndEncoded(r_run_ends, _)) => {
514 macro_rules! run_end_helper {
515 ($t:ty, $left:expr, $right:expr, $opts:expr) => {
516 compare_run_end_encoded::<$t>($left, $right, $opts)
517 };
518 }
519 downcast_run_end_index! {
520 l_run_ends.data_type(), r_run_ends.data_type() => (run_end_helper, left, right, opts),
521 _ => Err(ArrowError::InvalidArgumentError(format!(
522 "Cannot compare RunEndEncoded arrays with different run ends types: left={:?}, right={:?}",
523 l_run_ends.data_type(),
524 r_run_ends.data_type()
525 )))
526 }
527 },
528 (Map(_, _), Map(_, _)) => compare_map(left, right, opts),
529 (Null, Null) => Ok(Box::new(|_, _| Ordering::Equal)),
530 (Union(_, _), Union(_, _)) => compare_union(left, right, opts),
531 (lhs, rhs) => Err(ArrowError::InvalidArgumentError(match lhs == rhs {
532 true => format!("The data type type {lhs:?} has no natural order"),
533 false => "Can't compare arrays of different types".to_string(),
534 }))
535 }
536}
537
538#[cfg(test)]
539mod tests {
540 use super::*;
541 use arrow_array::builder::{Int32Builder, ListBuilder, MapBuilder, StringBuilder};
542 use arrow_buffer::{IntervalDayTime, NullBuffer, OffsetBuffer, ScalarBuffer, i256};
543 use arrow_schema::{ArrowError, DataType, Field, Fields, UnionFields};
544 use half::f16;
545 use std::cmp::Ordering;
546 use std::sync::Arc;
547
548 #[test]
549 fn test_fixed_size_binary() {
550 let items = vec![vec![1u8], vec![2u8]];
551 let array = FixedSizeBinaryArray::try_from_iter(items.into_iter()).unwrap();
552
553 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
554
555 assert_eq!(Ordering::Less, cmp(0, 1));
556 }
557
558 #[test]
559 fn test_fixed_size_binary_fixed_size_binary() {
560 let items = vec![vec![1u8]];
561 let array1 = FixedSizeBinaryArray::try_from_iter(items.into_iter()).unwrap();
562 let items = vec![vec![2u8]];
563 let array2 = FixedSizeBinaryArray::try_from_iter(items.into_iter()).unwrap();
564
565 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
566
567 assert_eq!(Ordering::Less, cmp(0, 0));
568 }
569
570 #[test]
571 fn test_i32() {
572 let array = Int32Array::from(vec![1, 2]);
573
574 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
575
576 assert_eq!(Ordering::Less, (cmp)(0, 1));
577 }
578
579 #[test]
580 fn test_i32_i32() {
581 let array1 = Int32Array::from(vec![1]);
582 let array2 = Int32Array::from(vec![2]);
583
584 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
585
586 assert_eq!(Ordering::Less, cmp(0, 0));
587 }
588
589 #[cfg_attr(miri, ignore)] #[test]
591 fn test_f16() {
592 let array = Float16Array::from(vec![f16::from_f32(1.0), f16::from_f32(2.0)]);
593
594 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
595
596 assert_eq!(Ordering::Less, cmp(0, 1));
597 }
598
599 #[test]
600 fn test_f64() {
601 let array = Float64Array::from(vec![1.0, 2.0]);
602
603 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
604
605 assert_eq!(Ordering::Less, cmp(0, 1));
606 }
607
608 #[test]
609 fn test_f64_nan() {
610 let array = Float64Array::from(vec![1.0, f64::NAN]);
611
612 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
613
614 assert_eq!(Ordering::Less, cmp(0, 1));
615 assert_eq!(Ordering::Equal, cmp(1, 1));
616 }
617
618 #[test]
619 fn test_f64_zeros() {
620 let array = Float64Array::from(vec![-0.0, 0.0]);
621
622 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
623
624 assert_eq!(Ordering::Less, cmp(0, 1));
625 assert_eq!(Ordering::Greater, cmp(1, 0));
626 }
627
628 #[test]
629 fn test_interval_day_time() {
630 let array = IntervalDayTimeArray::from(vec![
631 IntervalDayTimeType::make_value(0, 1000),
633 IntervalDayTimeType::make_value(1, 2),
635 IntervalDayTimeType::make_value(0, 90_000_000),
637 ]);
638
639 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
640
641 assert_eq!(Ordering::Less, cmp(0, 1));
642 assert_eq!(Ordering::Greater, cmp(1, 0));
643
644 assert_eq!(Ordering::Greater, cmp(1, 2));
648 assert_eq!(Ordering::Less, cmp(2, 1));
649 }
650
651 #[test]
652 fn test_interval_year_month() {
653 let array = IntervalYearMonthArray::from(vec![
654 IntervalYearMonthType::make_value(1, 0),
656 IntervalYearMonthType::make_value(0, 13),
658 IntervalYearMonthType::make_value(1, 1),
660 ]);
661
662 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
663
664 assert_eq!(Ordering::Less, cmp(0, 1));
665 assert_eq!(Ordering::Greater, cmp(1, 0));
666
667 assert_eq!(Ordering::Equal, cmp(1, 2));
669 assert_eq!(Ordering::Equal, cmp(2, 1));
670 }
671
672 #[test]
673 fn test_interval_month_day_nano() {
674 let array = IntervalMonthDayNanoArray::from(vec![
675 IntervalMonthDayNanoType::make_value(0, 100, 0),
677 IntervalMonthDayNanoType::make_value(1, 0, 0),
679 IntervalMonthDayNanoType::make_value(0, 100, 2),
681 ]);
682
683 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
684
685 assert_eq!(Ordering::Less, cmp(0, 1));
686 assert_eq!(Ordering::Greater, cmp(1, 0));
687
688 assert_eq!(Ordering::Greater, cmp(1, 2));
692 assert_eq!(Ordering::Less, cmp(2, 1));
693 }
694
695 #[test]
696 fn test_decimali32() {
697 let array = vec![Some(5_i32), Some(2_i32), Some(3_i32)]
698 .into_iter()
699 .collect::<Decimal32Array>()
700 .with_precision_and_scale(8, 6)
701 .unwrap();
702
703 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
704 assert_eq!(Ordering::Less, cmp(1, 0));
705 assert_eq!(Ordering::Greater, cmp(0, 2));
706 }
707
708 #[test]
709 fn test_decimali64() {
710 let array = vec![Some(5_i64), Some(2_i64), Some(3_i64)]
711 .into_iter()
712 .collect::<Decimal64Array>()
713 .with_precision_and_scale(16, 6)
714 .unwrap();
715
716 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
717 assert_eq!(Ordering::Less, cmp(1, 0));
718 assert_eq!(Ordering::Greater, cmp(0, 2));
719 }
720
721 #[test]
722 fn test_decimali128() {
723 let array = vec![Some(5_i128), Some(2_i128), Some(3_i128)]
724 .into_iter()
725 .collect::<Decimal128Array>()
726 .with_precision_and_scale(23, 6)
727 .unwrap();
728
729 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
730 assert_eq!(Ordering::Less, cmp(1, 0));
731 assert_eq!(Ordering::Greater, cmp(0, 2));
732 }
733
734 #[test]
735 fn test_decimali256() {
736 let array = vec![
737 Some(i256::from_i128(5_i128)),
738 Some(i256::from_i128(2_i128)),
739 Some(i256::from_i128(3_i128)),
740 ]
741 .into_iter()
742 .collect::<Decimal256Array>()
743 .with_precision_and_scale(53, 6)
744 .unwrap();
745
746 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
747 assert_eq!(Ordering::Less, cmp(1, 0));
748 assert_eq!(Ordering::Greater, cmp(0, 2));
749 }
750
751 #[test]
752 fn test_dict() {
753 let data = vec!["a", "b", "c", "a", "a", "c", "c"];
754 let array = data.into_iter().collect::<DictionaryArray<Int16Type>>();
755
756 let cmp = make_comparator(&array, &array, SortOptions::default()).unwrap();
757
758 assert_eq!(Ordering::Less, cmp(0, 1));
759 assert_eq!(Ordering::Equal, cmp(3, 4));
760 assert_eq!(Ordering::Greater, cmp(2, 3));
761 }
762
763 #[test]
764 fn test_multiple_dict() {
765 let d1 = vec!["a", "b", "c", "d"];
766 let a1 = d1.into_iter().collect::<DictionaryArray<Int16Type>>();
767 let d2 = vec!["e", "f", "g", "a"];
768 let a2 = d2.into_iter().collect::<DictionaryArray<Int16Type>>();
769
770 let cmp = make_comparator(&a1, &a2, SortOptions::default()).unwrap();
771
772 assert_eq!(Ordering::Less, cmp(0, 0));
773 assert_eq!(Ordering::Equal, cmp(0, 3));
774 assert_eq!(Ordering::Greater, cmp(1, 3));
775 }
776
777 #[test]
778 fn test_primitive_dict() {
779 let values = Int32Array::from(vec![1_i32, 0, 2, 5]);
780 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
781 let array1 = DictionaryArray::new(keys, Arc::new(values));
782
783 let values = Int32Array::from(vec![2_i32, 3, 4, 5]);
784 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
785 let array2 = DictionaryArray::new(keys, Arc::new(values));
786
787 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
788
789 assert_eq!(Ordering::Less, cmp(0, 0));
790 assert_eq!(Ordering::Less, cmp(0, 3));
791 assert_eq!(Ordering::Equal, cmp(3, 3));
792 assert_eq!(Ordering::Greater, cmp(3, 1));
793 assert_eq!(Ordering::Greater, cmp(3, 2));
794 }
795
796 #[test]
797 fn test_float_dict() {
798 let values = Float32Array::from(vec![1.0, 0.5, 2.1, 5.5]);
799 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
800 let array1 = DictionaryArray::try_new(keys, Arc::new(values)).unwrap();
801
802 let values = Float32Array::from(vec![1.2, 3.2, 4.0, 5.5]);
803 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
804 let array2 = DictionaryArray::new(keys, Arc::new(values));
805
806 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
807
808 assert_eq!(Ordering::Less, cmp(0, 0));
809 assert_eq!(Ordering::Less, cmp(0, 3));
810 assert_eq!(Ordering::Equal, cmp(3, 3));
811 assert_eq!(Ordering::Greater, cmp(3, 1));
812 assert_eq!(Ordering::Greater, cmp(3, 2));
813 }
814
815 #[test]
816 fn test_timestamp_dict() {
817 let values = TimestampSecondArray::from(vec![1, 0, 2, 5]);
818 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
819 let array1 = DictionaryArray::new(keys, Arc::new(values));
820
821 let values = TimestampSecondArray::from(vec![2, 3, 4, 5]);
822 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
823 let array2 = DictionaryArray::new(keys, Arc::new(values));
824
825 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
826
827 assert_eq!(Ordering::Less, cmp(0, 0));
828 assert_eq!(Ordering::Less, cmp(0, 3));
829 assert_eq!(Ordering::Equal, cmp(3, 3));
830 assert_eq!(Ordering::Greater, cmp(3, 1));
831 assert_eq!(Ordering::Greater, cmp(3, 2));
832 }
833
834 #[test]
835 fn test_interval_dict() {
836 let v1 = IntervalDayTime::new(0, 1);
837 let v2 = IntervalDayTime::new(0, 2);
838 let v3 = IntervalDayTime::new(12, 2);
839
840 let values = IntervalDayTimeArray::from(vec![Some(v1), Some(v2), None, Some(v3)]);
841 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
842 let array1 = DictionaryArray::new(keys, Arc::new(values));
843
844 let values = IntervalDayTimeArray::from(vec![Some(v3), Some(v2), None, Some(v1)]);
845 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
846 let array2 = DictionaryArray::new(keys, Arc::new(values));
847
848 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
849
850 assert_eq!(Ordering::Less, cmp(0, 0)); assert_eq!(Ordering::Equal, cmp(0, 3)); assert_eq!(Ordering::Greater, cmp(3, 3)); assert_eq!(Ordering::Greater, cmp(3, 1)); assert_eq!(Ordering::Greater, cmp(3, 2)); }
856
857 #[test]
858 fn test_duration_dict() {
859 let values = DurationSecondArray::from(vec![1, 0, 2, 5]);
860 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
861 let array1 = DictionaryArray::new(keys, Arc::new(values));
862
863 let values = DurationSecondArray::from(vec![2, 3, 4, 5]);
864 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
865 let array2 = DictionaryArray::new(keys, Arc::new(values));
866
867 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
868
869 assert_eq!(Ordering::Less, cmp(0, 0));
870 assert_eq!(Ordering::Less, cmp(0, 3));
871 assert_eq!(Ordering::Equal, cmp(3, 3));
872 assert_eq!(Ordering::Greater, cmp(3, 1));
873 assert_eq!(Ordering::Greater, cmp(3, 2));
874 }
875
876 #[test]
877 fn test_decimal_dict() {
878 let values = Decimal128Array::from(vec![1, 0, 2, 5]);
879 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
880 let array1 = DictionaryArray::new(keys, Arc::new(values));
881
882 let values = Decimal128Array::from(vec![2, 3, 4, 5]);
883 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
884 let array2 = DictionaryArray::new(keys, Arc::new(values));
885
886 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
887
888 assert_eq!(Ordering::Less, cmp(0, 0));
889 assert_eq!(Ordering::Less, cmp(0, 3));
890 assert_eq!(Ordering::Equal, cmp(3, 3));
891 assert_eq!(Ordering::Greater, cmp(3, 1));
892 assert_eq!(Ordering::Greater, cmp(3, 2));
893 }
894
895 #[test]
896 fn test_decimal256_dict() {
897 let values = Decimal256Array::from(vec![
898 i256::from_i128(1),
899 i256::from_i128(0),
900 i256::from_i128(2),
901 i256::from_i128(5),
902 ]);
903 let keys = Int8Array::from_iter_values([0, 0, 1, 3]);
904 let array1 = DictionaryArray::new(keys, Arc::new(values));
905
906 let values = Decimal256Array::from(vec![
907 i256::from_i128(2),
908 i256::from_i128(3),
909 i256::from_i128(4),
910 i256::from_i128(5),
911 ]);
912 let keys = Int8Array::from_iter_values([0, 1, 1, 3]);
913 let array2 = DictionaryArray::new(keys, Arc::new(values));
914
915 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
916
917 assert_eq!(Ordering::Less, cmp(0, 0));
918 assert_eq!(Ordering::Less, cmp(0, 3));
919 assert_eq!(Ordering::Equal, cmp(3, 3));
920 assert_eq!(Ordering::Greater, cmp(3, 1));
921 assert_eq!(Ordering::Greater, cmp(3, 2));
922 }
923
924 fn test_bytes_impl<T: ByteArrayType>() {
925 let offsets = OffsetBuffer::from_lengths([3, 3, 1]);
926 let a = GenericByteArray::<T>::new(offsets, b"abcdefa".into(), None);
927 let cmp = make_comparator(&a, &a, SortOptions::default()).unwrap();
928
929 assert_eq!(Ordering::Less, cmp(0, 1));
930 assert_eq!(Ordering::Greater, cmp(0, 2));
931 assert_eq!(Ordering::Equal, cmp(1, 1));
932 }
933
934 #[test]
935 fn test_bytes() {
936 test_bytes_impl::<Utf8Type>();
937 test_bytes_impl::<LargeUtf8Type>();
938 test_bytes_impl::<BinaryType>();
939 test_bytes_impl::<LargeBinaryType>();
940 }
941
942 fn assert_cmp_cases<A: Array>(
943 array1: &A,
944 array2: &A,
945 opts: SortOptions,
946 cases: &[(usize, usize, Ordering)],
947 ) {
948 let cmp = make_comparator(array1, array2, opts).unwrap();
949 for (left, right, expected) in cases {
950 assert_eq!(cmp(*left, *right), *expected);
951 }
952 }
953
954 #[test]
955 fn test_lists() {
956 let mut a = ListBuilder::new(ListBuilder::new(Int32Builder::new()));
957 a.extend([
958 Some(vec![Some(vec![Some(1), Some(2), None]), Some(vec![None])]),
959 Some(vec![
960 Some(vec![Some(1), Some(2), Some(3)]),
961 Some(vec![Some(1)]),
962 ]),
963 Some(vec![]),
964 ]);
965 let a = a.finish();
966 let mut b = ListBuilder::new(ListBuilder::new(Int32Builder::new()));
967 b.extend([
968 Some(vec![Some(vec![Some(1), Some(2), None]), Some(vec![None])]),
969 Some(vec![
970 Some(vec![Some(1), Some(2), None]),
971 Some(vec![Some(1)]),
972 ]),
973 Some(vec![
974 Some(vec![Some(1), Some(2), Some(3), Some(4)]),
975 Some(vec![Some(1)]),
976 ]),
977 None,
978 ]);
979 let b = b.finish();
980
981 assert_cmp_cases(
983 &a,
984 &b,
985 SortOptions {
986 descending: false,
987 nulls_first: true,
988 },
989 &[
990 (0, 0, Ordering::Equal),
991 (0, 1, Ordering::Less),
992 (0, 2, Ordering::Less),
993 (1, 2, Ordering::Less),
994 (1, 3, Ordering::Greater),
995 (2, 0, Ordering::Less),
996 ],
997 );
998
999 assert_cmp_cases(
1001 &a,
1002 &b,
1003 SortOptions {
1004 descending: true,
1005 nulls_first: true,
1006 },
1007 &[
1008 (0, 0, Ordering::Equal),
1009 (0, 1, Ordering::Less),
1010 (0, 2, Ordering::Less),
1011 (1, 2, Ordering::Greater),
1012 (1, 3, Ordering::Greater),
1013 (2, 0, Ordering::Greater),
1014 ],
1015 );
1016
1017 assert_cmp_cases(
1019 &a,
1020 &b,
1021 SortOptions {
1022 descending: true,
1023 nulls_first: false,
1024 },
1025 &[
1026 (0, 0, Ordering::Equal),
1027 (0, 1, Ordering::Greater),
1028 (0, 2, Ordering::Greater),
1029 (1, 2, Ordering::Greater),
1030 (1, 3, Ordering::Less),
1031 (2, 0, Ordering::Greater),
1032 ],
1033 );
1034
1035 assert_cmp_cases(
1037 &a,
1038 &b,
1039 SortOptions {
1040 descending: false,
1041 nulls_first: false,
1042 },
1043 &[
1044 (0, 0, Ordering::Equal),
1045 (0, 1, Ordering::Greater),
1046 (0, 2, Ordering::Greater),
1047 (1, 2, Ordering::Less),
1048 (1, 3, Ordering::Less),
1049 (2, 0, Ordering::Less),
1050 ],
1051 );
1052 }
1053
1054 fn list_view_array<O: OffsetSizeTrait>(
1055 values: Vec<i32>,
1056 offsets: &[usize],
1057 sizes: &[usize],
1058 valid: Option<&[bool]>,
1059 ) -> GenericListViewArray<O> {
1060 let offsets = offsets
1061 .iter()
1062 .map(|v| O::from_usize(*v).unwrap())
1063 .collect::<ScalarBuffer<O>>();
1064 let sizes = sizes
1065 .iter()
1066 .map(|v| O::from_usize(*v).unwrap())
1067 .collect::<ScalarBuffer<O>>();
1068 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1069 let values = Int32Array::from(values);
1070 let nulls = valid.map(NullBuffer::from);
1071 GenericListViewArray::new(field, offsets, sizes, Arc::new(values), nulls)
1072 }
1073
1074 fn test_list_view_comparisons<O: OffsetSizeTrait>() {
1075 let array = list_view_array::<O>(
1076 vec![1, 2, 3, 4, 5],
1077 &[0, 2, 1, 0, 3],
1078 &[2, 2, 2, 0, 2],
1079 Some(&[true, true, true, true, false]),
1080 );
1081
1082 assert_cmp_cases(
1084 &array,
1085 &array,
1086 SortOptions {
1087 descending: false,
1088 nulls_first: true,
1089 },
1090 &[
1091 (0, 2, Ordering::Less), (1, 2, Ordering::Greater), (3, 0, Ordering::Less), (4, 0, Ordering::Less), ],
1096 );
1097
1098 assert_cmp_cases(
1100 &array,
1101 &array,
1102 SortOptions {
1103 descending: false,
1104 nulls_first: false,
1105 },
1106 &[
1107 (0, 2, Ordering::Less),
1108 (1, 2, Ordering::Greater),
1109 (3, 0, Ordering::Less),
1110 (4, 0, Ordering::Greater), ],
1112 );
1113
1114 assert_cmp_cases(
1116 &array,
1117 &array,
1118 SortOptions {
1119 descending: true,
1120 nulls_first: true,
1121 },
1122 &[
1123 (0, 2, Ordering::Greater),
1124 (1, 2, Ordering::Less),
1125 (3, 0, Ordering::Greater),
1126 (4, 0, Ordering::Less),
1127 ],
1128 );
1129
1130 assert_cmp_cases(
1132 &array,
1133 &array,
1134 SortOptions {
1135 descending: true,
1136 nulls_first: false,
1137 },
1138 &[
1139 (0, 2, Ordering::Greater),
1140 (1, 2, Ordering::Less),
1141 (3, 0, Ordering::Greater),
1142 (4, 0, Ordering::Greater),
1143 ],
1144 );
1145 }
1146
1147 #[test]
1148 fn test_list_view() {
1149 test_list_view_comparisons::<i32>();
1150 }
1151
1152 #[test]
1153 fn test_large_list_view() {
1154 test_list_view_comparisons::<i64>();
1155 }
1156
1157 #[test]
1158 fn test_struct() {
1159 let fields = Fields::from(vec![
1160 Field::new("a", DataType::Int32, true),
1161 Field::new_list("b", Field::new_list_field(DataType::Int32, true), true),
1162 ]);
1163
1164 let a = Int32Array::from(vec![Some(1), Some(2), None, None]);
1165 let mut b = ListBuilder::new(Int32Builder::new());
1166 b.extend([Some(vec![Some(1), Some(2)]), Some(vec![None]), None, None]);
1167 let b = b.finish();
1168
1169 let nulls = Some(NullBuffer::from_iter([true, true, true, false]));
1170 let values = vec![Arc::new(a) as _, Arc::new(b) as _];
1171 let s1 = StructArray::new(fields.clone(), values, nulls);
1172
1173 let a = Int32Array::from(vec![None, Some(2), None]);
1174 let mut b = ListBuilder::new(Int32Builder::new());
1175 b.extend([None, None, Some(vec![])]);
1176 let b = b.finish();
1177
1178 let values = vec![Arc::new(a) as _, Arc::new(b) as _];
1179 let s2 = StructArray::new(fields.clone(), values, None);
1180
1181 let opts = SortOptions {
1182 descending: false,
1183 nulls_first: true,
1184 };
1185 let cmp = make_comparator(&s1, &s2, opts).unwrap();
1186 assert_eq!(cmp(0, 1), Ordering::Less); assert_eq!(cmp(0, 0), Ordering::Greater); assert_eq!(cmp(1, 1), Ordering::Greater); assert_eq!(cmp(2, 2), Ordering::Less); assert_eq!(cmp(3, 0), Ordering::Less); assert_eq!(cmp(2, 0), Ordering::Equal); assert_eq!(cmp(3, 0), Ordering::Less); let opts = SortOptions {
1195 descending: true,
1196 nulls_first: true,
1197 };
1198 let cmp = make_comparator(&s1, &s2, opts).unwrap();
1199 assert_eq!(cmp(0, 1), Ordering::Greater); assert_eq!(cmp(0, 0), Ordering::Greater); assert_eq!(cmp(1, 1), Ordering::Greater); assert_eq!(cmp(2, 2), Ordering::Less); assert_eq!(cmp(3, 0), Ordering::Less); assert_eq!(cmp(2, 0), Ordering::Equal); assert_eq!(cmp(3, 0), Ordering::Less); let opts = SortOptions {
1208 descending: true,
1209 nulls_first: false,
1210 };
1211 let cmp = make_comparator(&s1, &s2, opts).unwrap();
1212 assert_eq!(cmp(0, 1), Ordering::Greater); assert_eq!(cmp(0, 0), Ordering::Less); assert_eq!(cmp(1, 1), Ordering::Less); assert_eq!(cmp(2, 2), Ordering::Greater); assert_eq!(cmp(3, 0), Ordering::Greater); assert_eq!(cmp(2, 0), Ordering::Equal); assert_eq!(cmp(3, 0), Ordering::Greater); let opts = SortOptions {
1221 descending: false,
1222 nulls_first: false,
1223 };
1224 let cmp = make_comparator(&s1, &s2, opts).unwrap();
1225 assert_eq!(cmp(0, 1), Ordering::Less); assert_eq!(cmp(0, 0), Ordering::Less); assert_eq!(cmp(1, 1), Ordering::Less); assert_eq!(cmp(2, 2), Ordering::Greater); assert_eq!(cmp(3, 0), Ordering::Greater); assert_eq!(cmp(2, 0), Ordering::Equal); assert_eq!(cmp(3, 0), Ordering::Greater); }
1233
1234 #[test]
1235 fn test_map() {
1236 let string_builder = StringBuilder::new();
1239 let int_builder = Int32Builder::new();
1240 let mut map1_builder = MapBuilder::new(None, string_builder, int_builder);
1241
1242 map1_builder.keys().append_value("a");
1244 map1_builder.values().append_value(100);
1245 map1_builder.keys().append_value("b");
1246 map1_builder.values().append_value(1);
1247 map1_builder.append(true).unwrap();
1248
1249 map1_builder.keys().append_value("b");
1251 map1_builder.values().append_value(999);
1252 map1_builder.keys().append_value("c");
1253 map1_builder.values().append_value(1);
1254 map1_builder.append(true).unwrap();
1255
1256 map1_builder.append(true).unwrap();
1258
1259 map1_builder.keys().append_value("x");
1261 map1_builder.values().append_value(1);
1262 map1_builder.append(true).unwrap();
1263
1264 let map1 = map1_builder.finish();
1265
1266 let string_builder = StringBuilder::new();
1269 let int_builder = Int32Builder::new();
1270 let mut map2_builder = MapBuilder::new(None, string_builder, int_builder);
1271
1272 map2_builder.keys().append_value("a");
1274 map2_builder.values().append_value(1);
1275 map2_builder.keys().append_value("c");
1276 map2_builder.values().append_value(999);
1277 map2_builder.append(true).unwrap();
1278
1279 map2_builder.keys().append_value("b");
1281 map2_builder.values().append_value(1);
1282 map2_builder.keys().append_value("d");
1283 map2_builder.values().append_value(999);
1284 map2_builder.append(true).unwrap();
1285
1286 map2_builder.keys().append_value("a");
1288 map2_builder.values().append_value(1);
1289 map2_builder.append(true).unwrap();
1290
1291 map2_builder.append(false).unwrap();
1293
1294 let map2 = map2_builder.finish();
1295
1296 let opts = SortOptions {
1297 descending: false,
1298 nulls_first: true,
1299 };
1300 let cmp = make_comparator(&map1, &map2, opts).unwrap();
1301
1302 assert_eq!(cmp(0, 0), Ordering::Greater);
1306
1307 assert_eq!(cmp(1, 1), Ordering::Greater);
1310
1311 assert_eq!(cmp(0, 1), Ordering::Less);
1313
1314 assert_eq!(cmp(2, 2), Ordering::Less); assert_eq!(cmp(3, 3), Ordering::Greater); assert_eq!(cmp(3, 0), Ordering::Greater); assert_eq!(cmp(2, 0), Ordering::Less); let opts = SortOptions {
1327 descending: true,
1328 nulls_first: true,
1329 };
1330 let cmp = make_comparator(&map1, &map2, opts).unwrap();
1331
1332 assert_eq!(cmp(0, 0), Ordering::Less); assert_eq!(cmp(1, 1), Ordering::Less); assert_eq!(cmp(0, 1), Ordering::Greater); assert_eq!(cmp(3, 3), Ordering::Greater); assert_eq!(cmp(2, 2), Ordering::Greater); let opts = SortOptions {
1340 descending: false,
1341 nulls_first: false,
1342 };
1343 let cmp = make_comparator(&map1, &map2, opts).unwrap();
1344
1345 assert_eq!(cmp(0, 0), Ordering::Greater); assert_eq!(cmp(1, 1), Ordering::Greater); assert_eq!(cmp(3, 3), Ordering::Less); assert_eq!(cmp(2, 2), Ordering::Less); }
1351
1352 #[test]
1353 fn test_map_vs_list_consistency() {
1354 let string_builder = StringBuilder::new();
1357 let int_builder = Int32Builder::new();
1358 let mut map1_builder = MapBuilder::new(None, string_builder, int_builder);
1359
1360 map1_builder.keys().append_value("a");
1362 map1_builder.values().append_value(1);
1363 map1_builder.keys().append_value("b");
1364 map1_builder.values().append_value(2);
1365 map1_builder.append(true).unwrap();
1366
1367 map1_builder.keys().append_value("x");
1369 map1_builder.values().append_value(10);
1370 map1_builder.append(true).unwrap();
1371
1372 map1_builder.append(true).unwrap();
1374
1375 map1_builder.keys().append_value("c");
1377 map1_builder.values().append_value(3);
1378 map1_builder.append(true).unwrap();
1379
1380 let map1 = map1_builder.finish();
1381
1382 let string_builder = StringBuilder::new();
1384 let int_builder = Int32Builder::new();
1385 let mut map2_builder = MapBuilder::new(None, string_builder, int_builder);
1386
1387 map2_builder.keys().append_value("a");
1389 map2_builder.values().append_value(1);
1390 map2_builder.keys().append_value("b");
1391 map2_builder.values().append_value(2);
1392 map2_builder.append(true).unwrap();
1393
1394 map2_builder.keys().append_value("y");
1396 map2_builder.values().append_value(20);
1397 map2_builder.append(true).unwrap();
1398
1399 map2_builder.keys().append_value("d");
1401 map2_builder.values().append_value(4);
1402 map2_builder.append(true).unwrap();
1403
1404 map2_builder.append(false).unwrap();
1406
1407 let map2 = map2_builder.finish();
1408
1409 let list1: ListArray = map1.clone().into();
1411 let list2: ListArray = map2.clone().into();
1412
1413 let test_cases = [
1414 SortOptions {
1415 descending: false,
1416 nulls_first: true,
1417 },
1418 SortOptions {
1419 descending: true,
1420 nulls_first: true,
1421 },
1422 SortOptions {
1423 descending: false,
1424 nulls_first: false,
1425 },
1426 SortOptions {
1427 descending: true,
1428 nulls_first: false,
1429 },
1430 ];
1431
1432 for opts in test_cases {
1433 let map_cmp = make_comparator(&map1, &map2, opts).unwrap();
1434 let list_cmp = make_comparator(&list1, &list2, opts).unwrap();
1435
1436 for i in 0..map1.len() {
1438 for j in 0..map2.len() {
1439 let map_result = map_cmp(i, j);
1440 let list_result = list_cmp(i, j);
1441 assert_eq!(
1442 map_result, list_result,
1443 "Map comparison and List comparison should be equal for indices ({i}, {j}) with opts {opts:?}. Map: {map_result:?}, List: {list_result:?}"
1444 );
1445 }
1446 }
1447 }
1448 }
1449
1450 #[test]
1451 fn test_dense_union() {
1452 let int_array = Int32Array::from(vec![1, 2, 3]);
1457 let str_array = StringArray::from(vec!["b", "a"]);
1458
1459 let type_ids = [0, 1, 0, 1, 0].into_iter().collect::<ScalarBuffer<i8>>();
1460 let offsets = [0, 0, 1, 1, 2].into_iter().collect::<ScalarBuffer<i32>>();
1461
1462 let union_fields = [
1463 (0, Arc::new(Field::new("A", DataType::Int32, false))),
1464 (1, Arc::new(Field::new("B", DataType::Utf8, false))),
1465 ]
1466 .into_iter()
1467 .collect::<UnionFields>();
1468
1469 let children = vec![Arc::new(int_array) as ArrayRef, Arc::new(str_array)];
1470
1471 let array1 =
1472 UnionArray::try_new(union_fields.clone(), type_ids, Some(offsets), children).unwrap();
1473
1474 let int_array2 = Int32Array::from(vec![2, 1]);
1478 let str_array2 = StringArray::from(vec!["a", "c"]);
1479 let type_ids2 = [0, 1, 0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1480 let offsets2 = [0, 0, 1, 1].into_iter().collect::<ScalarBuffer<i32>>();
1481
1482 let children2 = vec![Arc::new(int_array2) as ArrayRef, Arc::new(str_array2)];
1483
1484 let array2 =
1485 UnionArray::try_new(union_fields, type_ids2, Some(offsets2), children2).unwrap();
1486
1487 let opts = SortOptions {
1488 descending: false,
1489 nulls_first: true,
1490 };
1491
1492 let cmp = make_comparator(&array1, &array2, opts).unwrap();
1496
1497 assert_eq!(cmp(0, 0), Ordering::Less); assert_eq!(cmp(0, 1), Ordering::Less); assert_eq!(cmp(1, 1), Ordering::Greater); assert_eq!(cmp(2, 0), Ordering::Equal); assert_eq!(cmp(3, 1), Ordering::Equal); assert_eq!(cmp(1, 3), Ordering::Less); let opts_desc = SortOptions {
1522 descending: true,
1523 nulls_first: true,
1524 };
1525 let cmp_desc = make_comparator(&array1, &array2, opts_desc).unwrap();
1526
1527 assert_eq!(cmp_desc(0, 0), Ordering::Greater); assert_eq!(cmp_desc(0, 1), Ordering::Greater); assert_eq!(cmp_desc(1, 1), Ordering::Less); }
1531
1532 #[test]
1533 fn test_sparse_union() {
1534 let int_array = Int32Array::from(vec![Some(1), None, Some(3)]);
1538 let str_array = StringArray::from(vec![None, Some("b"), None]);
1539 let type_ids = [0, 1, 0].into_iter().collect::<ScalarBuffer<i8>>();
1540
1541 let union_fields = [
1542 (0, Arc::new(Field::new("a", DataType::Int32, false))),
1543 (1, Arc::new(Field::new("b", DataType::Utf8, false))),
1544 ]
1545 .into_iter()
1546 .collect::<UnionFields>();
1547
1548 let children = vec![Arc::new(int_array) as ArrayRef, Arc::new(str_array)];
1549
1550 let array = UnionArray::try_new(union_fields, type_ids, None, children).unwrap();
1551
1552 let opts = SortOptions::default();
1553 let cmp = make_comparator(&array, &array, opts).unwrap();
1554
1555 assert_eq!(cmp(0, 2), Ordering::Less); assert_eq!(cmp(0, 1), Ordering::Less); }
1560
1561 #[test]
1562 #[should_panic(expected = "index out of bounds")]
1563 fn test_union_out_of_bounds() {
1564 let int_array = Int32Array::from(vec![1, 2]);
1566 let str_array = StringArray::from(vec!["a"]);
1567
1568 let type_ids = [0, 1, 0].into_iter().collect::<ScalarBuffer<i8>>();
1569 let offsets = [0, 0, 1].into_iter().collect::<ScalarBuffer<i32>>();
1570
1571 let union_fields = [
1572 (0, Arc::new(Field::new("A", DataType::Int32, false))),
1573 (1, Arc::new(Field::new("B", DataType::Utf8, false))),
1574 ]
1575 .into_iter()
1576 .collect::<UnionFields>();
1577
1578 let children = vec![Arc::new(int_array) as ArrayRef, Arc::new(str_array)];
1579
1580 let array = UnionArray::try_new(union_fields, type_ids, Some(offsets), children).unwrap();
1581
1582 let opts = SortOptions::default();
1583 let cmp = make_comparator(&array, &array, opts).unwrap();
1584
1585 cmp(0, 3);
1587 }
1588
1589 #[test]
1590 fn test_union_incompatible_fields() {
1591 let int_array1 = Int32Array::from(vec![1, 2]);
1593 let str_array1 = StringArray::from(vec!["a", "b"]);
1594
1595 let type_ids1 = [0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1596 let offsets1 = [0, 0].into_iter().collect::<ScalarBuffer<i32>>();
1597
1598 let union_fields1 = [
1599 (0, Arc::new(Field::new("A", DataType::Int32, false))),
1600 (1, Arc::new(Field::new("B", DataType::Utf8, false))),
1601 ]
1602 .into_iter()
1603 .collect::<UnionFields>();
1604
1605 let children1 = vec![Arc::new(int_array1) as ArrayRef, Arc::new(str_array1)];
1606
1607 let array1 =
1608 UnionArray::try_new(union_fields1, type_ids1, Some(offsets1), children1).unwrap();
1609
1610 let int_array2 = Int32Array::from(vec![3, 4]);
1612 let float_array2 = Float64Array::from(vec![1.0, 2.0]);
1613
1614 let type_ids2 = [0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1615 let offsets2 = [0, 0].into_iter().collect::<ScalarBuffer<i32>>();
1616
1617 let union_fields2 = [
1618 (0, Arc::new(Field::new("A", DataType::Int32, false))),
1619 (1, Arc::new(Field::new("C", DataType::Float64, false))),
1620 ]
1621 .into_iter()
1622 .collect::<UnionFields>();
1623
1624 let children2 = vec![Arc::new(int_array2) as ArrayRef, Arc::new(float_array2)];
1625
1626 let array2 =
1627 UnionArray::try_new(union_fields2, type_ids2, Some(offsets2), children2).unwrap();
1628
1629 let opts = SortOptions::default();
1630
1631 let Result::Err(ArrowError::InvalidArgumentError(out)) =
1632 make_comparator(&array1, &array2, opts)
1633 else {
1634 panic!("expected error when making comparator of incompatible union arrays");
1635 };
1636
1637 assert_eq!(
1638 &out,
1639 "Cannot compare UnionArrays with different fields: left=[(0, Field { name: \"A\", data_type: Int32 }), (1, Field { name: \"B\", data_type: Utf8 })], right=[(0, Field { name: \"A\", data_type: Int32 }), (1, Field { name: \"C\", data_type: Float64 })]"
1640 );
1641 }
1642
1643 #[test]
1644 fn test_union_incompatible_modes() {
1645 let int_array1 = Int32Array::from(vec![1, 2]);
1647 let str_array1 = StringArray::from(vec!["a", "b"]);
1648
1649 let type_ids1 = [0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1650 let offsets1 = [0, 0].into_iter().collect::<ScalarBuffer<i32>>();
1651
1652 let union_fields1 = [
1653 (0, Arc::new(Field::new("A", DataType::Int32, false))),
1654 (1, Arc::new(Field::new("B", DataType::Utf8, false))),
1655 ]
1656 .into_iter()
1657 .collect::<UnionFields>();
1658
1659 let children1 = vec![Arc::new(int_array1) as ArrayRef, Arc::new(str_array1)];
1660
1661 let array1 =
1662 UnionArray::try_new(union_fields1.clone(), type_ids1, Some(offsets1), children1)
1663 .unwrap();
1664
1665 let int_array2 = Int32Array::from(vec![Some(3), None]);
1667 let str_array2 = StringArray::from(vec![None, Some("c")]);
1668
1669 let type_ids2 = [0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1670
1671 let children2 = vec![Arc::new(int_array2) as ArrayRef, Arc::new(str_array2)];
1672
1673 let array2 = UnionArray::try_new(union_fields1, type_ids2, None, children2).unwrap();
1674
1675 let opts = SortOptions::default();
1676
1677 let Result::Err(ArrowError::InvalidArgumentError(out)) =
1678 make_comparator(&array1, &array2, opts)
1679 else {
1680 panic!("expected error when making comparator of union arrays with different modes");
1681 };
1682
1683 assert_eq!(
1684 &out,
1685 "Cannot compare UnionArrays with different modes: left=Dense, right=Sparse"
1686 );
1687 }
1688
1689 #[test]
1690 fn test_null_array_cmp() {
1691 let a = NullArray::new(3);
1692 let b = NullArray::new(3);
1693 let cmp = make_comparator(&a, &b, SortOptions::default()).unwrap();
1694
1695 assert_eq!(cmp(0, 0), Ordering::Equal);
1696 assert_eq!(cmp(0, 1), Ordering::Equal);
1697 assert_eq!(cmp(2, 0), Ordering::Equal);
1698 }
1699
1700 #[test]
1701 fn test_run_end_encoded_int32() {
1702 let run_ends1 = Int32Array::from(vec![2, 5, 6]);
1706 let values1 = Int32Array::from(vec![1, 2, 3]);
1707 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1708
1709 let run_ends2 = Int32Array::from(vec![1, 3, 6]);
1712 let values2 = Int32Array::from(vec![1, 2, 3]);
1713 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1714
1715 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
1716
1717 assert_eq!(cmp(0, 0), Ordering::Equal);
1719 assert_eq!(cmp(0, 1), Ordering::Less);
1721 assert_eq!(cmp(2, 1), Ordering::Equal);
1723 assert_eq!(cmp(5, 5), Ordering::Equal);
1725 assert_eq!(cmp(1, 2), Ordering::Less);
1727 assert_eq!(cmp(4, 4), Ordering::Less);
1729 }
1730
1731 #[test]
1732 fn test_run_end_encoded_with_nulls() {
1733 let run_ends1 = Int32Array::from(vec![2, 4, 5]);
1737 let values1 = Int32Array::from(vec![Some(1), None, Some(2)]);
1738 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1739
1740 let run_ends2 = Int32Array::from(vec![1, 3, 4, 5]);
1743 let values2 = Int32Array::from(vec![None, Some(1), Some(2), None]);
1744 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1745
1746 let opts = SortOptions::default();
1747 let cmp = make_comparator(&array1, &array2, opts).unwrap();
1748
1749 assert_eq!(cmp(0, 1), Ordering::Equal);
1751 assert_eq!(cmp(2, 0), Ordering::Equal);
1753 assert_eq!(cmp(0, 0), Ordering::Greater);
1755 assert_eq!(cmp(2, 1), Ordering::Less);
1757 }
1758
1759 #[test]
1760 fn test_run_end_encoded_int16() {
1761 let run_ends1 = Int16Array::from(vec![3_i16, 5, 6]);
1763 let values1 = StringArray::from(vec!["a", "b", "c"]);
1764 let array1 = RunArray::<Int16Type>::try_new(&run_ends1, &values1).unwrap();
1765
1766 let run_ends2 = Int16Array::from(vec![2_i16, 4, 6]);
1767 let values2 = StringArray::from(vec!["a", "b", "c"]);
1768 let array2 = RunArray::<Int16Type>::try_new(&run_ends2, &values2).unwrap();
1769
1770 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
1771
1772 assert_eq!(cmp(0, 0), Ordering::Equal); assert_eq!(cmp(2, 2), Ordering::Less); assert_eq!(cmp(3, 2), Ordering::Equal); assert_eq!(cmp(5, 4), Ordering::Equal); }
1779
1780 #[test]
1781 fn test_run_end_encoded_int64() {
1782 let run_ends1 = Int64Array::from(vec![2_i64, 4, 6]);
1784 let values1 = Int64Array::from(vec![10_i64, 20, 30]);
1785 let array1 = RunArray::<Int64Type>::try_new(&run_ends1, &values1).unwrap();
1786
1787 let run_ends2 = Int64Array::from(vec![3_i64, 5, 6]);
1788 let values2 = Int64Array::from(vec![10_i64, 20, 30]);
1789 let array2 = RunArray::<Int64Type>::try_new(&run_ends2, &values2).unwrap();
1790
1791 let cmp = make_comparator(&array1, &array2, SortOptions::default()).unwrap();
1792
1793 assert_eq!(cmp(0, 0), Ordering::Equal); assert_eq!(cmp(1, 2), Ordering::Equal); assert_eq!(cmp(2, 3), Ordering::Equal); assert_eq!(cmp(4, 4), Ordering::Greater); }
1800
1801 #[test]
1802 fn test_run_end_encoded_sliced() {
1803 let run_ends = Int32Array::from(vec![2, 5, 7, 8]);
1807 let values = Int32Array::from(vec![1, 2, 3, 4]);
1808 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1809
1810 let slice1 = array.slice(1, 4);
1812 let slice2 = array.slice(3, 4);
1814
1815 let cmp = make_comparator(&slice1, &slice2, SortOptions::default()).unwrap();
1816
1817 assert_eq!(cmp(0, 0), Ordering::Less);
1819 assert_eq!(cmp(1, 0), Ordering::Equal);
1821 assert_eq!(cmp(3, 2), Ordering::Less);
1823 assert_eq!(cmp(1, 3), Ordering::Less);
1825
1826 let run_ends2 = Int32Array::from(vec![2, 4]);
1828 let values2 = Int32Array::from(vec![1, 2]);
1829 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1830
1831 let cmp = make_comparator(&slice1, &array2, SortOptions::default()).unwrap();
1832
1833 assert_eq!(cmp(0, 0), Ordering::Equal);
1835 assert_eq!(cmp(1, 1), Ordering::Greater);
1837 assert_eq!(cmp(3, 3), Ordering::Equal);
1839 }
1840
1841 #[test]
1842 fn test_run_end_encoded_sliced_with_nulls() {
1843 let run_ends = Int32Array::from(vec![2, 4, 6, 7, 8]);
1847 let values = Int32Array::from(vec![Some(1), None, Some(2), None, Some(3)]);
1848 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1849
1850 let slice1 = array.slice(1, 5);
1852 let slice2 = array.slice(3, 5);
1854
1855 let opts = SortOptions::default(); let cmp = make_comparator(&slice1, &slice2, opts).unwrap();
1857
1858 assert_eq!(cmp(0, 0), Ordering::Greater);
1860 assert_eq!(cmp(1, 0), Ordering::Equal);
1862 assert_eq!(cmp(1, 1), Ordering::Less);
1864 assert_eq!(cmp(3, 1), Ordering::Equal);
1866 assert_eq!(cmp(4, 4), Ordering::Less);
1868 assert_eq!(cmp(3, 3), Ordering::Greater);
1870 }
1871
1872 #[test]
1873 fn test_run_end_encoded_different_types() {
1874 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1876 let values1 = Int32Array::from(vec![1, 2, 3]);
1877 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1878
1879 let run_ends2 = Int64Array::from(vec![2_i64, 4, 6]);
1880 let values2 = Int64Array::from(vec![1_i64, 2, 3]);
1881 let array2 = RunArray::<Int64Type>::try_new(&run_ends2, &values2).unwrap();
1882
1883 let result = make_comparator(&array1, &array2, SortOptions::default());
1884 assert!(result.is_err());
1885 let err = match result {
1886 Err(e) => e.to_string(),
1887 Ok(_) => panic!("Expected error"),
1888 };
1889 assert!(err.contains("Cannot compare RunEndEncoded arrays"));
1890 }
1891}