1pub(crate) mod aggregate;
21pub mod expr;
22pub mod hex;
23pub mod memory;
24pub mod proxy;
25pub mod string_utils;
26
27use crate::assert_or_internal_err;
28use crate::error::{_exec_datafusion_err, _exec_err, _internal_datafusion_err};
29use crate::{Result, ScalarValue};
30use arrow::array::{
31 Array, ArrayRef, FixedSizeListArray, LargeListArray, ListArray, OffsetSizeTrait,
32 cast::AsArray,
33};
34use arrow::array::{
35 ArrowPrimitiveType, BooleanArray, Datum, GenericListArray, Int32Array, Int64Array,
36 MutableArrayData, PrimitiveArray, make_array,
37};
38use arrow::array::{LargeListViewArray, ListViewArray};
39use arrow::buffer::{OffsetBuffer, ScalarBuffer};
40use arrow::compute::kernels::cmp::eq;
41use arrow::compute::kernels::length::length;
42use arrow::compute::{SortColumn, SortOptions, partition};
43use arrow::datatypes::{
44 ArrowNativeType, DataType, Field, Int32Type, Int64Type, SchemaRef,
45};
46#[cfg(feature = "sql")]
47use sqlparser::{ast::Ident, dialect::GenericDialect, parser::Parser};
48use std::borrow::{Borrow, Cow};
49use std::cmp::{Ordering, min};
50use std::collections::HashSet;
51use std::iter::repeat_n;
52use std::num::NonZero;
53use std::ops::Range;
54use std::sync::{Arc, LazyLock};
55use std::thread::available_parallelism;
56
57pub fn project_schema(
84 schema: &SchemaRef,
85 projection: Option<&impl AsRef<[usize]>>,
86) -> Result<SchemaRef> {
87 let schema = match projection {
88 Some(columns) => Arc::new(schema.project(columns.as_ref())?),
89 None => Arc::clone(schema),
90 };
91 Ok(schema)
92}
93
94pub fn extract_row_at_idx_to_buf(
96 columns: &[ArrayRef],
97 idx: usize,
98 buf: &mut Vec<ScalarValue>,
99) -> Result<()> {
100 buf.clear();
101
102 let iter = columns
103 .iter()
104 .map(|arr| ScalarValue::try_from_array(arr, idx));
105 for v in iter.into_iter() {
106 buf.push(v?);
107 }
108
109 Ok(())
110}
111pub fn get_row_at_idx(columns: &[ArrayRef], idx: usize) -> Result<Vec<ScalarValue>> {
113 columns
114 .iter()
115 .map(|arr| ScalarValue::try_from_array(arr, idx))
116 .collect()
117}
118
119pub fn compare_rows(
121 x: &[ScalarValue],
122 y: &[ScalarValue],
123 sort_options: &[SortOptions],
124) -> Result<Ordering> {
125 let zip_it = x.iter().zip(y.iter()).zip(sort_options.iter());
126 for ((lhs, rhs), sort_options) in zip_it {
128 let result = match (lhs.is_null(), rhs.is_null(), sort_options.nulls_first) {
130 (true, false, false) | (false, true, true) => Ordering::Greater,
131 (true, false, true) | (false, true, false) => Ordering::Less,
132 (false, false, _) => {
133 if sort_options.descending {
134 rhs.try_cmp(lhs)?
135 } else {
136 lhs.try_cmp(rhs)?
137 }
138 }
139 (true, true, _) => continue,
140 };
141 if result != Ordering::Equal {
142 return Ok(result);
143 }
144 }
145 Ok(Ordering::Equal)
146}
147
148pub fn bisect<const SIDE: bool>(
153 item_columns: &[ArrayRef],
154 target: &[ScalarValue],
155 sort_options: &[SortOptions],
156) -> Result<usize> {
157 let low: usize = 0;
158 let high: usize = item_columns
159 .first()
160 .ok_or_else(|| _internal_datafusion_err!("Column array shouldn't be empty"))?
161 .len();
162 let compare_fn = |current: &[ScalarValue], target: &[ScalarValue]| {
163 let cmp = compare_rows(current, target, sort_options)?;
164 Ok(if SIDE { cmp.is_lt() } else { cmp.is_le() })
165 };
166 find_bisect_point(item_columns, target, compare_fn, low, high)
167}
168
169pub fn find_bisect_point<F>(
176 item_columns: &[ArrayRef],
177 target: &[ScalarValue],
178 compare_fn: F,
179 mut low: usize,
180 mut high: usize,
181) -> Result<usize>
182where
183 F: Fn(&[ScalarValue], &[ScalarValue]) -> Result<bool>,
184{
185 while low < high {
186 let mid = ((high - low) / 2) + low;
187 let val = get_row_at_idx(item_columns, mid)?;
188 if compare_fn(&val, target)? {
189 low = mid + 1;
190 } else {
191 high = mid;
192 }
193 }
194 Ok(low)
195}
196
197pub fn linear_search<const SIDE: bool>(
202 item_columns: &[ArrayRef],
203 target: &[ScalarValue],
204 sort_options: &[SortOptions],
205) -> Result<usize> {
206 let low: usize = 0;
207 let high: usize = item_columns
208 .first()
209 .ok_or_else(|| _internal_datafusion_err!("Column array shouldn't be empty"))?
210 .len();
211 let compare_fn = |current: &[ScalarValue], target: &[ScalarValue]| {
212 let cmp = compare_rows(current, target, sort_options)?;
213 Ok(if SIDE { cmp.is_lt() } else { cmp.is_le() })
214 };
215 search_in_slice(item_columns, target, compare_fn, low, high)
216}
217
218pub fn search_in_slice<F>(
223 item_columns: &[ArrayRef],
224 target: &[ScalarValue],
225 compare_fn: F,
226 mut low: usize,
227 high: usize,
228) -> Result<usize>
229where
230 F: Fn(&[ScalarValue], &[ScalarValue]) -> Result<bool>,
231{
232 while low < high {
233 let val = get_row_at_idx(item_columns, low)?;
234 if !compare_fn(&val, target)? {
235 break;
236 }
237 low += 1;
238 }
239 Ok(low)
240}
241
242pub fn evaluate_partition_ranges(
247 num_rows: usize,
248 partition_columns: &[SortColumn],
249) -> Result<Vec<Range<usize>>> {
250 Ok(if partition_columns.is_empty() {
251 vec![Range {
252 start: 0,
253 end: num_rows,
254 }]
255 } else {
256 let cols: Vec<_> = partition_columns
257 .iter()
258 .map(|x| Arc::clone(&x.values))
259 .collect();
260 partition(&cols)?.ranges()
261 })
262}
263
264pub fn quote_identifier(s: &str) -> Cow<'_, str> {
269 if needs_quotes(s) {
270 Cow::Owned(format!("\"{}\"", s.replace('"', "\"\"")))
271 } else {
272 Cow::Borrowed(s)
273 }
274}
275
276fn needs_quotes(s: &str) -> bool {
278 let mut chars = s.chars();
279
280 if let Some(first_char) = chars.next()
282 && !(first_char.is_ascii_lowercase() || first_char == '_')
283 {
284 return true;
285 }
286
287 !chars.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_')
288}
289
290#[cfg(feature = "sql")]
291pub(crate) fn parse_identifiers(s: &str) -> Result<Vec<Ident>> {
292 let dialect = GenericDialect;
293 let mut parser = Parser::new(&dialect).try_with_sql(s)?;
294 let idents = parser.parse_multipart_identifier()?;
295 Ok(idents)
296}
297
298#[cfg(feature = "sql")]
302pub(crate) fn parse_identifiers_normalized(s: &str, ignore_case: bool) -> Vec<String> {
303 parse_identifiers(s)
304 .unwrap_or_default()
305 .into_iter()
306 .map(|id| match id.quote_style {
307 Some(_) => id.value,
308 None if ignore_case => id.value,
309 _ => id.value.to_ascii_lowercase(),
310 })
311 .collect::<Vec<_>>()
312}
313
314#[cfg(not(feature = "sql"))]
315pub(crate) fn parse_identifiers(s: &str) -> Result<Vec<String>> {
316 let mut result = Vec::new();
317 let mut current = String::new();
318 let mut in_quotes = false;
319
320 for ch in s.chars() {
321 match ch {
322 '"' => {
323 in_quotes = !in_quotes;
324 current.push(ch);
325 }
326 '.' if !in_quotes => {
327 result.push(current.clone());
328 current.clear();
329 }
330 _ => {
331 current.push(ch);
332 }
333 }
334 }
335
336 if !current.is_empty() {
338 result.push(current);
339 }
340
341 Ok(result)
342}
343
344#[cfg(not(feature = "sql"))]
345pub(crate) fn parse_identifiers_normalized(s: &str, ignore_case: bool) -> Vec<String> {
346 parse_identifiers(s)
347 .unwrap_or_default()
348 .into_iter()
349 .map(|id| {
350 let is_double_quoted = if id.len() > 2 {
351 let mut chars = id.chars();
352 chars.next() == Some('"') && chars.last() == Some('"')
353 } else {
354 false
355 };
356 if is_double_quoted {
357 id[1..id.len() - 1].to_string().replace("\"\"", "\"")
358 } else if ignore_case {
359 id
360 } else {
361 id.to_ascii_lowercase()
362 }
363 })
364 .collect::<Vec<_>>()
365}
366
367pub fn get_at_indices<T: Clone, I: Borrow<usize>>(
369 items: &[T],
370 indices: impl IntoIterator<Item = I>,
371) -> Result<Vec<T>> {
372 indices
373 .into_iter()
374 .map(|idx| items.get(*idx.borrow()).cloned())
375 .collect::<Option<Vec<T>>>()
376 .ok_or_else(|| {
377 _exec_datafusion_err!("Expects indices to be in the range of searched vector")
378 })
379}
380
381pub fn longest_consecutive_prefix<T: Borrow<usize>>(
387 sequence: impl IntoIterator<Item = T>,
388) -> usize {
389 let mut count = 0;
390 for item in sequence {
391 if !count.eq(item.borrow()) {
392 break;
393 }
394 count += 1;
395 }
396 count
397}
398
399pub fn split_vec_min_alloc<T>(vec: &mut Vec<T>, n: usize) -> Vec<T> {
407 if n * 2 <= vec.len() {
408 vec.drain(0..n).collect()
409 } else {
410 let remaining = vec.split_off(n);
411 std::mem::replace(vec, remaining)
412 }
413}
414
415#[cfg(test)]
416mod split_vec_min_alloc_tests {
417 use super::split_vec_min_alloc;
418
419 #[test]
420 fn drain_branch() {
421 let mut v = vec![1, 2, 3, 4, 5, 6];
423 let first = split_vec_min_alloc(&mut v, 2);
424 assert_eq!(first, vec![1, 2]);
425 assert_eq!(v, vec![3, 4, 5, 6]);
426 }
427
428 #[test]
429 fn split_off_branch() {
430 let mut v = vec![1, 2, 3, 4, 5, 6];
432 let first = split_vec_min_alloc(&mut v, 4);
433 assert_eq!(first, vec![1, 2, 3, 4]);
434 assert_eq!(v, vec![5, 6]);
435 }
436
437 #[test]
438 fn exactly_half() {
439 let mut v = vec![1, 2, 3, 4];
441 let first = split_vec_min_alloc(&mut v, 2);
442 assert_eq!(first, vec![1, 2]);
443 assert_eq!(v, vec![3, 4]);
444 }
445
446 #[test]
447 fn take_all() {
448 let mut v = vec![1, 2, 3];
449 let first = split_vec_min_alloc(&mut v, 3);
450 assert_eq!(first, vec![1, 2, 3]);
451 assert!(v.is_empty());
452 }
453
454 #[test]
455 fn take_none() {
456 let mut v = vec![1, 2, 3];
457 let first = split_vec_min_alloc(&mut v, 0);
458 assert!(first.is_empty());
459 assert_eq!(v, vec![1, 2, 3]);
460 }
461
462 #[test]
463 fn emitted_prefix_does_not_realloc_on_push() {
464 let mut v: Vec<u32> = Vec::with_capacity(64);
480 v.extend(0..10);
481 let original_capacity = v.capacity();
482 assert!(original_capacity >= 64);
483
484 let mut prefix = split_vec_min_alloc(&mut v, 8);
486 assert_eq!(prefix, vec![0, 1, 2, 3, 4, 5, 6, 7]);
487
488 assert_eq!(
491 prefix.capacity(),
492 original_capacity,
493 "split-off branch must hand the original allocation to the prefix"
494 );
495
496 prefix.push(99);
498
499 assert_eq!(
503 prefix.capacity(),
504 original_capacity,
505 "push must reuse the preserved allocation (no realloc)"
506 );
507 assert!(prefix.capacity() <= original_capacity);
508
509 let mut shrunk: Vec<u32> = prefix[..8].to_vec();
514 shrunk.shrink_to_fit();
515 let shrunk_capacity = shrink_then_push_capacity(&mut shrunk);
516 assert!(
517 shrunk_capacity > 8,
518 "shrink-to-fit then push reallocates to a larger capacity"
519 );
520 }
521
522 fn shrink_then_push_capacity(v: &mut Vec<u32>) -> usize {
525 v.push(99);
526 v.capacity()
527 }
528}
529
530#[derive(Debug, Clone)]
552pub struct SingleRowListArrayBuilder {
553 arr: ArrayRef,
555 nullable: bool,
557 field_name: Option<String>,
560}
561
562impl SingleRowListArrayBuilder {
563 pub fn new(arr: ArrayRef) -> Self {
565 Self {
566 arr,
567 nullable: true,
568 field_name: None,
569 }
570 }
571
572 pub fn with_nullable(mut self, nullable: bool) -> Self {
574 self.nullable = nullable;
575 self
576 }
577
578 pub fn with_field_name(mut self, field_name: Option<String>) -> Self {
580 self.field_name = field_name;
581 self
582 }
583
584 pub fn with_field(self, field: &Field) -> Self {
586 self.with_field_name(Some(field.name().to_owned()))
587 .with_nullable(field.is_nullable())
588 }
589
590 pub fn build_list_array(self) -> ListArray {
592 let (field, arr) = self.into_field_and_arr();
593 let offsets = OffsetBuffer::from_lengths([arr.len()]);
594 ListArray::new(field, offsets, arr, None)
595 }
596
597 pub fn build_list_scalar(self) -> ScalarValue {
599 ScalarValue::List(Arc::new(self.build_list_array()))
600 }
601
602 pub fn build_large_list_array(self) -> LargeListArray {
604 let (field, arr) = self.into_field_and_arr();
605 let offsets = OffsetBuffer::from_lengths([arr.len()]);
606 LargeListArray::new(field, offsets, arr, None)
607 }
608
609 pub fn build_large_list_scalar(self) -> ScalarValue {
611 ScalarValue::LargeList(Arc::new(self.build_large_list_array()))
612 }
613
614 pub fn build_fixed_size_list_array(self, list_size: usize) -> FixedSizeListArray {
616 let (field, arr) = self.into_field_and_arr();
617 FixedSizeListArray::try_new_with_length(field, list_size as i32, arr, None, 1)
618 .unwrap()
619 }
620
621 pub fn build_fixed_size_list_scalar(self, list_size: usize) -> ScalarValue {
623 ScalarValue::FixedSizeList(Arc::new(self.build_fixed_size_list_array(list_size)))
624 }
625
626 pub fn build_list_view_array(self) -> ListViewArray {
628 let (field, arr) = self.into_field_and_arr();
629 let offsets = ScalarBuffer::from(vec![0]);
630 let sizes = ScalarBuffer::from(vec![i32::try_from(arr.len()).expect(
631 "Trying to construct a ListView where element length exceeds i32::MAX",
632 )]);
633 ListViewArray::new(field, offsets, sizes, arr, None)
634 }
635
636 pub fn build_list_view_scalar(self) -> ScalarValue {
638 ScalarValue::ListView(Arc::new(self.build_list_view_array()))
639 }
640
641 pub fn build_large_list_view_array(self) -> LargeListViewArray {
643 let (field, arr) = self.into_field_and_arr();
644 let offsets = ScalarBuffer::from(vec![0]);
645 let sizes = ScalarBuffer::from(vec![arr.len() as i64]);
646 LargeListViewArray::new(field, offsets, sizes, arr, None)
647 }
648
649 pub fn build_large_list_view_scalar(self) -> ScalarValue {
651 ScalarValue::LargeListView(Arc::new(self.build_large_list_view_array()))
652 }
653
654 fn into_field_and_arr(self) -> (Arc<Field>, ArrayRef) {
656 let Self {
657 arr,
658 nullable,
659 field_name,
660 } = self;
661 let data_type = arr.data_type().to_owned();
662 let field = match field_name {
663 Some(name) => Field::new(name, data_type, nullable),
664 None => Field::new_list_field(data_type, nullable),
665 };
666 (Arc::new(field), arr)
667 }
668}
669
670pub fn arrays_into_list_array(
693 arr: impl IntoIterator<Item = ArrayRef>,
694) -> Result<ListArray> {
695 let arr = arr.into_iter().collect::<Vec<_>>();
696 assert_or_internal_err!(!arr.is_empty(), "Cannot wrap empty array into list array");
697
698 let lens = arr.iter().map(|x| x.len()).collect::<Vec<_>>();
699 let data_type = arr[0].data_type().to_owned();
701 let values = arr.iter().map(|x| x.as_ref()).collect::<Vec<_>>();
702 Ok(ListArray::new(
703 Arc::new(Field::new_list_field(data_type, true)),
704 OffsetBuffer::from_lengths(lens),
705 arrow::compute::concat(values.as_slice())?,
706 None,
707 ))
708}
709
710pub fn list_to_arrays<O: OffsetSizeTrait>(a: &ArrayRef) -> Vec<ArrayRef> {
712 a.as_list::<O>().iter().flatten().collect::<Vec<_>>()
713}
714
715pub fn fixed_size_list_to_arrays(a: &ArrayRef) -> Vec<ArrayRef> {
717 a.as_fixed_size_list().iter().flatten().collect::<Vec<_>>()
718}
719
720pub fn base_type(data_type: &DataType) -> DataType {
736 match data_type {
737 DataType::List(field)
738 | DataType::LargeList(field)
739 | DataType::ListView(field)
740 | DataType::LargeListView(field)
741 | DataType::FixedSizeList(field, _) => base_type(field.data_type()),
742 _ => data_type.to_owned(),
743 }
744}
745
746#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
752pub enum ListCoercion {
753 FixedSizedListToList,
755}
756
757pub fn coerced_type_with_base_type_only(
771 data_type: &DataType,
772 base_type: &DataType,
773 array_coercion: Option<&ListCoercion>,
774) -> DataType {
775 match (data_type, array_coercion) {
776 (DataType::List(field), _)
777 | (DataType::FixedSizeList(field, _), Some(ListCoercion::FixedSizedListToList)) =>
778 {
779 let field_type = coerced_type_with_base_type_only(
780 field.data_type(),
781 base_type,
782 array_coercion,
783 );
784
785 DataType::List(Arc::new(Field::new(
786 field.name(),
787 field_type,
788 field.is_nullable(),
789 )))
790 }
791 (DataType::FixedSizeList(field, len), _) => {
792 let field_type = coerced_type_with_base_type_only(
793 field.data_type(),
794 base_type,
795 array_coercion,
796 );
797
798 DataType::FixedSizeList(
799 Arc::new(Field::new(field.name(), field_type, field.is_nullable())),
800 *len,
801 )
802 }
803 (DataType::ListView(field), _) => {
804 let field_type = coerced_type_with_base_type_only(
805 field.data_type(),
806 base_type,
807 array_coercion,
808 );
809
810 DataType::ListView(Arc::new(Field::new(
811 field.name(),
812 field_type,
813 field.is_nullable(),
814 )))
815 }
816 (DataType::LargeList(field), _) => {
817 let field_type = coerced_type_with_base_type_only(
818 field.data_type(),
819 base_type,
820 array_coercion,
821 );
822
823 DataType::LargeList(Arc::new(Field::new(
824 field.name(),
825 field_type,
826 field.is_nullable(),
827 )))
828 }
829 (DataType::LargeListView(field), _) => {
830 let field_type = coerced_type_with_base_type_only(
831 field.data_type(),
832 base_type,
833 array_coercion,
834 );
835
836 DataType::LargeListView(Arc::new(Field::new(
837 field.name(),
838 field_type,
839 field.is_nullable(),
840 )))
841 }
842
843 _ => base_type.clone(),
844 }
845}
846
847pub fn coerced_fixed_size_list_to_list(data_type: &DataType) -> DataType {
849 match data_type {
850 DataType::List(field) | DataType::FixedSizeList(field, _) => {
851 let field_type = coerced_fixed_size_list_to_list(field.data_type());
852
853 DataType::List(Arc::new(Field::new(
854 field.name(),
855 field_type,
856 field.is_nullable(),
857 )))
858 }
859 DataType::ListView(field) => {
860 let field_type = coerced_fixed_size_list_to_list(field.data_type());
861
862 DataType::ListView(Arc::new(Field::new(
863 field.name(),
864 field_type,
865 field.is_nullable(),
866 )))
867 }
868 DataType::LargeList(field) => {
869 let field_type = coerced_fixed_size_list_to_list(field.data_type());
870
871 DataType::LargeList(Arc::new(Field::new(
872 field.name(),
873 field_type,
874 field.is_nullable(),
875 )))
876 }
877 DataType::LargeListView(field) => {
878 let field_type = coerced_fixed_size_list_to_list(field.data_type());
879
880 DataType::LargeListView(Arc::new(Field::new(
881 field.name(),
882 field_type,
883 field.is_nullable(),
884 )))
885 }
886
887 _ => data_type.clone(),
888 }
889}
890
891pub fn list_ndims(data_type: &DataType) -> u64 {
893 match data_type {
894 DataType::List(field)
895 | DataType::LargeList(field)
896 | DataType::ListView(field)
897 | DataType::LargeListView(field)
898 | DataType::FixedSizeList(field, _) => 1 + list_ndims(field.data_type()),
899 _ => 0,
900 }
901}
902
903pub mod datafusion_strsim {
905 use std::cmp::min;
908 use std::str::Chars;
909
910 struct StringWrapper<'a>(&'a str);
911
912 impl<'b> IntoIterator for &StringWrapper<'b> {
913 type Item = char;
914 type IntoIter = Chars<'b>;
915
916 fn into_iter(self) -> Self::IntoIter {
917 self.0.chars()
918 }
919 }
920
921 fn generic_levenshtein_with_buffer<'a, 'b, Iter1, Iter2, Elem1, Elem2>(
927 a: &'a Iter1,
928 b: &'b Iter2,
929 cache: &mut Vec<usize>,
930 ) -> usize
931 where
932 &'a Iter1: IntoIterator<Item = Elem1>,
933 &'b Iter2: IntoIterator<Item = Elem2>,
934 Elem1: PartialEq<Elem2>,
935 {
936 let b_len = b.into_iter().count();
937
938 if a.into_iter().next().is_none() {
939 return b_len;
940 }
941
942 cache.clear();
944 cache.extend(1..=b_len);
945
946 let mut result = 0;
947
948 for (i, a_elem) in a.into_iter().enumerate() {
949 result = i + 1;
950 let mut distance_b = i;
951
952 for (j, b_elem) in b.into_iter().enumerate() {
953 let cost = if a_elem == b_elem { 0usize } else { 1usize };
954 let distance_a = distance_b + cost;
955 distance_b = cache[j];
956 result = min(result + 1, min(distance_a, distance_b + 1));
957 cache[j] = result;
958 }
959 }
960
961 result
962 }
963
964 fn generic_levenshtein<'a, 'b, Iter1, Iter2, Elem1, Elem2>(
967 a: &'a Iter1,
968 b: &'b Iter2,
969 ) -> usize
970 where
971 &'a Iter1: IntoIterator<Item = Elem1>,
972 &'b Iter2: IntoIterator<Item = Elem2>,
973 Elem1: PartialEq<Elem2>,
974 {
975 let mut cache = Vec::new();
976 generic_levenshtein_with_buffer(a, b, &mut cache)
977 }
978
979 pub fn levenshtein(a: &str, b: &str) -> usize {
988 generic_levenshtein(&StringWrapper(a), &StringWrapper(b))
989 }
990
991 pub fn levenshtein_with_buffer(a: &str, b: &str, cache: &mut Vec<usize>) -> usize {
997 generic_levenshtein_with_buffer(&StringWrapper(a), &StringWrapper(b), cache)
998 }
999
1000 pub fn normalized_levenshtein(a: &str, b: &str) -> f64 {
1014 if a.is_empty() && b.is_empty() {
1015 return 1.0;
1016 }
1017 1.0 - (levenshtein(a, b) as f64)
1018 / (a.chars().count().max(b.chars().count()) as f64)
1019 }
1020}
1021
1022pub fn merge_and_order_indices<T: Borrow<usize>, S: Borrow<usize>>(
1025 first: impl IntoIterator<Item = T>,
1026 second: impl IntoIterator<Item = S>,
1027) -> Vec<usize> {
1028 let mut result: Vec<_> = first
1029 .into_iter()
1030 .map(|e| *e.borrow())
1031 .chain(second.into_iter().map(|e| *e.borrow()))
1032 .collect::<HashSet<_>>()
1033 .into_iter()
1034 .collect();
1035 result.sort();
1036 result
1037}
1038
1039pub fn set_difference<T: Borrow<usize>, S: Borrow<usize>>(
1042 first: impl IntoIterator<Item = T>,
1043 second: impl IntoIterator<Item = S>,
1044) -> Vec<usize> {
1045 let set: HashSet<_> = second.into_iter().map(|e| *e.borrow()).collect();
1046 first
1047 .into_iter()
1048 .map(|e| *e.borrow())
1049 .filter(|e| !set.contains(e))
1050 .collect()
1051}
1052
1053pub fn find_indices<T: PartialEq, S: Borrow<T>>(
1056 items: &[T],
1057 targets: impl IntoIterator<Item = S>,
1058) -> Result<Vec<usize>> {
1059 targets
1060 .into_iter()
1061 .map(|target| items.iter().position(|e| target.borrow().eq(e)))
1062 .collect::<Option<_>>()
1063 .ok_or_else(|| _exec_datafusion_err!("Target not found"))
1064}
1065
1066pub fn transpose<T>(original: Vec<Vec<T>>) -> Vec<Vec<T>> {
1068 match original.as_slice() {
1069 [] => vec![],
1070 [first, ..] => {
1071 let mut result = (0..first.len()).map(|_| vec![]).collect::<Vec<_>>();
1072 for row in original {
1073 for (item, transposed_row) in row.into_iter().zip(&mut result) {
1074 transposed_row.push(item);
1075 }
1076 }
1077 result
1078 }
1079 }
1080}
1081
1082pub fn combine_limit(
1126 parent_skip: usize,
1127 parent_fetch: Option<usize>,
1128 child_skip: usize,
1129 child_fetch: Option<usize>,
1130) -> (usize, Option<usize>) {
1131 let combined_skip = child_skip.saturating_add(parent_skip);
1132
1133 let combined_fetch = match (parent_fetch, child_fetch) {
1134 (Some(parent_fetch), Some(child_fetch)) => {
1135 Some(min(parent_fetch, child_fetch.saturating_sub(parent_skip)))
1136 }
1137 (Some(parent_fetch), None) => Some(parent_fetch),
1138 (None, Some(child_fetch)) => Some(child_fetch.saturating_sub(parent_skip)),
1139 (None, None) => None,
1140 };
1141
1142 (combined_skip, combined_fetch)
1143}
1144
1145pub fn get_available_parallelism() -> usize {
1152 static PARALLELISM: LazyLock<usize> = LazyLock::new(|| {
1153 available_parallelism()
1154 .unwrap_or(NonZero::new(1).expect("literal value `1` shouldn't be zero"))
1155 .get()
1156 });
1157 *PARALLELISM
1158}
1159
1160pub fn take_function_args<const N: usize, T>(
1187 function_name: &str,
1188 args: impl IntoIterator<Item = T>,
1189) -> Result<[T; N]> {
1190 let args = args.into_iter().collect::<Vec<_>>();
1191 args.try_into().map_err(|v: Vec<T>| {
1192 _exec_datafusion_err!(
1193 "{} function requires {} {}, got {}",
1194 function_name,
1195 N,
1196 if N == 1 { "argument" } else { "arguments" },
1197 v.len()
1198 )
1199 })
1200}
1201
1202pub fn list_values(array: &dyn Array) -> Result<ArrayRef> {
1207 match array.data_type() {
1208 DataType::List(_) => Ok(sliced_list_values(array.as_list::<i32>())),
1209 DataType::LargeList(_) => Ok(sliced_list_values(array.as_list::<i64>())),
1210 DataType::FixedSizeList(_, _) => {
1211 Ok(Arc::clone(array.as_fixed_size_list().values()))
1212 }
1213 other => _exec_err!("expected list, got {other}"),
1214 }
1215}
1216
1217fn sliced_list_values<O: OffsetSizeTrait>(list: &GenericListArray<O>) -> ArrayRef {
1218 let values = list.values();
1219 let offsets = list.offsets();
1220
1221 if let (Some(first), Some(last)) = (offsets.first(), offsets.last()) {
1222 let first = first.as_usize();
1223 let last = last.as_usize();
1224
1225 if first != 0 || last != values.len() {
1226 return values.slice(first, last - first);
1227 }
1228 }
1229
1230 Arc::clone(values)
1231}
1232
1233pub fn adjust_offsets_for_slice<O: OffsetSizeTrait>(
1236 list: &GenericListArray<O>,
1237) -> OffsetBuffer<O> {
1238 let offsets = list.offsets();
1239
1240 offsets.clone().subtract(offsets[0])
1241}
1242
1243pub fn remove_list_null_values(array: &ArrayRef) -> Result<ArrayRef> {
1246 match array.data_type() {
1248 DataType::List(_) => Ok(Arc::new(truncate_list_nulls(array.as_list::<i32>())?)),
1249 DataType::LargeList(_) => {
1250 Ok(Arc::new(truncate_list_nulls(array.as_list::<i64>())?))
1251 }
1252 dt => _exec_err!("expected List or LargeList, got {dt}"),
1253 }
1254}
1255
1256fn truncate_list_nulls<O: OffsetSizeTrait>(
1258 list: &GenericListArray<O>,
1259) -> Result<GenericListArray<O>> {
1260 if let Some(nulls) = list.nulls()
1261 && nulls.null_count() > 0
1262 {
1263 let lengths = length(list)?;
1264 let zero: &dyn Datum = if lengths.data_type() == &DataType::Int32 {
1265 &Int32Array::new_scalar(0)
1266 } else {
1267 &Int64Array::new_scalar(0)
1268 };
1269
1270 let (mut valid_or_empty, _nulls) = eq(&lengths, zero)?.into_parts();
1271 valid_or_empty |= nulls.inner();
1272 let valid_or_empty = BooleanArray::from(valid_or_empty);
1273
1274 if valid_or_empty.has_false() {
1275 let array_data = list.values().to_data();
1276 let offsets = list.offsets();
1277 let capacity = offsets[offsets.len() - 1] - offsets[0];
1278 let mut mutable_array_data =
1279 MutableArrayData::new(vec![&array_data], false, capacity.as_usize());
1280
1281 let (valid_or_empty, _nulls) = valid_or_empty.into_parts();
1282
1283 for (start, end) in valid_or_empty.set_slices() {
1284 mutable_array_data.try_extend(
1285 0,
1286 offsets[start].as_usize(),
1287 offsets[end].as_usize(),
1288 )?;
1289 }
1290
1291 let lengths = std::iter::zip(offsets.lengths(), nulls)
1292 .map(|(length, is_valid)| if is_valid { length } else { 0 });
1293
1294 let offsets = OffsetBuffer::from_lengths(lengths);
1295 let values = make_array(mutable_array_data.freeze());
1296
1297 let field = match list.data_type() {
1298 DataType::List(field) => field,
1299 DataType::LargeList(field) => field,
1300 _ => unreachable!(),
1301 };
1302
1303 return Ok(GenericListArray::try_new(
1304 Arc::clone(field),
1305 offsets,
1306 values,
1307 list.nulls().cloned(),
1308 )?);
1309 }
1310 }
1311 Ok(list.clone())
1312}
1313
1314pub fn list_values_row_number(array: &dyn Array) -> Result<ArrayRef> {
1321 match array.data_type() {
1322 DataType::List(_) => Ok(Arc::new(variable_size_list_values_row_number::<
1323 Int32Type,
1324 >(array.as_list().offsets()))),
1325 DataType::LargeList(_) => Ok(Arc::new(variable_size_list_values_row_number::<
1326 Int64Type,
1327 >(array.as_list().offsets()))),
1328 DataType::ListView(_) => Ok(Arc::new(variable_size_list_values_row_number::<
1329 Int32Type,
1330 >(array.as_list_view().offsets()))),
1331 DataType::LargeListView(_) => {
1332 Ok(Arc::new(variable_size_list_values_row_number::<Int64Type>(
1333 array.as_list_view().offsets(),
1334 )))
1335 }
1336 DataType::FixedSizeList(_, _) => {
1337 let fixed_size_list = array.as_fixed_size_list();
1338
1339 Ok(Arc::new(fsl_values_row_number(
1340 fixed_size_list.value_length(),
1341 fixed_size_list.len(),
1342 )?))
1343 }
1344 DataType::Map(_, _) => Ok(Arc::new(variable_size_list_values_row_number::<
1345 Int32Type,
1346 >(array.as_map().offsets()))),
1347 other => _exec_err!("expected list, got {other}"),
1348 }
1349}
1350
1351fn variable_size_list_values_row_number<T: ArrowPrimitiveType>(
1353 offsets: &[T::Native],
1354) -> PrimitiveArray<T> {
1355 let mut rows_number = Vec::with_capacity(
1356 offsets[offsets.len() - 1].to_usize().unwrap() - offsets[0].to_usize().unwrap(),
1357 );
1358
1359 for (i, w) in offsets.windows(2).enumerate() {
1360 let len = w[1].as_usize() - w[0].as_usize();
1361 rows_number.extend(repeat_n(T::Native::usize_as(i), len));
1362 }
1363
1364 PrimitiveArray::new(rows_number.into(), None)
1365}
1366
1367fn fsl_values_row_number(list_size: i32, array_len: usize) -> Result<Int32Array> {
1369 let list_size = list_size.to_usize().ok_or_else(|| {
1370 _exec_datafusion_err!("fsl_values_index: invalid list_size {list_size}")
1371 })?;
1372
1373 let mut rows_number = Vec::with_capacity(list_size * array_len);
1374
1375 for i in 0..array_len {
1376 rows_number.extend(repeat_n(i as i32, list_size));
1377 }
1378
1379 Ok(PrimitiveArray::new(rows_number.into(), None))
1380}
1381
1382pub fn normalize_float_zero(array: &ArrayRef) -> ArrayRef {
1397 use arrow::array::{Float16Array, Float32Array, Float64Array};
1398 use arrow::datatypes::{Float16Type, Float32Type, Float64Type};
1399 const NEG_ZERO_F16_BITS: u16 = half::f16::NEG_ZERO.to_bits();
1402 const NEG_ZERO_F32_BITS: u32 = (-0.0_f32).to_bits();
1403 const NEG_ZERO_F64_BITS: u64 = (-0.0_f64).to_bits();
1404 match array.data_type() {
1405 DataType::Float32 => {
1406 let arr: &Float32Array = array.as_primitive::<Float32Type>();
1407 if !arr
1408 .values()
1409 .iter()
1410 .any(|v| v.to_bits() == NEG_ZERO_F32_BITS)
1411 {
1412 return Arc::clone(array);
1413 }
1414 let normalized: Float32Array =
1415 arr.unary(|v| if v.to_bits() << 1 == 0 { 0.0_f32 } else { v });
1416 Arc::new(normalized)
1417 }
1418 DataType::Float64 => {
1419 let arr: &Float64Array = array.as_primitive::<Float64Type>();
1420 if !arr
1421 .values()
1422 .iter()
1423 .any(|v| v.to_bits() == NEG_ZERO_F64_BITS)
1424 {
1425 return Arc::clone(array);
1426 }
1427 let normalized: Float64Array =
1428 arr.unary(|v| if v.to_bits() << 1 == 0 { 0.0_f64 } else { v });
1429 Arc::new(normalized)
1430 }
1431 DataType::Float16 => {
1432 let arr: &Float16Array = array.as_primitive::<Float16Type>();
1433 if !arr
1434 .values()
1435 .iter()
1436 .any(|v| v.to_bits() == NEG_ZERO_F16_BITS)
1437 {
1438 return Arc::clone(array);
1439 }
1440 let normalized: Float16Array = arr.unary(|v| {
1441 if v.to_bits() << 1 == 0 {
1442 half::f16::from_bits(0)
1443 } else {
1444 v
1445 }
1446 });
1447 Arc::new(normalized)
1448 }
1449 _ => Arc::clone(array),
1450 }
1451}
1452
1453pub fn normalize_float_zero_scalar(scalar: ScalarValue) -> ScalarValue {
1457 match scalar {
1458 ScalarValue::Float32(Some(v)) if v.to_bits() << 1 == 0 => {
1459 ScalarValue::Float32(Some(0.0))
1460 }
1461 ScalarValue::Float64(Some(v)) if v.to_bits() << 1 == 0 => {
1462 ScalarValue::Float64(Some(0.0))
1463 }
1464 ScalarValue::Float16(Some(v)) if v.to_bits() << 1 == 0 => {
1465 ScalarValue::Float16(Some(half::f16::from_bits(0)))
1466 }
1467 other => other,
1468 }
1469}
1470
1471#[cfg(test)]
1472mod tests {
1473 use std::sync::Arc;
1474
1475 use super::*;
1476 use crate::ScalarValue::Null;
1477 use arrow::{
1478 array::{Float64Array, Int32Array},
1479 buffer::NullBuffer,
1480 datatypes::Int32Type,
1481 };
1482 #[cfg(feature = "sql")]
1483 use sqlparser::ast::Ident;
1484
1485 #[test]
1486 fn test_bisect_linear_left_and_right() -> Result<()> {
1487 let arrays: Vec<ArrayRef> = vec![
1488 Arc::new(Float64Array::from(vec![5.0, 7.0, 8.0, 9., 10.])),
1489 Arc::new(Float64Array::from(vec![2.0, 3.0, 3.0, 4.0, 5.0])),
1490 Arc::new(Float64Array::from(vec![5.0, 7.0, 8.0, 10., 11.0])),
1491 Arc::new(Float64Array::from(vec![15.0, 13.0, 8.0, 5., 0.0])),
1492 ];
1493 let search_tuple: Vec<ScalarValue> = vec![
1494 ScalarValue::Float64(Some(8.0)),
1495 ScalarValue::Float64(Some(3.0)),
1496 ScalarValue::Float64(Some(8.0)),
1497 ScalarValue::Float64(Some(8.0)),
1498 ];
1499 let ords = [
1500 SortOptions {
1501 descending: false,
1502 nulls_first: true,
1503 },
1504 SortOptions {
1505 descending: false,
1506 nulls_first: true,
1507 },
1508 SortOptions {
1509 descending: false,
1510 nulls_first: true,
1511 },
1512 SortOptions {
1513 descending: true,
1514 nulls_first: true,
1515 },
1516 ];
1517 let res = bisect::<true>(&arrays, &search_tuple, &ords)?;
1518 assert_eq!(res, 2);
1519 let res = bisect::<false>(&arrays, &search_tuple, &ords)?;
1520 assert_eq!(res, 3);
1521 let res = linear_search::<true>(&arrays, &search_tuple, &ords)?;
1522 assert_eq!(res, 2);
1523 let res = linear_search::<false>(&arrays, &search_tuple, &ords)?;
1524 assert_eq!(res, 3);
1525 Ok(())
1526 }
1527
1528 #[test]
1529 fn vector_ord() {
1530 assert!(vec![1, 0, 0, 0, 0, 0, 0, 1] < vec![1, 0, 0, 0, 0, 0, 0, 2]);
1531 assert!(vec![1, 0, 0, 0, 0, 0, 1, 1] > vec![1, 0, 0, 0, 0, 0, 0, 2]);
1532 assert!(
1533 vec![
1534 ScalarValue::Int32(Some(2)),
1535 Null,
1536 ScalarValue::Int32(Some(0)),
1537 ] < vec![
1538 ScalarValue::Int32(Some(2)),
1539 Null,
1540 ScalarValue::Int32(Some(1)),
1541 ]
1542 );
1543 assert!(
1544 vec![
1545 ScalarValue::Int32(Some(2)),
1546 ScalarValue::Int32(None),
1547 ScalarValue::Int32(Some(0)),
1548 ] < vec![
1549 ScalarValue::Int32(Some(2)),
1550 ScalarValue::Int32(None),
1551 ScalarValue::Int32(Some(1)),
1552 ]
1553 );
1554 }
1555
1556 #[test]
1557 fn ord_same_type() {
1558 assert!((ScalarValue::Int32(Some(2)) < ScalarValue::Int32(Some(3))));
1559 }
1560
1561 #[test]
1562 fn test_bisect_linear_left_and_right_diff_sort() -> Result<()> {
1563 let arrays: Vec<ArrayRef> =
1565 vec![Arc::new(Float64Array::from(vec![4.0, 3.0, 2.0, 1.0, 0.0]))];
1566 let search_tuple: Vec<ScalarValue> = vec![ScalarValue::Float64(Some(4.0))];
1567 let ords = [SortOptions {
1568 descending: true,
1569 nulls_first: true,
1570 }];
1571 let res = bisect::<true>(&arrays, &search_tuple, &ords)?;
1572 assert_eq!(res, 0);
1573 let res = linear_search::<true>(&arrays, &search_tuple, &ords)?;
1574 assert_eq!(res, 0);
1575
1576 let arrays: Vec<ArrayRef> =
1578 vec![Arc::new(Float64Array::from(vec![4.0, 3.0, 2.0, 1.0, 0.0]))];
1579 let search_tuple: Vec<ScalarValue> = vec![ScalarValue::Float64(Some(4.0))];
1580 let ords = [SortOptions {
1581 descending: true,
1582 nulls_first: true,
1583 }];
1584 let res = bisect::<false>(&arrays, &search_tuple, &ords)?;
1585 assert_eq!(res, 1);
1586 let res = linear_search::<false>(&arrays, &search_tuple, &ords)?;
1587 assert_eq!(res, 1);
1588
1589 let arrays: Vec<ArrayRef> =
1591 vec![Arc::new(Float64Array::from(vec![5.0, 7.0, 8.0, 9., 10.]))];
1592 let search_tuple: Vec<ScalarValue> = vec![ScalarValue::Float64(Some(7.0))];
1593 let ords = [SortOptions {
1594 descending: false,
1595 nulls_first: true,
1596 }];
1597 let res = bisect::<true>(&arrays, &search_tuple, &ords)?;
1598 assert_eq!(res, 1);
1599 let res = linear_search::<true>(&arrays, &search_tuple, &ords)?;
1600 assert_eq!(res, 1);
1601
1602 let arrays: Vec<ArrayRef> =
1604 vec![Arc::new(Float64Array::from(vec![5.0, 7.0, 8.0, 9., 10.]))];
1605 let search_tuple: Vec<ScalarValue> = vec![ScalarValue::Float64(Some(7.0))];
1606 let ords = [SortOptions {
1607 descending: false,
1608 nulls_first: true,
1609 }];
1610 let res = bisect::<false>(&arrays, &search_tuple, &ords)?;
1611 assert_eq!(res, 2);
1612 let res = linear_search::<false>(&arrays, &search_tuple, &ords)?;
1613 assert_eq!(res, 2);
1614
1615 let arrays: Vec<ArrayRef> = vec![
1616 Arc::new(Float64Array::from(vec![5.0, 7.0, 8.0, 8.0, 9., 10.])),
1617 Arc::new(Float64Array::from(vec![10.0, 9.0, 8.0, 7.5, 7., 6.])),
1618 ];
1619 let search_tuple: Vec<ScalarValue> = vec![
1620 ScalarValue::Float64(Some(8.0)),
1621 ScalarValue::Float64(Some(8.0)),
1622 ];
1623 let ords = [
1624 SortOptions {
1625 descending: false,
1626 nulls_first: true,
1627 },
1628 SortOptions {
1629 descending: true,
1630 nulls_first: true,
1631 },
1632 ];
1633 let res = bisect::<false>(&arrays, &search_tuple, &ords)?;
1634 assert_eq!(res, 3);
1635 let res = linear_search::<false>(&arrays, &search_tuple, &ords)?;
1636 assert_eq!(res, 3);
1637
1638 let res = bisect::<true>(&arrays, &search_tuple, &ords)?;
1639 assert_eq!(res, 2);
1640 let res = linear_search::<true>(&arrays, &search_tuple, &ords)?;
1641 assert_eq!(res, 2);
1642 Ok(())
1643 }
1644
1645 #[test]
1646 fn test_evaluate_partition_ranges() -> Result<()> {
1647 let arrays: Vec<ArrayRef> = vec![
1648 Arc::new(Float64Array::from(vec![1.0, 1.0, 1.0, 2.0, 2.0, 2.0])),
1649 Arc::new(Float64Array::from(vec![4.0, 4.0, 3.0, 2.0, 1.0, 1.0])),
1650 ];
1651 let n_row = arrays[0].len();
1652 let options: Vec<SortOptions> = vec![
1653 SortOptions {
1654 descending: false,
1655 nulls_first: false,
1656 },
1657 SortOptions {
1658 descending: true,
1659 nulls_first: false,
1660 },
1661 ];
1662 let sort_columns = arrays
1663 .into_iter()
1664 .zip(options)
1665 .map(|(values, options)| SortColumn {
1666 values,
1667 options: Some(options),
1668 })
1669 .collect::<Vec<_>>();
1670 let ranges = evaluate_partition_ranges(n_row, &sort_columns)?;
1671 assert_eq!(ranges.len(), 4);
1672 assert_eq!(ranges[0], Range { start: 0, end: 2 });
1673 assert_eq!(ranges[1], Range { start: 2, end: 3 });
1674 assert_eq!(ranges[2], Range { start: 3, end: 4 });
1675 assert_eq!(ranges[3], Range { start: 4, end: 6 });
1676 Ok(())
1677 }
1678
1679 #[cfg(feature = "sql")]
1680 #[test]
1681 fn test_quote_identifier() -> Result<()> {
1682 let cases = vec![
1683 ("foo", r#"foo"#),
1684 ("_foo", r#"_foo"#),
1685 ("foo_bar", r#"foo_bar"#),
1686 ("foo-bar", r#""foo-bar""#),
1687 ("foo.bar", r#""foo.bar""#),
1689 ("Foo", r#""Foo""#),
1690 ("Foo.Bar", r#""Foo.Bar""#),
1691 ("test1", r#"test1"#),
1693 ("1test", r#""1test""#),
1694 ];
1695
1696 for (identifier, quoted_identifier) in cases {
1697 println!("input: \n{identifier}\nquoted_identifier:\n{quoted_identifier}");
1698
1699 assert_eq!(quote_identifier(identifier), quoted_identifier);
1700
1701 let quote_style = if quoted_identifier.starts_with('"') {
1704 Some('"')
1705 } else {
1706 None
1707 };
1708
1709 let expected_parsed = vec![Ident {
1710 value: identifier.to_string(),
1711 quote_style,
1712 span: sqlparser::tokenizer::Span::empty(),
1713 }];
1714
1715 assert_eq!(
1716 parse_identifiers(quoted_identifier).unwrap(),
1717 expected_parsed
1718 );
1719 }
1720
1721 Ok(())
1722 }
1723
1724 #[test]
1725 fn test_get_at_indices() -> Result<()> {
1726 let in_vec = vec![1, 2, 3, 4, 5, 6, 7];
1727 assert_eq!(get_at_indices(&in_vec, [0, 2])?, vec![1, 3]);
1728 assert_eq!(get_at_indices(&in_vec, [4, 2])?, vec![5, 3]);
1729 assert!(get_at_indices(&in_vec, [7]).is_err());
1731 Ok(())
1732 }
1733
1734 #[test]
1735 fn test_longest_consecutive_prefix() {
1736 assert_eq!(longest_consecutive_prefix([0, 3, 4]), 1);
1737 assert_eq!(longest_consecutive_prefix([0, 1, 3, 4]), 2);
1738 assert_eq!(longest_consecutive_prefix([0, 1, 2, 3, 4]), 5);
1739 assert_eq!(longest_consecutive_prefix([1, 2, 3, 4]), 0);
1740 }
1741
1742 #[test]
1743 fn test_merge_and_order_indices() {
1744 assert_eq!(
1745 merge_and_order_indices([0, 3, 4], [1, 3, 5]),
1746 vec![0, 1, 3, 4, 5]
1747 );
1748 assert_eq!(
1750 merge_and_order_indices([3, 0, 4], [5, 1, 3]),
1751 vec![0, 1, 3, 4, 5]
1752 );
1753 }
1754
1755 #[test]
1756 fn test_set_difference() {
1757 assert_eq!(set_difference([0, 3, 4], [1, 2]), vec![0, 3, 4]);
1758 assert_eq!(set_difference([0, 3, 4], [1, 2, 4]), vec![0, 3]);
1759 assert_eq!(set_difference([3, 4, 0], [1, 2, 4]), vec![3, 0]);
1761 assert_eq!(set_difference([0, 3, 4], [4, 1, 2]), vec![0, 3]);
1762 assert_eq!(set_difference([3, 4, 0], [4, 1, 2]), vec![3, 0]);
1763 }
1764
1765 #[test]
1766 fn test_find_indices() -> Result<()> {
1767 assert_eq!(find_indices(&[0, 3, 4], [0, 3, 4])?, vec![0, 1, 2]);
1768 assert_eq!(find_indices(&[0, 3, 4], [0, 4, 3])?, vec![0, 2, 1]);
1769 assert_eq!(find_indices(&[3, 0, 4], [0, 3])?, vec![1, 0]);
1770 assert!(find_indices(&[0, 3], [0, 3, 4]).is_err());
1771 assert!(find_indices(&[0, 3, 4], [0, 2]).is_err());
1772 Ok(())
1773 }
1774
1775 #[test]
1776 fn test_transpose() -> Result<()> {
1777 let in_data = vec![vec![1, 2, 3], vec![4, 5, 6]];
1778 let transposed = transpose(in_data);
1779 let expected = vec![vec![1, 4], vec![2, 5], vec![3, 6]];
1780 assert_eq!(expected, transposed);
1781 Ok(())
1782 }
1783
1784 #[test]
1785 fn test_sliced_list_values() {
1786 let data = vec![
1787 Some(vec![Some(0), Some(1), Some(2)]),
1788 None,
1789 Some(vec![Some(3), None, Some(5)]),
1790 Some(vec![Some(6), Some(7)]),
1791 ];
1792
1793 let list = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1794
1795 assert_eq!(
1796 sliced_list_values(&list).as_primitive(),
1797 &Int32Array::from(vec![
1798 Some(0),
1799 Some(1),
1800 Some(2),
1801 Some(3),
1802 None,
1803 Some(5),
1804 Some(6),
1805 Some(7)
1806 ])
1807 );
1808
1809 assert_eq!(
1810 sliced_list_values(&list.slice(0, 1)).as_primitive(),
1811 &Int32Array::from(vec![Some(0), Some(1), Some(2)])
1812 );
1813
1814 assert_eq!(
1815 sliced_list_values(&list.slice(2, 1)).as_primitive(),
1816 &Int32Array::from(vec![Some(3), None, Some(5)])
1817 );
1818
1819 assert_eq!(
1820 sliced_list_values(&list.slice(3, 1)).as_primitive(),
1821 &Int32Array::from(vec![Some(6), Some(7)])
1822 );
1823
1824 assert!(sliced_list_values(&list.slice(0, 0)).is_empty());
1825 assert!(sliced_list_values(&list.slice(1, 0)).is_empty());
1826 assert!(sliced_list_values(&list.slice(3, 0)).is_empty());
1827 }
1828
1829 #[test]
1830 fn test_adjust_offsets() {
1831 let data = vec![
1832 Some(vec![Some(0), Some(1), Some(2)]),
1833 None,
1834 Some(vec![Some(3), None, Some(5)]),
1835 Some(vec![Some(6), Some(7)]),
1836 ];
1837 let list = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
1838
1839 assert_eq!(
1840 adjust_offsets_for_slice(&list),
1841 OffsetBuffer::from_lengths([3, 0, 3, 2])
1842 );
1843
1844 assert_eq!(
1845 adjust_offsets_for_slice(&list.slice(0, 1)),
1846 OffsetBuffer::from_lengths([3])
1847 );
1848
1849 assert_eq!(
1850 adjust_offsets_for_slice(&list.slice(1, 2)),
1851 OffsetBuffer::from_lengths([0, 3])
1852 );
1853
1854 assert_eq!(
1855 adjust_offsets_for_slice(&list.slice(1, 3)),
1856 OffsetBuffer::from_lengths([0, 3, 2])
1857 );
1858
1859 assert_eq!(
1860 adjust_offsets_for_slice(&list.slice(0, 0)),
1861 OffsetBuffer::from_lengths([])
1862 );
1863
1864 assert_eq!(
1865 adjust_offsets_for_slice(&list.slice(1, 0)),
1866 OffsetBuffer::from_lengths([])
1867 );
1868
1869 assert_eq!(
1870 adjust_offsets_for_slice(&list.slice(3, 0)),
1871 OffsetBuffer::from_lengths([])
1872 );
1873 }
1874
1875 fn create_i32_list(
1876 values: impl Into<Int32Array>,
1877 offsets: OffsetBuffer<i32>,
1878 nulls: Option<NullBuffer>,
1879 ) -> ListArray {
1880 let list_field = Arc::new(Field::new_list_field(DataType::Int32, true));
1881
1882 ListArray::new(list_field, offsets, Arc::new(values.into()), nulls)
1883 }
1884
1885 #[test]
1886 fn test_remove_list_null_values_list() {
1887 let list = Arc::new(create_i32_list(
1888 vec![100, 20, 10, 0, 0, 0, 0, 1, 50],
1889 OffsetBuffer::<i32>::from_lengths(vec![3, 4, 0, 2, 0]),
1890 Some(NullBuffer::from(vec![true, false, false, true, false])),
1891 )) as ArrayRef;
1892
1893 let res = remove_list_null_values(&list).unwrap();
1894 let res = res.as_list::<i32>();
1895
1896 let expected = Arc::new(create_i32_list(
1897 vec![100, 20, 10, 1, 50],
1898 OffsetBuffer::<i32>::from_lengths(vec![3, 0, 0, 2, 0]),
1899 Some(NullBuffer::from(vec![true, false, false, true, false])),
1900 )) as ArrayRef;
1901 let expected = expected.as_list::<i32>();
1902
1903 assert_eq!(res, expected);
1904 assert_eq!(res.values(), expected.values());
1906 assert_eq!(res.offsets(), expected.offsets());
1907 }
1908
1909 #[test]
1910 fn test_list_array_values_row_number() {
1911 assert_eq!(
1912 variable_size_list_values_row_number::<Int32Type>(
1913 &OffsetBuffer::from_lengths([1, 3, 0, 2,])
1914 ),
1915 Int32Array::from(vec![0, 1, 1, 1, 3, 3])
1916 );
1917
1918 assert_eq!(
1919 variable_size_list_values_row_number::<Int32Type>(
1920 &OffsetBuffer::from_lengths([])
1921 ),
1922 Int32Array::new_null(0)
1923 );
1924
1925 assert_eq!(
1926 variable_size_list_values_row_number::<Int32Type>(
1927 &OffsetBuffer::from_lengths([0])
1928 ),
1929 Int32Array::new_null(0)
1930 );
1931
1932 assert_eq!(
1933 variable_size_list_values_row_number::<Int32Type>(
1934 &OffsetBuffer::from_lengths([0, 0])
1935 ),
1936 Int32Array::new_null(0)
1937 );
1938
1939 assert_eq!(
1940 variable_size_list_values_row_number::<Int32Type>(
1941 &OffsetBuffer::from_lengths([1])
1942 ),
1943 Int32Array::from(vec![0])
1944 );
1945
1946 assert_eq!(
1947 variable_size_list_values_row_number::<Int32Type>(
1948 &OffsetBuffer::from_lengths([2])
1949 ),
1950 Int32Array::from(vec![0, 0])
1951 );
1952 }
1953
1954 #[test]
1955 fn test_fsl_values_row_number() {
1956 assert_eq!(
1957 fsl_values_row_number(2, 3).unwrap(),
1958 Int32Array::from(vec![0, 0, 1, 1, 2, 2])
1959 );
1960
1961 assert_eq!(
1962 fsl_values_row_number(1, 3).unwrap(),
1963 Int32Array::from(vec![0, 1, 2])
1964 );
1965
1966 assert_eq!(
1967 fsl_values_row_number(2, 1).unwrap(),
1968 Int32Array::from(vec![0, 0])
1969 );
1970
1971 assert_eq!(
1972 fsl_values_row_number(2, 0).unwrap(),
1973 Int32Array::new_null(0),
1974 );
1975
1976 assert_eq!(
1977 fsl_values_row_number(0, 2).unwrap(),
1978 Int32Array::new_null(0),
1979 );
1980
1981 assert_eq!(
1982 fsl_values_row_number(0, 0).unwrap(),
1983 Int32Array::new_null(0),
1984 );
1985
1986 fsl_values_row_number(-1, 2).unwrap_err();
1987 fsl_values_row_number(-1, 0).unwrap_err();
1988 }
1989}