1use crate::array::*;
21use crate::datatypes::*;
22use crate::util::test_util::seedable_rng;
23use arrow_buffer::{Buffer, IntervalMonthDayNano, NullBuffer};
24use arrow_schema::Field;
25use half::f16;
26use rand::Rng;
27use rand::SeedableRng;
28use rand::distr::uniform::SampleUniform;
29use rand::rng;
30use rand::{
31 distr::{Alphanumeric, Distribution, SampleString, StandardUniform},
32 prelude::StdRng,
33};
34use std::ops::Range;
35use std::sync::Arc;
36
37pub fn create_primitive_array<T>(size: usize, null_density: f32) -> PrimitiveArray<T>
39where
40 T: ArrowPrimitiveType,
41 StandardUniform: Distribution<T::Native>,
42{
43 let mut rng = seedable_rng();
44
45 (0..size)
46 .map(|_| {
47 if rng.random::<f32>() < null_density {
48 None
49 } else {
50 Some(rng.random())
51 }
52 })
53 .collect()
54}
55
56pub fn create_primitive_array_range<T>(
59 size: usize,
60 null_density: f32,
61 value_range: Range<T::Native>,
62) -> PrimitiveArray<T>
63where
64 T: ArrowPrimitiveType,
65 StandardUniform: Distribution<T::Native>,
66 T::Native: SampleUniform,
67{
68 let mut rng = seedable_rng();
69
70 (0..size)
71 .map(|_| {
72 if rng.random::<f32>() < null_density {
73 None
74 } else {
75 Some(rng.random_range(value_range.clone()))
76 }
77 })
78 .collect()
79}
80
81pub fn create_primitive_array_with_seed<T>(
84 size: usize,
85 null_density: f32,
86 seed: u64,
87) -> PrimitiveArray<T>
88where
89 T: ArrowPrimitiveType,
90 StandardUniform: Distribution<T::Native>,
91{
92 let mut rng = StdRng::seed_from_u64(seed);
93
94 (0..size)
95 .map(|_| {
96 if rng.random::<f32>() < null_density {
97 None
98 } else {
99 Some(rng.random())
100 }
101 })
102 .collect()
103}
104
105pub fn create_month_day_nano_array_with_seed(
108 size: usize,
109 null_density: f32,
110 seed: u64,
111) -> IntervalMonthDayNanoArray {
112 let mut rng = StdRng::seed_from_u64(seed);
113
114 (0..size)
115 .map(|_| {
116 if rng.random::<f32>() < null_density {
117 None
118 } else {
119 Some(IntervalMonthDayNano::new(
120 rng.random(),
121 rng.random(),
122 rng.random(),
123 ))
124 }
125 })
126 .collect()
127}
128
129pub fn create_boolean_array(size: usize, null_density: f32, true_density: f32) -> BooleanArray
131where
132 StandardUniform: Distribution<bool>,
133{
134 let mut rng = seedable_rng();
135 (0..size)
136 .map(|_| {
137 if rng.random::<f32>() < null_density {
138 None
139 } else {
140 let value = rng.random::<f32>() < true_density;
141 Some(value)
142 }
143 })
144 .collect()
145}
146
147pub fn create_boolean_array_with_seed(
149 size: usize,
150 null_density: f32,
151 true_density: f32,
152 seed: u64,
153) -> BooleanArray
154where
155 StandardUniform: Distribution<bool>,
156{
157 let mut rng = StdRng::seed_from_u64(seed);
158 (0..size)
159 .map(|_| {
160 if rng.random::<f32>() < null_density {
161 None
162 } else {
163 let value = rng.random::<f32>() < true_density;
164 Some(value)
165 }
166 })
167 .collect()
168}
169
170pub fn create_string_array<Offset: OffsetSizeTrait>(
176 size: usize,
177 null_density: f32,
178) -> GenericStringArray<Offset> {
179 create_string_array_with_max_len(size, null_density, 400)
180}
181
182pub fn create_longer_string_array_with_same_prefix<Offset: OffsetSizeTrait>(
186 size: usize,
187 null_density: f32,
188) -> GenericStringArray<Offset> {
189 create_string_array_with_len_range_and_prefix(size, null_density, 13, 100, "prefix_")
190}
191
192pub fn create_longer_string_view_array_with_same_prefix(
196 size: usize,
197 null_density: f32,
198) -> StringViewArray {
199 create_string_view_array_with_len_range_and_prefix(size, null_density, 13, 100, "prefix_")
200}
201
202fn create_string_array_with_len_range_and_prefix<Offset: OffsetSizeTrait>(
203 size: usize,
204 null_density: f32,
205 min_str_len: usize,
206 max_str_len: usize,
207 prefix: &str,
208) -> GenericStringArray<Offset> {
209 create_string_array_with_len_range_and_prefix_and_seed(
210 size,
211 null_density,
212 min_str_len,
213 max_str_len,
214 prefix,
215 42,
216 )
217}
218
219pub fn create_string_array_with_len_range_and_prefix_and_seed<Offset: OffsetSizeTrait>(
223 size: usize,
224 null_density: f32,
225 min_str_len: usize,
226 max_str_len: usize,
227 prefix: &str,
228 seed: u64,
229) -> GenericStringArray<Offset> {
230 assert!(
231 min_str_len <= max_str_len,
232 "min_str_len must be <= max_str_len"
233 );
234 assert!(
235 prefix.len() <= max_str_len,
236 "Prefix length must be <= max_str_len"
237 );
238
239 let rng = &mut StdRng::seed_from_u64(seed);
240 (0..size)
241 .map(|_| {
242 if rng.random::<f32>() < null_density {
243 None
244 } else {
245 let remaining_len = rng.random_range(
246 min_str_len.saturating_sub(prefix.len())..=(max_str_len - prefix.len()),
247 );
248
249 let mut value = prefix.to_string();
250 value.extend(
251 rng.sample_iter(&Alphanumeric)
252 .take(remaining_len)
253 .map(char::from),
254 );
255
256 Some(value)
257 }
258 })
259 .collect()
260}
261pub fn create_string_view_array_with_len_range_and_seed(
269 size: usize,
270 null_density: f32,
271 range: Range<usize>,
272 seed: u64,
273) -> StringViewArray {
274 let rng = &mut StdRng::seed_from_u64(seed);
275 (0..size)
276 .map(|_| {
277 if rng.random::<f32>() < null_density {
278 None
279 } else {
280 let str_len = rng.random_range(range.clone());
281 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
282 let value = String::from_utf8(value).unwrap();
283 Some(value)
284 }
285 })
286 .collect()
287}
288
289fn create_string_view_array_with_len_range_and_prefix(
290 size: usize,
291 null_density: f32,
292 min_str_len: usize,
293 max_str_len: usize,
294 prefix: &str,
295) -> StringViewArray {
296 assert!(
297 min_str_len <= max_str_len,
298 "min_str_len must be <= max_str_len"
299 );
300 assert!(
301 prefix.len() <= max_str_len,
302 "Prefix length must be <= max_str_len"
303 );
304
305 let rng = &mut seedable_rng();
306 (0..size)
307 .map(|_| {
308 if rng.random::<f32>() < null_density {
309 None
310 } else {
311 let remaining_len = rng.random_range(
312 min_str_len.saturating_sub(prefix.len())..=(max_str_len - prefix.len()),
313 );
314
315 let mut value = prefix.to_string();
316 value.extend(
317 rng.sample_iter(&Alphanumeric)
318 .take(remaining_len)
319 .map(char::from),
320 );
321
322 Some(value)
323 }
324 })
325 .collect()
326}
327
328pub fn create_string_array_with_max_len<Offset: OffsetSizeTrait>(
330 size: usize,
331 null_density: f32,
332 max_str_len: usize,
333) -> GenericStringArray<Offset> {
334 let rng = &mut seedable_rng();
335 (0..size)
336 .map(|_| {
337 if rng.random::<f32>() < null_density {
338 None
339 } else {
340 let str_len = rng.random_range(0..max_str_len);
341 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
342 let value = String::from_utf8(value).unwrap();
343 Some(value)
344 }
345 })
346 .collect()
347}
348
349pub fn create_string_array_with_len<Offset: OffsetSizeTrait>(
351 size: usize,
352 null_density: f32,
353 str_len: usize,
354) -> GenericStringArray<Offset> {
355 let rng = &mut seedable_rng();
356
357 (0..size)
358 .map(|_| {
359 if rng.random::<f32>() < null_density {
360 None
361 } else {
362 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
363 let value = String::from_utf8(value).unwrap();
364 Some(value)
365 }
366 })
367 .collect()
368}
369
370pub fn create_string_view_array(size: usize, null_density: f32) -> StringViewArray {
374 create_string_view_array_with_max_len(size, null_density, 400)
375}
376
377pub fn create_string_view_array_with_max_len(
379 size: usize,
380 null_density: f32,
381 max_str_len: usize,
382) -> StringViewArray {
383 let rng = &mut seedable_rng();
384 (0..size)
385 .map(|_| {
386 if rng.random::<f32>() < null_density {
387 None
388 } else {
389 let str_len = rng.random_range(0..max_str_len);
390 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
391 let value = String::from_utf8(value).unwrap();
392 Some(value)
393 }
394 })
395 .collect()
396}
397
398pub fn create_string_view_array_with_fixed_len(
400 size: usize,
401 null_density: f32,
402 str_len: usize,
403) -> StringViewArray {
404 let rng = &mut seedable_rng();
405 (0..size)
406 .map(|_| {
407 if rng.random::<f32>() < null_density {
408 None
409 } else {
410 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
411 let value = String::from_utf8(value).unwrap();
412 Some(value)
413 }
414 })
415 .collect()
416}
417
418pub fn create_string_view_array_with_len(
420 size: usize,
421 null_density: f32,
422 str_len: usize,
423 mixed: bool,
424) -> StringViewArray {
425 let rng = &mut seedable_rng();
426
427 let mut lengths = Vec::with_capacity(size);
428
429 if mixed {
431 for _ in 0..size / 2 {
432 lengths.push(rng.random_range(1..12));
433 }
434 for _ in size / 2..size {
435 lengths.push(rng.random_range(12..=std::cmp::max(30, str_len)));
436 }
437 } else {
438 lengths.resize(size, str_len);
439 }
440
441 lengths
442 .into_iter()
443 .map(|len| {
444 if rng.random::<f32>() < null_density {
445 None
446 } else {
447 let value: Vec<u8> = rng.sample_iter(&Alphanumeric).take(len).collect();
448 Some(String::from_utf8(value).unwrap())
449 }
450 })
451 .collect()
452}
453
454pub fn create_string_dict_array<K: ArrowDictionaryKeyType>(
457 size: usize,
458 null_density: f32,
459 str_len: usize,
460) -> DictionaryArray<K> {
461 let rng = &mut seedable_rng();
462
463 let data: Vec<_> = (0..size)
464 .map(|_| {
465 if rng.random::<f32>() < null_density {
466 None
467 } else {
468 let value = rng.sample_iter(&Alphanumeric).take(str_len).collect();
469 let value = String::from_utf8(value).unwrap();
470 Some(value)
471 }
472 })
473 .collect();
474
475 data.iter().map(|x| x.as_deref()).collect()
476}
477
478pub fn create_primitive_list_array_with_seed<O, T>(
487 size: usize,
488 null_density: f32,
489 list_null_density: f32,
490 max_list_size: usize,
491 seed: u64,
492) -> GenericListArray<O>
493where
494 O: OffsetSizeTrait,
495 T: ArrowPrimitiveType,
496 StandardUniform: Distribution<T::Native>,
497{
498 let mut rng = StdRng::seed_from_u64(seed);
499
500 let values = (0..size).map(|_| {
501 if rng.random::<f32>() < null_density {
502 None
503 } else {
504 let list_size = rng.random_range(0..=max_list_size);
505 let list_values: Vec<Option<T::Native>> = (0..list_size)
506 .map(|_| {
507 if rng.random::<f32>() < list_null_density {
508 None
509 } else {
510 Some(rng.random())
511 }
512 })
513 .collect();
514 Some(list_values)
515 }
516 });
517
518 GenericListArray::<O>::from_iter_primitive::<T, _, _>(values)
519}
520
521pub fn create_primitive_list_array<O, T>(
525 size: usize,
526 null_density: f32,
527 list_null_density: f32,
528 max_list_size: usize,
529) -> GenericListArray<O>
530where
531 O: OffsetSizeTrait,
532 T: ArrowPrimitiveType,
533 StandardUniform: Distribution<T::Native>,
534{
535 let mut rng = seedable_rng();
536
537 let values = (0..size).map(|_| {
538 if rng.random::<f32>() < null_density {
539 None
540 } else {
541 let list_size = rng.random_range(0..=max_list_size);
542 let list_values: Vec<Option<T::Native>> = (0..list_size)
543 .map(|_| {
544 if rng.random::<f32>() < list_null_density {
545 None
546 } else {
547 Some(rng.random())
548 }
549 })
550 .collect();
551 Some(list_values)
552 }
553 });
554
555 GenericListArray::<O>::from_iter_primitive::<T, _, _>(values)
556}
557
558pub fn create_primitive_list_view_array<O, T>(
562 size: usize,
563 null_density: f32,
564 list_null_density: f32,
565 max_list_size: usize,
566) -> GenericListViewArray<O>
567where
568 T: ArrowPrimitiveType,
569 StandardUniform: Distribution<T::Native>,
570 O: OffsetSizeTrait,
571{
572 let mut rng = seedable_rng();
573
574 let values = (0..size).map(|_| {
575 if rng.random::<f32>() < null_density {
576 None
577 } else {
578 let list_size = rng.random_range(0..=max_list_size);
579 let list_values: Vec<Option<T::Native>> = (0..list_size)
580 .map(|_| {
581 if rng.random::<f32>() < list_null_density {
582 None
583 } else {
584 Some(rng.random())
585 }
586 })
587 .collect();
588 Some(list_values)
589 }
590 });
591
592 GenericListViewArray::<O>::from_iter_primitive::<T, _, _>(values)
593}
594
595pub fn create_primitive_run_array<R: RunEndIndexType, V: ArrowPrimitiveType>(
597 logical_array_len: usize,
598 physical_array_len: usize,
599) -> RunArray<R> {
600 assert!(logical_array_len >= physical_array_len);
601 let run_len = logical_array_len / physical_array_len;
603
604 let mut run_len_extra = logical_array_len % physical_array_len;
606
607 let mut values: Vec<V::Native> = (0..physical_array_len)
608 .flat_map(|s| {
609 let mut take_len = run_len;
610 if run_len_extra > 0 {
611 take_len += 1;
612 run_len_extra -= 1;
613 }
614 std::iter::repeat_n(V::Native::from_usize(s).unwrap(), take_len)
615 })
616 .collect();
617 while values.len() < logical_array_len {
618 let last_val = values[values.len() - 1];
619 values.push(last_val);
620 }
621 let mut builder = PrimitiveRunBuilder::<R, V>::with_capacity(physical_array_len);
622 builder.extend(values.into_iter().map(Some));
623
624 builder.finish()
625}
626
627pub fn create_string_array_for_runs(
631 physical_array_len: usize,
632 logical_array_len: usize,
633 string_len: usize,
634) -> Vec<String> {
635 assert!(logical_array_len >= physical_array_len);
636 let mut rng = rng();
637
638 let run_len = logical_array_len / physical_array_len;
640
641 let mut run_len_extra = logical_array_len % physical_array_len;
643
644 let mut values: Vec<String> = (0..physical_array_len)
645 .map(|_| (0..string_len).map(|_| rng.random::<char>()).collect())
646 .flat_map(|s| {
647 let mut take_len = run_len;
648 if run_len_extra > 0 {
649 take_len += 1;
650 run_len_extra -= 1;
651 }
652 std::iter::repeat_n(s, take_len)
653 })
654 .collect();
655 while values.len() < logical_array_len {
656 let last_val = values[values.len() - 1].clone();
657 values.push(last_val);
658 }
659 values
660}
661
662pub fn create_binary_array<Offset: OffsetSizeTrait>(
664 size: usize,
665 null_density: f32,
666) -> GenericBinaryArray<Offset> {
667 create_binary_array_with_seed(
668 size,
669 null_density,
670 42, 42, )
673}
674
675pub fn create_binary_array_with_seed<Offset: OffsetSizeTrait>(
683 size: usize,
684 null_density: f32,
685 bytes_seed: u64,
686 bytes_length_seed: u64,
687) -> GenericBinaryArray<Offset> {
688 let rng = &mut StdRng::seed_from_u64(bytes_seed);
689 let range_rng = &mut StdRng::seed_from_u64(bytes_length_seed);
690
691 (0..size)
692 .map(|_| {
693 if rng.random::<f32>() < null_density {
694 None
695 } else {
696 let value = rng
697 .sample_iter::<u8, _>(StandardUniform)
698 .take(range_rng.random_range(0..8))
699 .collect::<Vec<u8>>();
700 Some(value)
701 }
702 })
703 .collect()
704}
705
706pub fn create_binary_array_with_len_range_and_prefix_and_seed<Offset: OffsetSizeTrait>(
711 size: usize,
712 null_density: f32,
713 min_len: usize,
714 max_len: usize,
715 prefix: &[u8],
716 seed: u64,
717) -> GenericBinaryArray<Offset> {
718 assert!(min_len <= max_len, "min_len must be <= max_len");
719 assert!(prefix.len() <= max_len, "Prefix length must be <= max_len");
720
721 let rng = &mut StdRng::seed_from_u64(seed);
722 (0..size)
723 .map(|_| {
724 if rng.random::<f32>() < null_density {
725 None
726 } else {
727 let remaining_len = rng
728 .random_range(min_len.saturating_sub(prefix.len())..=(max_len - prefix.len()));
729
730 let remaining = rng
731 .sample_iter::<u8, _>(StandardUniform)
732 .take(remaining_len);
733
734 let value = prefix.iter().copied().chain(remaining).collect::<Vec<u8>>();
735 Some(value)
736 }
737 })
738 .collect()
739}
740
741pub fn create_fsb_array(size: usize, null_density: f32, value_len: usize) -> FixedSizeBinaryArray {
743 let rng = &mut seedable_rng();
744
745 FixedSizeBinaryArray::try_from_sparse_iter_with_size(
746 (0..size).map(|_| {
747 if rng.random::<f32>() < null_density {
748 None
749 } else {
750 let value = rng
751 .sample_iter::<u8, _>(StandardUniform)
752 .take(value_len)
753 .collect::<Vec<u8>>();
754 Some(value)
755 }
756 }),
757 value_len as i32,
758 )
759 .unwrap()
760}
761
762pub fn create_dict_from_values<K>(
765 size: usize,
766 null_density: f32,
767 values: &dyn Array,
768) -> DictionaryArray<K>
769where
770 K: ArrowDictionaryKeyType,
771 StandardUniform: Distribution<K::Native>,
772 K::Native: SampleUniform,
773{
774 let min_key = K::Native::from_usize(0).unwrap();
775 let max_key = K::Native::from_usize(values.len()).unwrap();
776 create_sparse_dict_from_values(size, null_density, values, min_key..max_key)
777}
778
779pub fn create_sparse_dict_from_values<K>(
782 size: usize,
783 null_density: f32,
784 values: &dyn Array,
785 key_range: Range<K::Native>,
786) -> DictionaryArray<K>
787where
788 K: ArrowDictionaryKeyType,
789 StandardUniform: Distribution<K::Native>,
790 K::Native: SampleUniform,
791{
792 let mut rng = seedable_rng();
793 let data_type =
794 DataType::Dictionary(Box::new(K::DATA_TYPE), Box::new(values.data_type().clone()));
795
796 let keys: Buffer = (0..size)
797 .map(|_| rng.random_range(key_range.clone()))
798 .collect();
799
800 let nulls: Option<Buffer> = (null_density != 0.).then(|| {
801 (0..size)
802 .map(|_| rng.random_bool((1.0 - null_density) as _))
803 .collect()
804 });
805
806 let data = ArrayDataBuilder::new(data_type)
807 .len(size)
808 .null_bit_buffer(nulls)
809 .add_buffer(keys)
810 .add_child_data(values.to_data())
811 .build()
812 .unwrap();
813
814 DictionaryArray::from(data)
815}
816
817pub fn create_f16_array(size: usize, nan_density: f32) -> Float16Array {
819 let mut rng = seedable_rng();
820
821 (0..size)
822 .map(|_| {
823 if rng.random::<f32>() < nan_density {
824 Some(f16::NAN)
825 } else {
826 Some(rng.random())
827 }
828 })
829 .collect()
830}
831
832pub fn create_f32_array(size: usize, nan_density: f32) -> Float32Array {
834 let mut rng = seedable_rng();
835
836 (0..size)
837 .map(|_| {
838 if rng.random::<f32>() < nan_density {
839 Some(f32::NAN)
840 } else {
841 Some(rng.random())
842 }
843 })
844 .collect()
845}
846
847pub fn create_f64_array(size: usize, nan_density: f32) -> Float64Array {
849 let mut rng = seedable_rng();
850
851 (0..size)
852 .map(|_| {
853 if rng.random::<f32>() < nan_density {
854 Some(f64::NAN)
855 } else {
856 Some(rng.random())
857 }
858 })
859 .collect()
860}
861
862pub fn create_f64_array_with_seed(size: usize, nan_density: f32, seed: u64) -> Float64Array {
864 let mut rng = StdRng::seed_from_u64(seed);
865
866 (0..size)
867 .map(|_| {
868 if rng.random::<f32>() < nan_density {
869 Some(f64::NAN)
870 } else {
871 Some(rng.random())
872 }
873 })
874 .collect()
875}
876
877pub fn create_primitive_fixed_size_list_array<T>(
885 size: usize,
886 null_density: f32,
887 value_null_density: f32,
888 list_size: i32,
889) -> FixedSizeListArray
890where
891 T: ArrowPrimitiveType,
892 StandardUniform: Distribution<T::Native>,
893{
894 let mut rng = seedable_rng();
895 let list_size_usize = usize::try_from(list_size).expect("list_size must be non-negative");
896 let values: PrimitiveArray<T> = (0..size * list_size_usize)
897 .map(|_| {
898 if rng.random::<f32>() < value_null_density {
899 None
900 } else {
901 Some(rng.random())
902 }
903 })
904 .collect();
905 let field = Arc::new(Field::new("item", T::DATA_TYPE, value_null_density > 0.0));
906 let nulls = (null_density > 0.0).then(|| {
907 NullBuffer::new(arrow_buffer::BooleanBuffer::collect_bool(size, |_| {
908 rng.random::<f32>() >= null_density
909 }))
910 });
911 FixedSizeListArray::new(field, list_size, Arc::new(values), nulls)
912}
913
914pub fn create_string_map_array<T>(
923 size: usize,
924 null_density: f32,
925 max_map_size: usize,
926 key_len: usize,
927) -> MapArray
928where
929 T: ArrowPrimitiveType,
930 StandardUniform: Distribution<T::Native>,
931{
932 let mut rng = seedable_rng();
933 let mut builder = MapBuilder::new(None, StringBuilder::new(), PrimitiveBuilder::<T>::new());
934 for _ in 0..size {
935 if rng.random::<f32>() < null_density {
936 builder.append(false).unwrap();
937 } else {
938 let n = rng.random_range(0..=max_map_size);
939 for _ in 0..n {
940 builder
941 .keys()
942 .append_value(Alphanumeric.sample_string(&mut rng, key_len));
943 builder.values().append_value(rng.random());
944 }
945 builder.append(true).unwrap();
946 }
947 }
948 builder.finish()
949}