1use std::collections::{HashMap, HashSet};
43use std::ops::Range;
44use std::sync::{Arc, Mutex};
45
46use rudb_common::{Error, LogicalType, Result, Spread, Value};
47
48use crate::buffer::Buffer;
49use crate::string::{Arenas, StringColumn, StringView};
50use crate::validity::Validity;
51use crate::vector::{
52 Data, Form, NOWHERE, Vector, copy_of, data_for, empty_data_for, layout_of, placed_of,
53};
54
55#[derive(Debug)]
60pub struct Assembly {
61 ty: LogicalType,
62 rows: usize,
63 data: Data,
65 at: Vec<usize>,
67 live: Vec<bool>,
69 values: Option<Vec<Value>>,
77}
78
79impl Assembly {
80 pub fn new(ty: LogicalType, rows: usize) -> Result<Self> {
86 let nested =
87 matches!(ty, LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _));
88 let values = if nested { Some(vec![Value::Null; rows]) } else { None };
89 let data = if nested { Data::Empty } else { empty_data_for(&ty)? };
90 Ok(Self { ty, rows, data, at: vec![NOWHERE; rows], live: vec![false; rows], values })
91 }
92
93 #[must_use]
95 pub fn rows(&self) -> usize {
96 self.rows
97 }
98
99 pub fn place(&mut self, positions: &[u32], piece: &Vector) -> Result<()> {
112 if positions.len() != piece.len() {
113 return Err(Error::internal(format!(
114 "a piece of {} rows placed at {} positions",
115 piece.len(),
116 positions.len()
117 )));
118 }
119 for &row in positions {
120 if row as usize >= self.rows {
121 return Err(Error::internal(format!(
122 "row {row} placed in an assembly of {} rows",
123 self.rows
124 )));
125 }
126 }
127 if let Some(values) = &mut self.values {
128 for (slot, &row) in positions.iter().enumerate() {
132 values[row as usize] = piece.value_at(slot);
133 }
134 return Ok(());
135 }
136 let flat = piece.flatten()?;
141 let Some(from) = flat.data() else {
142 return Err(Error::internal("a flattened vector with no run of data in it"));
143 };
144 let start = self.data.len();
145 let appended = extend(&mut self.data, from, &mut Arenas::default())?;
146 for (slot, &row) in positions.iter().enumerate() {
147 let row = row as usize;
148 if slot < appended {
151 self.at[row] = start + slot;
152 self.live[row] = !piece.is_null_at(slot);
153 } else {
154 self.at[row] = NOWHERE;
155 self.live[row] = false;
156 }
157 }
158 Ok(())
159 }
160
161 pub fn finish(self) -> Result<Vector> {
167 if let Some(values) = self.values {
168 return Vector::from_values(self.ty, &values);
169 }
170 if matches!(self.data, Data::Empty) {
173 return Ok(Vector::constant(self.ty, Value::Null, self.rows));
174 }
175 let validity = Validity::from_run(&self.live);
176 if let Data::Varlen(column) = self.data {
182 let (laid, arena) = column.into_parts();
183 let arena = Arc::new(arena);
184 if straight(&self.at) {
185 return Ok(Vector::string_views(self.ty, laid, arena)?.with_validity(validity));
186 }
187 let views = self
188 .at
189 .iter()
190 .map(|&index| laid.get(index).copied().unwrap_or_else(StringView::empty))
191 .collect();
192 return Ok(Vector::string_views(self.ty, views, arena)?.with_validity(validity));
193 }
194 if straight(&self.at) {
198 return Ok(Vector::flat(self.ty, self.data)?.with_validity(validity));
199 }
200 let gathered = copy_of(&self.data, &self.at);
201 Ok(Vector::flat(self.ty, gathered)?.with_validity(validity))
202 }
203}
204
205pub fn concat<V: AsRef<Vector>>(ty: &LogicalType, pieces: &[V]) -> Result<Option<Vector>> {
233 let pieces: Vec<&Vector> = pieces.iter().map(AsRef::as_ref).collect();
234 laid(ty, &pieces)
235}
236
237pub fn concat_on<V: AsRef<Vector>>(
270 ty: &LogicalType,
271 pieces: &[V],
272 spread: &Spread<'_>,
273) -> Result<Option<Vector>> {
274 let pieces: Vec<&Vector> = pieces.iter().map(AsRef::as_ref).collect();
275 if let Some(strung) = strung(ty, &pieces, spread)? {
276 return Ok(Some(strung));
277 }
278 laid(ty, &pieces)
279}
280
281fn strung(ty: &LogicalType, pieces: &[&Vector], spread: &Spread<'_>) -> Result<Option<Vector>> {
286 let Some(columns) = apart(ty, pieces) else {
287 return Ok(None);
288 };
289 let mut bases = Vec::with_capacity(columns.len());
293 let mut bytes = 0usize;
294 let mut rows = 0usize;
295 for column in &columns {
296 bases.push((bytes, rows));
297 bytes += column.arena().len();
298 rows += column.len();
299 }
300
301 let mut arena = vec![0u8; bytes];
306 let mut views = vec![StringView::empty(); rows];
307 let mut arena_rest: &mut [u8] = &mut arena;
311 let mut views_rest: &mut [StringView] = &mut views;
312 let mut slots = Vec::with_capacity(columns.len());
313 for column in &columns {
314 let (arena_head, arena_tail) = arena_rest.split_at_mut(column.arena().len());
315 let (views_head, views_tail) = views_rest.split_at_mut(column.len());
316 slots.push(Mutex::new((arena_head, views_head)));
317 arena_rest = arena_tail;
318 views_rest = views_tail;
319 }
320
321 let task = |at: usize| {
322 let column = columns[at];
323 let (base, _) = bases[at];
324 let mut slot = slots[at].lock().unwrap_or_else(|poisoned| poisoned.into_inner());
325 let (into_arena, into_views) = &mut *slot;
326 into_arena.copy_from_slice(column.arena());
327 let base = base as u64;
328 for (slot, view) in into_views.iter_mut().zip(column.views()) {
329 *slot = view.shifted(base);
330 }
331 };
332 spread(columns.len(), &task)?;
333 drop(slots);
334
335 let validity = run_of(pieces, rows);
336 let page = Vector::string_views(ty.clone(), views, Arc::new(Buffer::from(arena)))?;
337 Ok(Some(page.with_validity(validity)))
338}
339
340fn apart<'a>(ty: &LogicalType, pieces: &[&'a Vector]) -> Option<Vec<&'a StringColumn>> {
362 if pieces.len() < 2 {
363 return None;
364 }
365 let mut columns = Vec::with_capacity(pieces.len());
366 let mut seen = HashSet::with_capacity(pieces.len());
367 for piece in pieces {
368 if piece.form() != Form::Flat || piece.logical_type() != ty || piece.is_empty() {
369 return None;
370 }
371 let Some(Data::Varlen(column)) = piece.data() else {
372 return None;
373 };
374 if !column.mostly_read() || !seen.insert(column.arena().as_ptr() as usize) {
375 return None;
376 }
377 columns.push(column);
378 }
379 Some(columns)
380}
381
382fn laid(ty: &LogicalType, pieces: &[&Vector]) -> Result<Option<Vector>> {
388 if pieces.is_empty() {
389 return Ok(None);
390 }
391 let rows = pieces.iter().map(|piece| piece.len()).sum();
392 let shared = pieces[0].stable_dictionary_parts().map(|(_, values)| values).filter(|values| {
393 pieces.iter().all(|piece| {
394 piece.logical_type() == ty
395 && !piece.is_empty()
396 && piece
397 .stable_dictionary_parts()
398 .is_some_and(|(_, held)| Arc::ptr_eq(held, values))
399 })
400 });
401 if let Some(values) = shared {
402 let mut codes = Vec::with_capacity(rows);
403 for piece in pieces {
404 if let Some((held, _)) = piece.stable_dictionary_parts() {
405 codes.extend_from_slice(held);
406 }
407 }
408 let validity = run_of(pieces, rows);
409 return Ok(Some(
410 Vector::stable_dictionary(codes, Arc::clone(values))?.with_validity(validity),
411 ));
412 }
413 if let Some(arena) = pieces[0].shared_views().map(|(_, arena)| arena).filter(|arena| {
417 pieces.iter().all(|piece| {
418 piece.logical_type() == ty
419 && piece.shared_views().is_some_and(|(_, held)| Arc::ptr_eq(held, arena))
420 })
421 }) {
422 let mut views = Vec::with_capacity(rows);
423 for piece in pieces {
424 if let Some((held, _)) = piece.shared_views() {
425 views.extend_from_slice(held);
426 }
427 }
428 let validity = run_of(pieces, rows);
429 return Ok(Some(
430 Vector::string_views(ty.clone(), views, Arc::clone(arena))?.with_validity(validity),
431 ));
432 }
433 let laid = pieces
436 .iter()
437 .all(|piece| piece.form() == Form::Flat && piece.logical_type() == ty && !piece.is_empty());
438 if !laid {
439 return Ok(None);
440 }
441 if let Some(data) = adjoined(pieces) {
442 let validity = run_of(pieces, rows);
443 return Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity)));
444 }
445 let mut data = data_for(ty, rows)?;
449 let mut arenas = arenas_of(pieces);
450 for piece in pieces {
451 let from = piece
452 .data()
453 .ok_or_else(|| Error::internal("a flat vector with no run of data in it"))?;
454 let appended = extend(&mut data, from, &mut arenas)?;
455 if appended != piece.len() {
456 return Err(Error::internal(format!(
457 "a piece of {} rows laid {appended} values end to end",
458 piece.len()
459 )));
460 }
461 }
462 let validity = run_of(pieces, rows);
463 if let Data::Varlen(column) = data {
464 let (views, arena) = column.into_parts();
465 let page = Vector::string_views(ty.clone(), views, Arc::new(arena))?;
466 return Ok(Some(page.with_validity(validity)));
467 }
468 Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity).into_pages()))
469}
470
471pub fn interleave(ty: &LogicalType, pieces: &[Vector], order: &[usize]) -> Result<Vector> {
488 interleave_placed(ty, pieces, order, None)
489}
490
491pub fn interleave_placed(
512 ty: &LogicalType,
513 pieces: &[Vector],
514 order: &[usize],
515 inverse: Option<&[u32]>,
516) -> Result<Vector> {
517 let rows: usize = pieces.iter().map(Vector::len).sum();
518 if let Some(inverse) = inverse.filter(|inverse| inverse.len() != rows || order.len() != rows) {
519 return Err(Error::internal(format!(
520 "{} places and {} positions for a permutation of {rows} rows",
521 inverse.len(),
522 order.len()
523 )));
524 }
525 if let Some(&past) = order.iter().find(|&&index| index >= rows) {
526 return Err(Error::internal(format!("row {past} read out of pieces of {rows} rows")));
527 }
528 if matches!(ty, LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)) {
529 let laid: Vec<Value> = pieces
532 .iter()
533 .flat_map(|piece| (0..piece.len()).map(|row| piece.value_at(row)))
534 .collect();
535 let values: Vec<Value> =
536 order.iter().map(|&index| laid.get(index).cloned().unwrap_or(Value::Null)).collect();
537 return Vector::from_values(ty.clone(), &values);
538 }
539 if let Some(merged) = merged_dictionary(ty, pieces, order, inverse)? {
540 return Ok(merged);
541 }
542 if let Some(inverse) = inverse {
543 if let Some(placed) = placed_strings(ty, pieces, inverse, 0..rows)? {
544 return Ok(placed);
545 }
546 if let Some(placed) = placed_fixed(ty, pieces, inverse)? {
547 return Ok(placed);
548 }
549 }
550 let mut data = data_for(ty, rows)?;
551 if matches!(data, Data::Empty) {
554 return Ok(Vector::constant(ty.clone(), Value::Null, order.len()));
555 }
556 let mut arenas = arenas_of(pieces);
557 if let Data::Varlen(column) = &mut data {
560 column.reserve_bytes(arenas.bytes());
561 }
562 let mut masks = Vec::with_capacity(pieces.len());
565 for piece in pieces {
566 let flat = piece.flatten()?;
570 let from = flat.data().ok_or_else(|| Error::internal("a flattened vector with no data"))?;
571 let appended = extend(&mut data, from, &mut arenas)?;
572 if appended != piece.len() {
573 return Err(Error::internal(format!(
574 "a piece of {} rows laid {appended} values end to end",
575 piece.len()
576 )));
577 }
578 masks.push((flat.len(), flat.validity().clone()));
579 }
580 let laid = if masks.iter().all(|(_, mask)| matches!(mask, Validity::AllValid)) {
581 Validity::AllValid
582 } else {
583 let mut live = Vec::with_capacity(rows);
584 for (len, mask) in &masks {
585 live.extend((0..*len).map(|row| mask.is_valid(row)));
588 }
589 Validity::from_run(&live)
590 };
591 if laid.count_valid(rows) == 0 {
592 return Ok(Vector::constant(ty.clone(), Value::Null, order.len()));
593 }
594 let validity = match (laid, inverse) {
595 (Validity::AllValid, _) => Validity::AllValid,
596 (laid, Some(inverse)) => {
597 let mut live = vec![false; order.len()];
598 for (row, &to) in inverse.iter().enumerate() {
599 if let Some(slot) = live.get_mut(to as usize) {
600 *slot = laid.is_valid(row);
601 }
602 }
603 Validity::from_run(&live)
604 }
605 (laid, None) => Validity::from_iter(order.len(), |row| {
606 order.get(row).is_some_and(|&index| laid.is_valid(index))
607 }),
608 };
609 if let Data::Varlen(column) = data {
610 let (views, arena) = column.into_parts();
611 let gathered = match inverse {
612 Some(inverse) => {
613 let mut placed = vec![StringView::empty(); order.len()];
614 for (view, &to) in views.iter().zip(inverse) {
615 if let Some(slot) = placed.get_mut(to as usize) {
616 *slot = *view;
617 }
618 }
619 placed
620 }
621 None => order
622 .iter()
623 .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
624 .collect(),
625 };
626 return Ok(
627 Vector::string_views(ty.clone(), gathered, Arc::new(arena))?.with_validity(validity)
628 );
629 }
630 let data = match inverse {
631 Some(inverse) => placed_of(&data, inverse),
632 None => copy_of(&data, order),
633 };
634 Ok(Vector::flat(ty.clone(), data)?.with_validity(validity))
635}
636
637fn placed_fixed(ty: &LogicalType, pieces: &[Vector], inverse: &[u32]) -> Result<Option<Vector>> {
649 let rows = inverse.len();
650 let mut live: Option<Vec<bool>> = None;
651 let mut base = 0;
652 let mut mark = |mask: &Validity, places: &[u32]| {
654 if matches!(mask, Validity::AllValid) {
655 return;
656 }
657 let live = live.get_or_insert_with(|| vec![true; rows]);
658 for (row, &to) in places.iter().enumerate() {
659 if let Some(slot) = live.get_mut(to as usize) {
660 *slot = mask.is_valid(row);
661 }
662 }
663 };
664 macro_rules! placed {
665 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
666 match data_for(ty, 0)? {
667 $(Data::$variant(_) => {
668 let mut out: Vec<$native> = vec![$zero; rows];
669 for piece in pieces {
670 let len = piece.len();
671 let places = inverse.get(base..base + len).ok_or_else(|| {
672 Error::internal("pieces longer than the places they are written to")
673 })?;
674 base += len;
675 let coded = piece.dictionary_parts().and_then(|(codes, values)| {
676 match (values.form(), values.validity(), values.data()) {
677 (Form::Flat, Validity::AllValid, Some(Data::$variant(held))) => {
678 Some((codes, held.as_slice()))
679 }
680 _ => None,
681 }
682 });
683 if let Some((codes, held)) = coded {
684 for (&code, &to) in codes.iter().zip(places) {
685 if let (Some(slot), Some(value)) =
686 (out.get_mut(to as usize), held.get(code as usize))
687 {
688 *slot = *value;
689 }
690 }
691 mark(piece.validity(), places);
692 continue;
693 }
694 let flat;
696 let piece = if piece.form() == Form::Flat {
697 piece
698 } else {
699 flat = piece.flatten()?;
702 &flat
703 };
704 let Some(Data::$variant(values)) = piece.data() else {
705 return Err(Error::internal(format!(
706 "a piece of {} laid into a column of {ty}",
707 piece.logical_type()
708 )));
709 };
710 if values.len() != len {
711 return Err(Error::internal(format!(
712 "a piece of {len} rows holds {} values",
713 values.len()
714 )));
715 }
716 for (value, &to) in values.iter().zip(places) {
717 if let Some(slot) = out.get_mut(to as usize) {
718 *slot = *value;
719 }
720 }
721 mark(piece.validity(), places);
722 }
723 let validity = match live {
724 None => Validity::AllValid,
725 Some(live) if !live.contains(&true) => {
726 return Ok(Some(Vector::constant(ty.clone(), Value::Null, rows)));
727 }
728 Some(live) => Validity::from_run(&live),
729 };
730 let data = Data::$variant(Buffer::from_vec(out));
731 Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity)))
732 })+
733 _ => Ok(None),
734 }
735 };
736 }
737 crate::for_each_layout!(fixed, placed)
738}
739
740fn placed_strings(
755 ty: &LogicalType,
756 pieces: &[Vector],
757 inverse: &[u32],
758 range: Range<usize>,
759) -> Result<Option<Vector>> {
760 if !strings_placeable(ty, pieces) {
761 return Ok(None);
762 }
763 let first = range.start;
764 let rows = range.len();
765 let local = |to: u32| (to as usize).checked_sub(first).filter(|&at| at < rows);
767 let mut offsets = vec![0u64; rows + 1];
768 let mut places = inverse.iter();
769 for piece in pieces {
770 let (views, _) = piece.text_parts().unwrap_or_default();
771 for (view, &to) in views.iter().zip(places.by_ref()) {
772 if view.is_inline() {
773 continue;
774 }
775 if let Some(slot) = local(to).and_then(|at| offsets.get_mut(at + 1)) {
776 *slot = view.len() as u64;
777 }
778 }
779 }
780 let mut total = 0;
781 for offset in &mut offsets {
782 total += *offset;
783 *offset = total;
784 }
785 let mut arena =
786 vec![0u8; usize::try_from(total).map_err(|_| Error::internal("an arena too large"))?];
787 let mut placed = vec![StringView::empty(); rows];
788 let mut live = vec![true; rows];
789 let mut places = inverse.iter();
790 for piece in pieces {
791 let (views, from) = piece.text_parts().unwrap_or_default();
792 let validity = piece.validity();
793 for (row, (view, &to)) in views.iter().zip(places.by_ref()).enumerate() {
794 let Some(to) = local(to) else {
795 continue;
796 };
797 if !validity.is_valid(row) {
798 if let Some(slot) = live.get_mut(to) {
799 *slot = false;
800 }
801 continue;
802 }
803 let (Some(bytes), Some(&at), Some(slot)) =
804 (view.bytes_in(from), offsets.get(to), placed.get_mut(to))
805 else {
806 continue;
807 };
808 if view.is_inline() {
809 *slot = *view;
810 continue;
811 }
812 if let Some(into) = arena.get_mut(at as usize..at as usize + bytes.len()) {
813 into.copy_from_slice(bytes);
814 }
815 *slot = StringView::over(bytes, at);
816 }
817 }
818 let validity = if live.iter().all(|&valid| valid) {
819 Validity::AllValid
820 } else {
821 Validity::from_run(&live)
822 };
823 let vector = Vector::string_views(ty.clone(), placed, Arc::new(Buffer::from_vec(arena)))?;
824 Ok(Some(vector.with_validity(validity)))
825}
826
827#[must_use]
830pub fn strings_placeable(ty: &LogicalType, pieces: &[Vector]) -> bool {
831 matches!(ty, LogicalType::Varchar | LogicalType::Blob)
832 && pieces.iter().all(|piece| piece.text_parts().is_some())
833}
834
835pub fn placed_string_rows(
847 ty: &LogicalType,
848 pieces: &[Vector],
849 inverse: &[u32],
850 range: Range<usize>,
851) -> Result<Vector> {
852 let rows: usize = pieces.iter().map(Vector::len).sum();
853 if inverse.len() != rows || range.end > rows || range.start > range.end {
854 return Err(Error::internal(format!(
855 "rows {range:?} of {} places for {rows} rows",
856 inverse.len()
857 )));
858 }
859 placed_strings(ty, pieces, inverse, range)?
860 .ok_or_else(|| Error::internal("a string column placed that is not flat views"))
861}
862
863const ROWS_PER_MERGED_ENTRY: usize = 8;
872
873fn merged_dictionary(
883 ty: &LogicalType,
884 pieces: &[Vector],
885 order: &[usize],
886 inverse: Option<&[u32]>,
887) -> Result<Option<Vector>> {
888 if !matches!(ty, LogicalType::Varchar | LogicalType::Blob) || pieces.is_empty() {
889 return Ok(None);
890 }
891 let rows: usize = pieces.iter().map(Vector::len).sum();
892 let mut dictionaries: Vec<&Arc<Vector>> = Vec::new();
893 let mut which = Vec::with_capacity(pieces.len());
894 let mut entries = 0;
895 for piece in pieces {
896 let Some((_, values)) = piece.shared_dictionary_parts() else {
897 return Ok(None);
898 };
899 if !matches!(piece.validity(), Validity::AllValid) {
900 return Ok(None);
901 }
902 let at = match dictionaries.iter().position(|seen| Arc::ptr_eq(seen, values)) {
903 Some(at) => at,
904 None => {
905 entries += values.len();
906 if entries.saturating_mul(ROWS_PER_MERGED_ENTRY) > rows {
907 return Ok(None);
908 }
909 dictionaries.push(values);
910 dictionaries.len() - 1
911 }
912 };
913 which.push(at);
914 }
915 let mut merged: HashMap<Option<&[u8]>, u32> = HashMap::new();
917 let mut values = Vec::new();
918 let mut remaps = Vec::with_capacity(dictionaries.len());
919 for dictionary in &dictionaries {
920 let mut remap = Vec::with_capacity(dictionary.len());
921 for entry in 0..dictionary.len() {
924 let next = u32::try_from(values.len())
925 .map_err(|_| Error::internal("a merged dictionary past four billion entries"))?;
926 let code = *merged.entry(dictionary.bytes_at(entry)).or_insert_with(|| {
927 values.push(dictionary.value_at(entry));
928 next
929 });
930 remap.push(code);
931 }
932 remaps.push(remap);
933 }
934 let mut laid = Vec::with_capacity(rows);
935 for (piece, &at) in pieces.iter().zip(&which) {
936 let (codes, _) = piece
937 .dictionary_parts()
938 .ok_or_else(|| Error::internal("a dictionary piece lost its dictionary"))?;
939 let remap = &remaps[at];
940 laid.extend(codes.iter().map(|&code| remap[code as usize]));
941 }
942 let codes = match inverse {
945 Some(inverse) => {
946 let mut codes = vec![0u32; order.len()];
947 for (&code, &to) in laid.iter().zip(inverse) {
948 if let Some(slot) = codes.get_mut(to as usize) {
949 *slot = code;
950 }
951 }
952 codes
953 }
954 None => order.iter().map(|&index| laid[index]).collect(),
955 };
956 let values = Vector::from_values(ty.clone(), &values)?;
957 Ok(Some(Vector::stable_dictionary(codes, Arc::new(values))?))
958}
959
960fn run_of(pieces: &[&Vector], rows: usize) -> Validity {
966 if pieces.iter().all(|piece| matches!(piece.validity(), Validity::AllValid)) {
967 return Validity::AllValid;
968 }
969 if pieces.iter().all(|piece| matches!(piece.validity(), Validity::AllInvalid)) {
970 return Validity::AllInvalid;
971 }
972 let mut live = Vec::with_capacity(rows);
973 for piece in pieces {
974 for row in 0..piece.len() {
977 live.push(!piece.is_null_at(row));
978 }
979 }
980 Validity::from_run(&live)
981}
982
983fn straight(at: &[usize]) -> bool {
985 at.iter().enumerate().all(|(row, &index)| row == index)
986}
987
988fn arenas_of<V: AsRef<Vector>>(pieces: &[V]) -> Arenas {
990 let mut arenas = Arenas::default();
991 for piece in pieces {
992 if let Some(Data::Varlen(column)) = piece.as_ref().data() {
993 arenas.count(column);
994 }
995 }
996 arenas
997}
998
999fn adjoined(pieces: &[&Vector]) -> Option<Data> {
1006 macro_rules! joined {
1007 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1008 match pieces.first()?.data()? {
1009 $(Data::$variant(first) => {
1010 if !first.is_shared() {
1011 return None;
1012 }
1013 let mut run = first.clone();
1014 for piece in &pieces[1..] {
1015 let Some(Data::$variant(next)) = piece.data() else { return None };
1016 run = run.joined(next)?;
1017 }
1018 Some(Data::$variant(run))
1019 })+
1020 Data::Varlen(first) => {
1021 if !first.is_paged() {
1022 return None;
1023 }
1024 let mut run = first.clone();
1025 for piece in &pieces[1..] {
1026 let Some(Data::Varlen(next)) = piece.data() else { return None };
1027 run = run.joined(next)?;
1028 }
1029 Some(Data::Varlen(run))
1030 }
1031 _ => None,
1032 }
1033 };
1034 }
1035 crate::for_each_layout!(fixed, joined)
1036}
1037
1038fn extend(into: &mut Data, from: &Data, arenas: &mut Arenas) -> Result<usize> {
1044 macro_rules! extended {
1045 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1046 match (&mut *into, from) {
1047 (_, Data::Empty) => Ok(0),
1050 $((Data::$variant(out), Data::$variant(values)) => {
1051 out.extend_from_slice(values.as_slice());
1052 Ok(values.len())
1053 })+
1054 (Data::Varlen(out), Data::Varlen(values)) => {
1057 out.push_column(values, arenas);
1058 Ok(values.len())
1059 }
1060 (out, from) => Err(Error::internal(format!(
1061 "a run of {:?} values cannot be laid after a run of {:?} ones",
1062 layout_of(from),
1063 layout_of(out)
1064 ))),
1065 }
1066 };
1067 }
1068 crate::for_each_layout!(fixed, extended)
1069}
1070
1071#[cfg(test)]
1079mod tests {
1080 use super::*;
1081 use crate::{Chunk, Form};
1082
1083 fn values(vector: &Vector) -> Vec<Value> {
1085 (0..vector.len()).map(|row| vector.value_at(row)).collect()
1086 }
1087
1088 fn scattered(ty: &LogicalType, rows: usize, pieces: &[(Vec<u32>, Vector)]) -> Vector {
1093 let mut answers = vec![Value::Null; rows];
1094 for (positions, piece) in pieces {
1095 for (slot, &row) in positions.iter().enumerate() {
1096 answers[row as usize] = piece.value_at(slot);
1097 }
1098 }
1099 Vector::from_values(ty.clone(), &answers).expect("the reference builds")
1100 }
1101
1102 fn agrees(ty: &LogicalType, rows: usize, pieces: &[(Vec<u32>, Vector)]) -> Vector {
1104 let mut assembly = Assembly::new(ty.clone(), rows).expect("an assembly of this type");
1105 for (positions, piece) in pieces {
1106 assembly.place(positions, piece).expect("the piece is placed");
1107 }
1108 let built = assembly.finish().expect("the assembly finishes");
1109 assert_eq!(built.len(), rows, "an assembly of {rows} rows");
1110 assert_eq!(values(&built), values(&scattered(ty, rows, pieces)), "against the slow way");
1111 built
1112 }
1113
1114 #[test]
1115 fn two_pieces_interleave_back_into_the_order_the_rows_came_in() {
1116 let evens = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(0), Value::BigInt(2)])
1117 .expect("a vector");
1118 let odds = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1), Value::BigInt(3)])
1119 .expect("a vector");
1120 let built = agrees(&LogicalType::BigInt, 4, &[(vec![0, 2], evens), (vec![1, 3], odds)]);
1121 assert_eq!(
1122 values(&built),
1123 vec![Value::BigInt(0), Value::BigInt(1), Value::BigInt(2), Value::BigInt(3)]
1124 );
1125 }
1126
1127 #[test]
1128 fn a_row_no_piece_claims_is_null() {
1129 let piece =
1132 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(7)]).expect("a vector");
1133 let built = agrees(&LogicalType::BigInt, 3, &[(vec![1], piece)]);
1134 assert_eq!(values(&built), vec![Value::Null, Value::BigInt(7), Value::Null]);
1135 }
1136
1137 #[test]
1138 fn no_pieces_at_all_is_a_column_of_nulls_of_the_right_length() {
1139 let built = agrees(&LogicalType::Integer, 5, &[]);
1140 assert!(built.is_null_at(4), "every row of it is null");
1141 }
1142
1143 #[test]
1144 fn a_null_inside_a_piece_stays_null_where_the_piece_put_it() {
1145 let piece = Vector::from_values(
1148 LogicalType::BigInt,
1149 &[Value::BigInt(1), Value::Null, Value::BigInt(3)],
1150 )
1151 .expect("a vector");
1152 let built = agrees(&LogicalType::BigInt, 3, &[(vec![2, 0, 1], piece)]);
1153 assert!(built.is_null_at(0), "the null landed where the piece put it");
1154 assert_eq!(built.value_at(2), Value::BigInt(1));
1155 }
1156
1157 #[test]
1158 fn strings_are_assembled_without_going_through_a_value_each() {
1159 let left = Vector::from_values(
1160 LogicalType::Varchar,
1161 &[Value::Varchar("a short one".into()), Value::Varchar("another".into())],
1162 )
1163 .expect("a vector");
1164 let right = Vector::from_values(
1165 LogicalType::Varchar,
1166 &[Value::Varchar("a string that is far too long to live inline in a view".into())],
1167 )
1168 .expect("a vector");
1169 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 2], left), (vec![1], right)]);
1170 assert_eq!(built.value_at(0), Value::Varchar("a short one".into()));
1171 assert_eq!(
1172 built.value_at(1),
1173 Value::Varchar("a string that is far too long to live inline in a view".into())
1174 );
1175 assert_eq!(built.value_at(2), Value::Varchar("another".into()));
1176 }
1177
1178 #[test]
1179 fn strings_laid_end_to_end_in_order_come_back_as_views_over_the_arena_they_went_into() {
1180 let first = Vector::from_values(
1183 LogicalType::Varchar,
1184 &[Value::Varchar("one".into()), Value::Varchar("two".into())],
1185 )
1186 .expect("a vector");
1187 let second = Vector::from_values(
1188 LogicalType::Varchar,
1189 &[Value::Varchar("a third one long enough to be out of line".into())],
1190 )
1191 .expect("a vector");
1192 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 1], first), (vec![2], second)]);
1193 assert_eq!(built.form(), Form::StringView, "the bytes stay where they were appended");
1194 assert_eq!(
1195 built.value_at(2),
1196 Value::Varchar("a third one long enough to be out of line".into())
1197 );
1198 }
1199
1200 #[test]
1201 fn a_string_row_no_piece_claims_is_null_rather_than_empty() {
1202 let piece = Vector::from_values(
1205 LogicalType::Varchar,
1206 &[Value::Varchar("a value long enough to be out of line".into())],
1207 )
1208 .expect("a vector");
1209 let built = agrees(&LogicalType::Varchar, 3, &[(vec![2], piece)]);
1210 assert_eq!(built.value_at(0), Value::Null);
1211 assert_eq!(built.value_at(1), Value::Null);
1212 assert_eq!(
1213 built.value_at(2),
1214 Value::Varchar("a value long enough to be out of line".into())
1215 );
1216 }
1217
1218 #[test]
1219 fn a_constant_piece_is_written_out_rather_than_read_a_row_at_a_time() {
1220 let arm = Vector::from_values(LogicalType::Varchar, &[Value::Varchar("kept".into())])
1223 .expect("a vector");
1224 let otherwise = Vector::constant(LogicalType::Varchar, Value::Varchar("".into()), 3);
1225 let built = agrees(&LogicalType::Varchar, 4, &[(vec![2], arm), (vec![0, 1, 3], otherwise)]);
1226 assert_eq!(built.value_at(0), Value::Varchar("".into()));
1227 assert_eq!(built.value_at(2), Value::Varchar("kept".into()));
1228 }
1229
1230 #[test]
1231 fn a_dictionary_piece_is_walked_to_its_values() {
1232 let dictionary = Vector::from_values(
1235 LogicalType::Varchar,
1236 &[Value::Varchar("one".into()), Value::Varchar("two".into())],
1237 )
1238 .expect("a dictionary");
1239 let piece = Vector::dictionary(vec![1, 0, 1], dictionary).expect("a dictionary vector");
1240 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 1, 2], piece)]);
1241 assert_eq!(
1242 values(&built),
1243 vec![
1244 Value::Varchar("two".into()),
1245 Value::Varchar("one".into()),
1246 Value::Varchar("two".into())
1247 ]
1248 );
1249 }
1250
1251 #[test]
1252 fn a_piece_placed_at_the_wrong_number_of_positions_is_an_error() {
1253 let piece =
1254 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1)]).expect("a vector");
1255 let mut assembly = Assembly::new(LogicalType::BigInt, 4).expect("an assembly");
1256 assert!(assembly.place(&[0, 1], &piece).is_err(), "two positions for one row");
1257 }
1258
1259 #[test]
1260 fn a_position_past_the_end_is_an_error_rather_than_a_lost_row() {
1261 let piece =
1262 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1)]).expect("a vector");
1263 let mut assembly = Assembly::new(LogicalType::BigInt, 2).expect("an assembly");
1264 assert!(assembly.place(&[9], &piece).is_err(), "a row past the end of the assembly");
1265 }
1266
1267 #[test]
1268 fn a_piece_of_the_wrong_layout_is_an_error_rather_than_a_wrong_answer() {
1269 let piece =
1272 Vector::from_values(LogicalType::Varchar, &[Value::Varchar("x".into())]).expect("text");
1273 let mut assembly = Assembly::new(LogicalType::BigInt, 1).expect("an assembly");
1274 assert!(assembly.place(&[0], &piece).is_err(), "text laid after integers");
1275 }
1276
1277 #[test]
1278 fn every_layout_assembles_the_way_it_scatters() {
1279 let cases: Vec<(LogicalType, Vec<Value>)> = vec![
1282 (LogicalType::Boolean, vec![Value::Boolean(true), Value::Boolean(false)]),
1283 (LogicalType::TinyInt, vec![Value::TinyInt(1), Value::TinyInt(-2)]),
1284 (LogicalType::SmallInt, vec![Value::SmallInt(3), Value::SmallInt(-4)]),
1285 (LogicalType::Integer, vec![Value::Integer(5), Value::Integer(-6)]),
1286 (LogicalType::BigInt, vec![Value::BigInt(7), Value::BigInt(-8)]),
1287 (LogicalType::HugeInt, vec![Value::HugeInt(9), Value::HugeInt(-10)]),
1288 (LogicalType::UTinyInt, vec![Value::UTinyInt(11), Value::UTinyInt(12)]),
1289 (LogicalType::USmallInt, vec![Value::USmallInt(13), Value::USmallInt(14)]),
1290 (LogicalType::UInteger, vec![Value::UInteger(15), Value::UInteger(16)]),
1291 (LogicalType::UBigInt, vec![Value::UBigInt(17), Value::UBigInt(18)]),
1292 (LogicalType::Float, vec![Value::Float(1.5), Value::Float(-2.5)]),
1293 (LogicalType::Double, vec![Value::Double(3.5), Value::Double(-4.5)]),
1294 (
1295 LogicalType::Varchar,
1296 vec![Value::Varchar("first".into()), Value::Varchar("second".into())],
1297 ),
1298 (LogicalType::Date, vec![Value::Date(19), Value::Date(20)]),
1299 ];
1300 for (ty, pair) in cases {
1301 let left = Vector::from_values(ty.clone(), &pair[..1]).expect("a vector");
1302 let right = Vector::from_values(ty.clone(), &pair[1..]).expect("a vector");
1303 let built = agrees(&ty, 2, &[(vec![1], left), (vec![0], right)]);
1304 assert_eq!(built.value_at(0), pair[1], "{ty:?} at row 0");
1305 assert_eq!(built.value_at(1), pair[0], "{ty:?} at row 1");
1306 }
1307 }
1308
1309 #[test]
1310 fn an_assembly_is_a_chunk_column_like_any_other() {
1311 let piece = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1), Value::BigInt(2)])
1314 .expect("a vector");
1315 let built = agrees(&LogicalType::BigInt, 2, &[(vec![1, 0], piece)]);
1316 let chunk = Chunk::new(vec![built]).expect("a chunk of one column");
1317 assert_eq!(chunk.len(), 2, "two rows");
1318 }
1319
1320 fn all_of(pieces: &[Vector]) -> Vec<Value> {
1322 pieces.iter().flat_map(values).collect()
1323 }
1324
1325 fn laid(ty: &LogicalType, pieces: &[Vector]) -> Vector {
1327 let built = concat(ty, pieces).expect("the pieces lay").expect("this run lays");
1328 assert_eq!(built.len(), pieces.iter().map(Vector::len).sum::<usize>(), "the row count");
1329 assert_eq!(values(&built), all_of(pieces), "the values laid end to end");
1330 built
1331 }
1332
1333 #[test]
1334 fn pieces_laid_end_to_end_read_back_in_the_order_they_were_given() {
1335 let piece = |from: i64, to: i64| {
1336 let held: Vec<Value> = (from..to).map(Value::BigInt).collect();
1337 Vector::from_values(LogicalType::BigInt, &held).expect("a run of bigints")
1338 };
1339 let pieces = [piece(0, 4), piece(4, 9), piece(9, 10)];
1340 let built = laid(&LogicalType::BigInt, &pieces);
1341 assert_eq!(built.form(), Form::Flat, "a run of flat pieces lays flat");
1342 let window = built.slice(4, 5).expect("a window into the page");
1345 assert_eq!(values(&window), all_of(&pieces[1..2]), "the second piece, cut back out");
1346 }
1347
1348 #[test]
1351 fn neighbouring_windows_of_one_page_lay_without_a_copy() {
1352 let held: Vec<Value> =
1353 (0..20).map(|at| if at % 7 == 3 { Value::Null } else { Value::BigInt(at) }).collect();
1354 let page = Vector::from_values(LogicalType::BigInt, &held).expect("a run").into_pages();
1355 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1356 let address = |vector: &Vector| match vector.data() {
1357 Some(Data::Int64(run)) => run.as_slice().as_ptr() as usize,
1358 other => panic!("a bigint run laid as {other:?}"),
1359 };
1360 let built = laid(&LogicalType::BigInt, &[cut(2, 5), cut(7, 8), cut(15, 3)]);
1361 assert_eq!(address(&built), address(&page) + 2 * 8, "the neighbours were copied");
1362 let other = Vector::from_values(LogicalType::BigInt, &held).expect("a run").into_pages();
1364 let other_cut = other.slice(7, 3).expect("a window");
1365 for pieces in [
1366 vec![cut(2, 5), cut(8, 3)],
1367 vec![cut(7, 3), cut(2, 5)],
1368 vec![cut(2, 5), other_cut],
1369 vec![Vector::from_values(LogicalType::BigInt, &held[..4]).expect("owned"), cut(4, 2)],
1370 ] {
1371 let built = laid(&LogicalType::BigInt, &pieces);
1372 assert_ne!(address(&built), address(&page) + 2 * 8, "a copy was expected");
1373 }
1374 }
1375
1376 #[test]
1379 fn neighbouring_cuts_of_a_paged_string_column_lay_without_a_copy() {
1380 let held: Vec<Value> = (0..20)
1381 .map(|at| Value::Varchar(format!("a string long enough for the arena {at}")))
1382 .collect();
1383 let page = Vector::from_values(LogicalType::Varchar, &held).expect("a run").into_pages();
1384 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1385 let views = |vector: &Vector| match vector.data() {
1386 Some(Data::Varlen(column)) => column.views().as_ptr() as usize,
1387 other => panic!("a varchar run laid as {other:?}"),
1388 };
1389 let built = laid(&LogicalType::Varchar, &[cut(2, 5), cut(7, 8), cut(15, 3)]);
1390 assert_eq!(views(&built), views(&page) + 2 * size_of::<StringView>(), "views copied");
1391 let owned = Vector::from_values(LogicalType::Varchar, &held).expect("a run");
1392 let copied = laid(&LogicalType::Varchar, &[owned.slice(0, 4).expect("a cut"), cut(4, 2)]);
1393 assert_eq!(copied.len(), 6);
1394 }
1395
1396 #[test]
1397 fn a_null_in_a_piece_is_a_null_in_the_same_row_of_the_page() {
1398 let ty = LogicalType::Integer;
1399 let whole = Vector::from_values(ty.clone(), &[Value::Integer(1), Value::Integer(2)])
1400 .expect("no nulls");
1401 let holed =
1402 Vector::from_values(ty.clone(), &[Value::Null, Value::Integer(4)]).expect("one null");
1403 let built = laid(&ty, &[whole.clone(), holed.clone()]);
1404 assert!(!built.is_null_at(1), "a row that was not null became one");
1405 assert!(built.is_null_at(2), "the null did not come through");
1406 let clean = laid(&ty, &[whole.clone(), whole]);
1408 assert_eq!(clean.validity(), &Validity::AllValid, "a mask nothing needed");
1409 let empty = laid(&ty, &[holed.clone(), holed]);
1410 assert!(empty.is_null_at(0) && empty.is_null_at(2), "both nulls came through");
1411 }
1412
1413 #[test]
1415 fn strings_lay_into_one_arena_and_come_back_as_views() {
1416 let ty = LogicalType::Varchar;
1417 let word = |text: &str| {
1418 Vector::from_values(ty.clone(), &[Value::Varchar(text.to_string())]).expect("a string")
1419 };
1420 let pieces = [word("a string too long to sit inside a view"), word("short")];
1421 let built = laid(&ty, &pieces);
1422 assert_eq!(
1423 built.form(),
1424 Form::StringView,
1425 "a varchar page that is not views cuts by copying"
1426 );
1427 let window = built.slice(0, 1).expect("a window into the page");
1428 assert_eq!(values(&window), all_of(&pieces[..1]), "the long string, cut back out");
1429 }
1430
1431 #[test]
1432 fn stable_dictionary_pieces_sharing_values_lay_as_codes() {
1433 let ty = LogicalType::Varchar;
1434 let values = Arc::new(
1435 Vector::from_values(
1436 ty.clone(),
1437 &[Value::Varchar("a".to_string()), Value::Varchar("b".to_string())],
1438 )
1439 .expect("dictionary values"),
1440 );
1441 let first = Vector::stable_dictionary(vec![1, 0], Arc::clone(&values)).expect("codes");
1442 let second = Vector::stable_dictionary(vec![1], Arc::clone(&values)).expect("codes");
1443 let built = concat(&ty, &[first, second]).expect("no error").expect("shared codes lay");
1444 let (codes, held) = built.stable_dictionary_parts().expect("the stable form survives");
1445 assert_eq!(codes, &[1, 0, 1]);
1446 assert!(Arc::ptr_eq(held, &values));
1447 }
1448
1449 #[test]
1451 fn an_encoded_piece_is_left_alone_rather_than_flattened() {
1452 let ty = LogicalType::BigInt;
1453 let flat = Vector::from_values(ty.clone(), &[Value::BigInt(1)]).expect("a flat piece");
1454 let values = Vector::from_values(ty.clone(), &[Value::BigInt(7), Value::BigInt(8)])
1455 .expect("two distinct values");
1456 let coded = Vector::dictionary(vec![0, 1, 0], values).expect("a dictionary piece");
1457 let one = std::slice::from_ref(&coded);
1458 assert!(concat(&ty, one).expect("no error").is_none(), "a dictionary laid");
1459 assert!(
1460 concat(&ty, &[flat.clone(), coded]).expect("no error").is_none(),
1461 "a mixed run laid"
1462 );
1463 assert!(
1464 concat::<Vector>(&ty, &[]).expect("no error").is_none(),
1465 "nothing laid into something"
1466 );
1467 let other =
1470 Vector::from_values(LogicalType::Integer, &[Value::Integer(1)]).expect("an int");
1471 assert!(concat(&ty, &[flat, other]).expect("no error").is_none(), "two types laid");
1472 }
1473
1474 fn on_a_thread_each(count: usize, task: &(dyn Fn(usize) + Sync)) -> Result<()> {
1481 std::thread::scope(|scope| {
1482 let running: Vec<_> =
1483 (0..count).rev().map(|at| scope.spawn(move || task(at))).collect();
1484 for thread in running {
1485 thread.join().expect("a piece copier panicked");
1486 }
1487 });
1488 Ok(())
1489 }
1490
1491 fn owned_strings(pieces: usize, each: usize) -> Vec<Vector> {
1496 (0..pieces)
1497 .map(|piece| {
1498 let held: Vec<Value> = (0..each)
1499 .map(|row| match (piece + row) % 4 {
1500 0 => Value::Null,
1501 1 => Value::Varchar(format!("short {row}")),
1502 _ => Value::Varchar(format!(
1503 "a string of piece {piece} row {row} that is well past twelve bytes"
1504 )),
1505 })
1506 .collect();
1507 Vector::from_values(LogicalType::Varchar, &held).expect("a run of strings")
1508 })
1509 .collect()
1510 }
1511
1512 #[test]
1513 fn string_pieces_laid_on_many_threads_hold_the_same_strings_as_laid_on_one() {
1514 let ty = LogicalType::Varchar;
1515 let pieces = owned_strings(9, 7);
1516 let borrowed: Vec<&Vector> = pieces.iter().collect();
1520 assert!(apart(&ty, &borrowed).is_some(), "the parallel lay declined its own case");
1521 let serial = concat(&ty, &pieces).expect("no error").expect("owned arenas lay");
1522 let parallel = concat_on(&ty, &pieces, &on_a_thread_each)
1523 .expect("no error")
1524 .expect("owned arenas lay");
1525 assert_eq!(parallel.len(), serial.len(), "the row count");
1526 assert_eq!(values(¶llel), all_of(&pieces), "the values laid end to end");
1527 assert_eq!(values(¶llel), values(&serial), "the two paths disagree");
1528 assert_eq!(parallel.form(), serial.form(), "a different body came out");
1531 }
1532
1533 #[test]
1535 fn a_run_the_parallel_lay_does_not_own_is_left_to_the_serial_one() {
1536 let ty = LogicalType::Varchar;
1537 let pieces = owned_strings(3, 5);
1538 assert!(apart(&ty, &[&pieces[0]]).is_none(), "one piece was taken");
1539 let page = concat(&ty, &pieces).expect("no error").expect("a page").into_pages();
1542 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1543 let cuts = [cut(0, 4), cut(4, 6), cut(10, 5)];
1544 let borrowed: Vec<&Vector> = cuts.iter().collect();
1545 assert!(apart(&ty, &borrowed).is_none(), "cuts of one page were taken");
1546 let serial = concat(&ty, &cuts).expect("no error").expect("shared views lay");
1549 let parallel =
1550 concat_on(&ty, &cuts, &on_a_thread_each).expect("no error").expect("shared views");
1551 assert_eq!(values(¶llel), values(&serial), "the fall through changed the answer");
1552 }
1553
1554 #[test]
1557 fn a_piece_holding_more_arena_than_it_reads_is_left_to_the_serial_lay() {
1558 let ty = LogicalType::Varchar;
1559 let pieces = owned_strings(2, 8);
1560 let page = concat(&ty, &pieces).expect("no error").expect("a page");
1561 let thin = page.slice(2, 1).expect("a window").flatten().expect("flattened");
1564 let fat = page.slice(3, 1).expect("a window").flatten().expect("flattened");
1565 let held = [thin, fat];
1566 let borrowed: Vec<&Vector> = held.iter().collect();
1567 if borrowed.iter().all(|piece| match piece.data() {
1568 Some(Data::Varlen(column)) => !column.mostly_read(),
1569 _ => false,
1570 }) {
1571 assert!(apart(&ty, &borrowed).is_none(), "a mostly unread arena was taken");
1572 }
1573 let serial = concat(&ty, &held).expect("no error").expect("flat pieces lay");
1574 let parallel =
1575 concat_on(&ty, &held, &on_a_thread_each).expect("no error").expect("flat pieces");
1576 assert_eq!(values(¶llel), values(&serial), "the two paths disagree");
1577 }
1578
1579 #[test]
1582 fn an_interleave_reads_the_pieces_in_the_order_it_is_given() {
1583 let words: Vec<Value> = ["a long enough word to leave the inline view", "b", "c"]
1584 .iter()
1585 .map(|word| Value::Varchar((*word).to_string()))
1586 .collect();
1587 let dictionary = Vector::from_values(LogicalType::Varchar, &words).expect("words");
1588 let strings = [
1589 Vector::dictionary(vec![2, 0, 1], dictionary).expect("a dictionary"),
1590 Vector::from_values(
1591 LogicalType::Varchar,
1592 &[Value::Null, Value::Varchar("another string past twelve bytes".to_string())],
1593 )
1594 .expect("flat"),
1595 ];
1596 let numbers = [
1597 Vector::from_values(
1598 LogicalType::BigInt,
1599 &[Value::BigInt(7), Value::Null, Value::BigInt(9)],
1600 )
1601 .expect("flat"),
1602 Vector::constant(LogicalType::BigInt, Value::BigInt(4), 1),
1603 Vector::constant(LogicalType::BigInt, Value::Null, 1),
1604 ];
1605 let lists = [
1606 Vector::from_values(
1607 LogicalType::List(Box::new(LogicalType::Integer)),
1608 &[
1609 Value::List { element: LogicalType::Integer, values: vec![Value::Integer(1)] },
1610 Value::Null,
1611 Value::List { element: LogicalType::Integer, values: vec![] },
1612 ],
1613 )
1614 .expect("lists"),
1615 Vector::from_values(
1616 LogicalType::List(Box::new(LogicalType::Integer)),
1617 &[
1618 Value::List {
1619 element: LogicalType::Integer,
1620 values: vec![Value::Integer(2), Value::Integer(3)],
1621 },
1622 Value::Null,
1623 ],
1624 )
1625 .expect("lists"),
1626 ];
1627 let order = [4, 0, 3, 1, 2, 3];
1628 for pieces in [&strings[..], &numbers[..], &lists[..]] {
1629 let ty = pieces[0].logical_type().clone();
1630 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
1631 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
1632 let got = interleave(&ty, pieces, &order).expect("an interleave");
1633 assert_eq!(values(&got), expected, "{ty}");
1634 }
1635 assert!(interleave(&LogicalType::BigInt, &numbers, &[5]).is_err(), "row 5 of 5 rows");
1636 let order = [4, 0, 3, 1, 2];
1639 let mut inverse = [0u32; 5];
1640 for (at, &row) in order.iter().enumerate() {
1641 inverse[row] = at as u32;
1642 }
1643 let texts: Vec<Value> = ["a string past the twelve bytes of a view", "short", "x"]
1644 .iter()
1645 .map(|text| Value::Varchar((*text).to_string()))
1646 .chain([Value::Varchar("another long string for the arena".to_string())])
1647 .collect();
1648 let valid = [
1649 Vector::from_values(LogicalType::Varchar, &texts[..2]).expect("flat"),
1650 Vector::from_values(LogicalType::Varchar, &texts[2..]).expect("flat"),
1651 Vector::constant(LogicalType::Varchar, Value::Varchar("one more".to_string()), 1),
1652 ];
1653 for pieces in [&strings[..], &numbers[..], &lists[..], &valid[..]] {
1654 let ty = pieces[0].logical_type().clone();
1655 let pulled = interleave(&ty, pieces, &order).expect("an interleave");
1656 let pushed =
1657 interleave_placed(&ty, pieces, &order, Some(&inverse)).expect("a placed one");
1658 assert_eq!(values(&pushed), values(&pulled), "{ty}");
1659 }
1660 assert!(
1661 interleave_placed(&LogicalType::BigInt, &numbers, &order, Some(&inverse[..4])).is_err(),
1662 "four places for five rows"
1663 );
1664 let untyped = [Vector::constant(LogicalType::Null, Value::Null, 3)];
1665 let got = interleave(&LogicalType::Null, &untyped, &[2, 0]).expect("an untyped null");
1666 assert_eq!(values(&got), vec![Value::Null, Value::Null]);
1667 }
1668
1669 #[test]
1672 fn a_fixed_width_column_is_written_to_its_places_from_pieces_of_any_form() {
1673 let ty = LogicalType::BigInt;
1674 let int = Value::BigInt;
1675 let flat = Vector::from_values(ty.clone(), &[int(1), Value::Null, int(3)]).expect("flat");
1676 let paged = Vector::from_values(ty.clone(), &[int(4), int(5)]).expect("flat").into_pages();
1677 let words = Vector::from_values(ty.clone(), &[int(70), int(80)]).expect("values");
1678 let coded = Vector::dictionary(vec![1, 0, 1], words).expect("coded");
1679 let nulled = Vector::from_values(ty.clone(), &[int(90), Value::Null]).expect("values");
1680 let chained = Vector::dictionary(vec![1, 0], nulled).expect("coded over nulls");
1681 let constant = Vector::constant(ty.clone(), int(6), 2);
1682 let pieces = [flat, paged, coded, chained, constant];
1683 let rows: usize = pieces.iter().map(Vector::len).sum();
1684 let order: Vec<usize> = (0..rows).map(|at| (at * 5 + 3) % rows).collect();
1685 let mut inverse = vec![0u32; rows];
1686 for (to, &from) in order.iter().enumerate() {
1687 inverse[from] = u32::try_from(to).expect("a small row");
1688 }
1689 let read = interleave_placed(&ty, &pieces, &order, None).expect("read through order");
1690 let written =
1691 interleave_placed(&ty, &pieces, &order, Some(&inverse)).expect("written to places");
1692 assert_eq!(values(&written), values(&read));
1693 assert_eq!(values(&written)[inverse[1] as usize], Value::Null, "the flat piece's null");
1694 assert_eq!(values(&written)[inverse[8] as usize], Value::Null, "the dictionary's null");
1695
1696 let nothing = Vector::from_values(ty.clone(), &[Value::Null, Value::Null]).expect("nulls");
1697 let written = interleave_placed(&ty, &[nothing], &[1, 0], Some(&[1, 0])).expect("nulls");
1698 assert_eq!(values(&written), [Value::Null, Value::Null]);
1699 }
1700
1701 #[test]
1702 fn placed_strings_are_laid_in_the_order_of_the_result() {
1703 let word = |text: &str| Value::Varchar(text.to_string());
1704 let flat = Vector::from_values(
1705 LogicalType::Varchar,
1706 &[word("the first string past twelve bytes"), Value::Null, word("short")],
1707 )
1708 .expect("flat");
1709 let arena = b"xxa second string past twelve bytesyy".to_vec();
1710 let views = vec![StringView::over(&arena[2..35], 2), StringView::inline("tiny")];
1711 let viewed =
1712 Vector::string_views(LogicalType::Varchar, views, Arc::new(Buffer::from_vec(arena)))
1713 .expect("views");
1714 let pieces = [flat, viewed];
1715 let order = [3, 0, 4, 2, 1];
1716 let mut inverse = vec![0u32; order.len()];
1717 for (to, &from) in order.iter().enumerate() {
1718 inverse[from] = u32::try_from(to).expect("a small row");
1719 }
1720 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
1721 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
1722 let got = interleave_placed(&LogicalType::Varchar, &pieces, &order, Some(&inverse))
1723 .expect("a placed interleave");
1724 assert_eq!(values(&got), expected);
1725 let (_, arena) = got.text_parts().expect("views");
1726 assert_eq!(
1727 arena, b"a second string past twelve bytesthe first string past twelve bytes",
1728 "the long strings in the order they come out, and nothing else"
1729 );
1730 assert!(strings_placeable(&LogicalType::Varchar, &pieces));
1731 for split in 0..=order.len() {
1732 let mut joined = Vec::new();
1733 for range in [0..split, split..order.len()] {
1734 let part = placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, range)
1735 .expect("a range of rows");
1736 joined.extend(values(&part));
1737 }
1738 assert_eq!(joined, expected, "split at {split}");
1739 }
1740 let (_, arena) = placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, 1..3)
1741 .expect("the middle rows")
1742 .text_parts()
1743 .map(|(views, arena)| (views.len(), arena.to_vec()))
1744 .expect("views");
1745 assert_eq!(arena, b"the first string past twelve bytes", "only the range's own strings");
1746 assert!(placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, 4..6).is_err());
1747 }
1748
1749 #[test]
1750 fn an_interleave_of_dictionaries_merges_them_into_one() {
1751 let word = |text: &str| Value::Varchar(text.to_string());
1752 let first = [word("MAIL"), word("a word long enough to leave the inline view")];
1753 let second = [Value::Null, word("MAIL"), word("SHIP")];
1754 let first = Arc::new(Vector::from_values(LogicalType::Varchar, &first).expect("words"));
1755 let second = Arc::new(Vector::from_values(LogicalType::Varchar, &second).expect("words"));
1756 let over = |codes: Vec<u32>, dictionary: &Arc<Vector>| {
1757 Vector::dictionary_over(codes, Arc::clone(dictionary)).expect("a dictionary")
1758 };
1759 let pieces = [
1760 over((0..16).map(|row| row % 2).collect(), &first),
1761 over((0..16).map(|row| row % 3).collect(), &second),
1762 over(vec![1; 8], &first),
1763 ];
1764 let order: Vec<usize> = (0..40).rev().collect();
1765 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
1766 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
1767 let got = interleave(&LogicalType::Varchar, &pieces, &order).expect("an interleave");
1768 assert_eq!(values(&got), expected);
1769 let (_, merged) = got.stable_dictionary_parts().expect("one stable dictionary");
1770 assert_eq!(merged.len(), 4, "MAIL once, the long word, the null and SHIP");
1771 let mut inverse = vec![0u32; order.len()];
1772 for (to, &from) in order.iter().enumerate() {
1773 inverse[from] = u32::try_from(to).expect("a small row");
1774 }
1775 let placed = interleave_placed(&LogicalType::Varchar, &pieces, &order, Some(&inverse))
1776 .expect("a placed interleave");
1777 assert_eq!(values(&placed), expected, "placed codes land where pulled ones do");
1778 assert!(placed.stable_dictionary_parts().is_some(), "and stay one dictionary");
1779
1780 let mixed = [pieces[0].clone(), pieces[1].flatten().expect("flat")];
1781 let got = interleave(&LogicalType::Varchar, &mixed, &order[8..]).expect("an interleave");
1782 assert!(got.dictionary_parts().is_none(), "a flat piece gathers flat");
1783 let few = &pieces[..1];
1784 let got = interleave(&LogicalType::Varchar, few, &[3, 2]).expect("an interleave");
1785 assert_eq!(
1786 values(&got),
1787 vec![word("a word long enough to leave the inline view"), word("MAIL")]
1788 );
1789 }
1790}