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 picked(
259 ty: &LogicalType,
260 sources: &[&Vector],
261 picks: &[(u32, u32)],
262) -> Result<Option<Vector>> {
263 if let Some(codes) = picked_codes(sources, picks)? {
264 return Ok(Some(codes));
265 }
266 let mut leaves: Vec<(&Vector, Option<&[u32]>)> = Vec::with_capacity(sources.len());
268 for source in sources {
269 match source.form() {
270 Form::Flat => leaves.push((source, None)),
271 Form::Dictionary => match source.dictionary_parts() {
272 Some((codes, values)) if values.form() == Form::Flat => {
273 leaves.push((values, Some(codes)));
274 }
275 _ => return Ok(None),
276 },
277 _ => return Ok(None),
278 }
279 }
280 let mut datas = Vec::with_capacity(leaves.len());
281 for (leaf, _) in &leaves {
282 let Some(data) = leaf.data() else { return Ok(None) };
283 datas.push(data);
284 }
285 let mut live = Vec::with_capacity(picks.len());
288 let picks: Vec<(u32, u32)> = picks
289 .iter()
290 .map(|&(source, row)| {
291 let found = sources.get(source as usize).zip(leaves.get(source as usize)).and_then(
292 |(held, (leaf, codes))| {
293 let row = row as usize;
294 if row >= held.len() || !held.validity().is_valid(row) {
295 return None;
296 }
297 let at =
298 codes.map_or(Some(row), |codes| codes.get(row).map(|&c| c as usize))?;
299 (at < leaf.len() && leaf.validity().is_valid(at)).then_some(at)
300 },
301 );
302 live.push(found.is_some());
303 found.map_or((crate::NO_ROW, 0), |at| (source, at as u32))
305 })
306 .collect();
307 let first = datas.first().copied();
308 macro_rules! picking {
309 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
310 match first {
311 None | Some(Data::Empty) => return Ok(Some(Vector::constant(ty.clone(), Value::Null, picks.len()))),
312 $(Some(Data::$variant(_)) => {
313 let mut runs = Vec::with_capacity(datas.len());
314 for data in &datas {
315 let Data::$variant(values) = data else {
316 return Ok(None);
317 };
318 runs.push(values.as_slice());
319 }
320 let mut out: Vec<$native> = Vec::with_capacity(picks.len());
321 out.extend(picks.iter().map(|&(source, row)| {
322 runs.get(source as usize)
323 .and_then(|run| run.get(row as usize))
324 .copied()
325 .unwrap_or($zero)
326 }));
327 Data::$variant(Buffer::from_vec(out))
328 })+
329 Some(Data::Varlen(_)) => {
330 let mut runs = Vec::with_capacity(datas.len());
331 for data in &datas {
332 let Data::Varlen(values) = data else {
333 return Ok(None);
334 };
335 runs.push(values);
336 }
337 let mut out = StringColumn::with_capacity(picks.len());
338 for &(source, row) in &picks {
339 match runs.get(source as usize) {
340 Some(run) => out.push_from(run, row as usize),
341 None => out.push(""),
342 };
343 }
344 Data::Varlen(out)
345 }
346 }
347 };
348 }
349 let data = crate::for_each_layout!(fixed, picking);
350 let vector = Vector::flat(ty.clone(), data)?;
351 Ok(Some(if live.iter().all(|&alive| alive) {
352 vector
353 } else {
354 vector.with_validity(Validity::from_run(&live))
355 }))
356}
357
358pub fn concat_on<V: AsRef<Vector>>(
396 ty: &LogicalType,
397 pieces: &[V],
398 spread: &Spread<'_>,
399) -> Result<Option<Vector>> {
400 let pieces: Vec<&Vector> = pieces.iter().map(AsRef::as_ref).collect();
401 if let Some(strung) = strung(ty, &pieces, spread)? {
402 return Ok(Some(strung));
403 }
404 if let Some(tiled) = tiled(ty, &pieces, spread)? {
405 return Ok(Some(tiled));
406 }
407 laid(ty, &pieces)
408}
409
410const TILED_ROWS: usize = 1 << 16;
413
414fn tiled(ty: &LogicalType, pieces: &[&Vector], spread: &Spread<'_>) -> Result<Option<Vector>> {
426 let rows: usize = pieces.iter().map(|piece| piece.len()).sum();
427 if pieces.len() < 2 || rows < TILED_ROWS {
428 return Ok(None);
429 }
430 let flat = pieces.iter().all(|piece| {
431 piece.form() == Form::Flat
432 && piece.logical_type() == ty
433 && !piece.is_empty()
434 && piece.data().is_some_and(|data| data.len() == piece.len())
435 });
436 if !flat || adjoined(pieces).is_some() {
437 return Ok(None);
438 }
439 macro_rules! tiles {
440 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
441 match pieces[0].data() {
442 $(Some(Data::$variant(_)) => {
443 let mut page: Vec<$native> = vec![$zero; rows];
444 let mut rest: &mut [$native] = &mut page;
447 let mut slots = Vec::with_capacity(pieces.len());
448 for piece in pieces {
449 let (head, tail) = rest.split_at_mut(piece.len());
450 slots.push(Mutex::new(head));
451 rest = tail;
452 }
453 let task = |at: usize| {
454 let Some(Data::$variant(values)) = pieces[at].data() else { return };
455 let mut slot = slots[at].lock().unwrap_or_else(|poisoned| poisoned.into_inner());
456 if let Some(values) = values.as_slice().get(..slot.len()) {
457 slot.copy_from_slice(values);
458 }
459 };
460 spread(pieces.len(), &task)?;
461 drop(slots);
462 Data::$variant(Buffer::from_vec(page))
463 })+
464 _ => return Ok(None),
465 }
466 };
467 }
468 if pieces.iter().any(|piece| layout_of_piece(piece) != layout_of_piece(pieces[0])) {
470 return Ok(None);
471 }
472 let data = crate::for_each_layout!(fixed, tiles);
473 let validity = run_of(pieces, rows);
474 Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity).into_pages()))
475}
476
477fn layout_of_piece(piece: &Vector) -> Option<std::mem::Discriminant<Data>> {
479 piece.data().map(std::mem::discriminant)
480}
481
482fn strung(ty: &LogicalType, pieces: &[&Vector], spread: &Spread<'_>) -> Result<Option<Vector>> {
487 let Some(columns) = apart(ty, pieces) else {
488 return Ok(None);
489 };
490 let mut bases = Vec::with_capacity(columns.len());
494 let mut bytes = 0usize;
495 let mut rows = 0usize;
496 for column in &columns {
497 bases.push((bytes, rows));
498 bytes += column.arena().len();
499 rows += column.len();
500 }
501
502 let mut arena = vec![0u8; bytes];
507 let mut views = vec![StringView::empty(); rows];
508 let mut arena_rest: &mut [u8] = &mut arena;
512 let mut views_rest: &mut [StringView] = &mut views;
513 let mut slots = Vec::with_capacity(columns.len());
514 for column in &columns {
515 let (arena_head, arena_tail) = arena_rest.split_at_mut(column.arena().len());
516 let (views_head, views_tail) = views_rest.split_at_mut(column.len());
517 slots.push(Mutex::new((arena_head, views_head)));
518 arena_rest = arena_tail;
519 views_rest = views_tail;
520 }
521
522 let task = |at: usize| {
523 let column = columns[at];
524 let (base, _) = bases[at];
525 let mut slot = slots[at].lock().unwrap_or_else(|poisoned| poisoned.into_inner());
526 let (into_arena, into_views) = &mut *slot;
527 into_arena.copy_from_slice(column.arena());
528 let base = base as u64;
529 for (slot, view) in into_views.iter_mut().zip(column.views()) {
530 *slot = view.shifted(base);
531 }
532 };
533 spread(columns.len(), &task)?;
534 drop(slots);
535
536 let validity = run_of(pieces, rows);
537 let page = Vector::string_views(ty.clone(), views, Arc::new(Buffer::from(arena)))?;
538 Ok(Some(page.with_validity(validity)))
539}
540
541fn apart<'a>(ty: &LogicalType, pieces: &[&'a Vector]) -> Option<Vec<&'a StringColumn>> {
563 if pieces.len() < 2 {
564 return None;
565 }
566 let mut columns = Vec::with_capacity(pieces.len());
567 let mut seen = HashSet::with_capacity(pieces.len());
568 for piece in pieces {
569 if piece.form() != Form::Flat || piece.logical_type() != ty || piece.is_empty() {
570 return None;
571 }
572 let Some(Data::Varlen(column)) = piece.data() else {
573 return None;
574 };
575 if !column.mostly_read() || !seen.insert(column.arena().as_ptr() as usize) {
576 return None;
577 }
578 columns.push(column);
579 }
580 Some(columns)
581}
582
583fn laid(ty: &LogicalType, pieces: &[&Vector]) -> Result<Option<Vector>> {
589 if pieces.is_empty() {
590 return Ok(None);
591 }
592 let rows = pieces.iter().map(|piece| piece.len()).sum();
593 let shared = pieces[0].stable_dictionary_parts().map(|(_, values)| values).filter(|values| {
594 pieces.iter().all(|piece| {
595 piece.logical_type() == ty
596 && !piece.is_empty()
597 && piece
598 .stable_dictionary_parts()
599 .is_some_and(|(_, held)| Arc::ptr_eq(held, values))
600 })
601 });
602 if let Some(values) = shared {
603 let mut codes = Vec::with_capacity(rows);
604 for piece in pieces {
605 if let Some((held, _)) = piece.stable_dictionary_parts() {
606 codes.extend_from_slice(held);
607 }
608 }
609 let validity = run_of(pieces, rows);
610 return Ok(Some(
611 Vector::stable_dictionary(codes, Arc::clone(values))?.with_validity(validity),
612 ));
613 }
614 if let Some(arena) = pieces[0].shared_views().map(|(_, arena)| arena).filter(|arena| {
618 pieces.iter().all(|piece| {
619 piece.logical_type() == ty
620 && piece.shared_views().is_some_and(|(_, held)| Arc::ptr_eq(held, arena))
621 })
622 }) {
623 let mut views = Vec::with_capacity(rows);
624 for piece in pieces {
625 if let Some((held, _)) = piece.shared_views() {
626 views.extend_from_slice(held);
627 }
628 }
629 let validity = run_of(pieces, rows);
630 return Ok(Some(
631 Vector::string_views(ty.clone(), views, Arc::clone(arena))?.with_validity(validity),
632 ));
633 }
634 let laid = pieces
637 .iter()
638 .all(|piece| piece.form() == Form::Flat && piece.logical_type() == ty && !piece.is_empty());
639 if !laid {
640 return Ok(None);
641 }
642 if let Some(data) = adjoined(pieces) {
643 let validity = run_of(pieces, rows);
644 return Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity)));
645 }
646 let mut data = data_for(ty, rows)?;
650 let mut arenas = arenas_of(pieces);
651 for piece in pieces {
652 let from = piece
653 .data()
654 .ok_or_else(|| Error::internal("a flat vector with no run of data in it"))?;
655 let appended = extend(&mut data, from, &mut arenas)?;
656 if appended != piece.len() {
657 return Err(Error::internal(format!(
658 "a piece of {} rows laid {appended} values end to end",
659 piece.len()
660 )));
661 }
662 }
663 let validity = run_of(pieces, rows);
664 if let Data::Varlen(column) = data {
665 let (views, arena) = column.into_parts();
666 let page = Vector::string_views(ty.clone(), views, Arc::new(arena))?;
667 return Ok(Some(page.with_validity(validity)));
668 }
669 Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity).into_pages()))
670}
671
672pub fn interleave(ty: &LogicalType, pieces: &[Vector], order: &[usize]) -> Result<Vector> {
689 interleave_placed(ty, pieces, order, None)
690}
691
692pub fn interleave_placed(
713 ty: &LogicalType,
714 pieces: &[Vector],
715 order: &[usize],
716 inverse: Option<&[u32]>,
717) -> Result<Vector> {
718 let rows: usize = pieces.iter().map(Vector::len).sum();
719 if let Some(inverse) = inverse.filter(|inverse| inverse.len() != rows || order.len() != rows) {
720 return Err(Error::internal(format!(
721 "{} places and {} positions for a permutation of {rows} rows",
722 inverse.len(),
723 order.len()
724 )));
725 }
726 if let Some(&past) = order.iter().find(|&&index| index >= rows) {
727 return Err(Error::internal(format!("row {past} read out of pieces of {rows} rows")));
728 }
729 if matches!(ty, LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)) {
730 let laid: Vec<Value> = pieces
733 .iter()
734 .flat_map(|piece| (0..piece.len()).map(|row| piece.value_at(row)))
735 .collect();
736 let values: Vec<Value> =
737 order.iter().map(|&index| laid.get(index).cloned().unwrap_or(Value::Null)).collect();
738 return Vector::from_values(ty.clone(), &values);
739 }
740 if let Some(merged) = merged_dictionary(ty, pieces, order, inverse)? {
741 return Ok(merged);
742 }
743 if let Some(inverse) = inverse {
744 if let Some(placed) = placed_strings(ty, pieces, inverse, 0..rows)? {
745 return Ok(placed);
746 }
747 if let Some(placed) = placed_fixed(ty, pieces, inverse)? {
748 return Ok(placed);
749 }
750 }
751 let mut data = data_for(ty, rows)?;
752 if matches!(data, Data::Empty) {
755 return Ok(Vector::constant(ty.clone(), Value::Null, order.len()));
756 }
757 let mut arenas = arenas_of(pieces);
758 if let Data::Varlen(column) = &mut data {
761 column.reserve_bytes(arenas.bytes());
762 }
763 let mut masks = Vec::with_capacity(pieces.len());
766 for piece in pieces {
767 let flat = piece.flatten()?;
771 let from = flat.data().ok_or_else(|| Error::internal("a flattened vector with no data"))?;
772 let appended = extend(&mut data, from, &mut arenas)?;
773 if appended != piece.len() {
774 return Err(Error::internal(format!(
775 "a piece of {} rows laid {appended} values end to end",
776 piece.len()
777 )));
778 }
779 masks.push((flat.len(), flat.validity().clone()));
780 }
781 let laid = if masks.iter().all(|(_, mask)| matches!(mask, Validity::AllValid)) {
782 Validity::AllValid
783 } else {
784 let mut live = Vec::with_capacity(rows);
785 for (len, mask) in &masks {
786 live.extend((0..*len).map(|row| mask.is_valid(row)));
789 }
790 Validity::from_run(&live)
791 };
792 if laid.count_valid(rows) == 0 {
793 return Ok(Vector::constant(ty.clone(), Value::Null, order.len()));
794 }
795 let validity = match (laid, inverse) {
796 (Validity::AllValid, _) => Validity::AllValid,
797 (laid, Some(inverse)) => {
798 let mut live = vec![false; order.len()];
799 for (row, &to) in inverse.iter().enumerate() {
800 if let Some(slot) = live.get_mut(to as usize) {
801 *slot = laid.is_valid(row);
802 }
803 }
804 Validity::from_run(&live)
805 }
806 (laid, None) => Validity::from_iter(order.len(), |row| {
807 order.get(row).is_some_and(|&index| laid.is_valid(index))
808 }),
809 };
810 if let Data::Varlen(column) = data {
811 let (views, arena) = column.into_parts();
812 let gathered = match inverse {
813 Some(inverse) => {
814 let mut placed = vec![StringView::empty(); order.len()];
815 for (view, &to) in views.iter().zip(inverse) {
816 if let Some(slot) = placed.get_mut(to as usize) {
817 *slot = *view;
818 }
819 }
820 placed
821 }
822 None => order
823 .iter()
824 .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
825 .collect(),
826 };
827 return Ok(
828 Vector::string_views(ty.clone(), gathered, Arc::new(arena))?.with_validity(validity)
829 );
830 }
831 let data = match inverse {
832 Some(inverse) => placed_of(&data, inverse),
833 None => copy_of(&data, order),
834 };
835 Ok(Vector::flat(ty.clone(), data)?.with_validity(validity))
836}
837
838fn placed_fixed(ty: &LogicalType, pieces: &[Vector], inverse: &[u32]) -> Result<Option<Vector>> {
850 let rows = inverse.len();
851 let mut live: Option<Vec<bool>> = None;
852 let mut base = 0;
853 let mut mark = |mask: &Validity, places: &[u32]| {
855 if matches!(mask, Validity::AllValid) {
856 return;
857 }
858 let live = live.get_or_insert_with(|| vec![true; rows]);
859 for (row, &to) in places.iter().enumerate() {
860 if let Some(slot) = live.get_mut(to as usize) {
861 *slot = mask.is_valid(row);
862 }
863 }
864 };
865 macro_rules! placed {
866 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
867 match data_for(ty, 0)? {
868 $(Data::$variant(_) => {
869 let mut out: Vec<$native> = vec![$zero; rows];
870 for piece in pieces {
871 let len = piece.len();
872 let places = inverse.get(base..base + len).ok_or_else(|| {
873 Error::internal("pieces longer than the places they are written to")
874 })?;
875 base += len;
876 let coded = piece.dictionary_parts().and_then(|(codes, values)| {
877 match (values.form(), values.validity(), values.data()) {
878 (Form::Flat, Validity::AllValid, Some(Data::$variant(held))) => {
879 Some((codes, held.as_slice()))
880 }
881 _ => None,
882 }
883 });
884 if let Some((codes, held)) = coded {
885 for (&code, &to) in codes.iter().zip(places) {
886 if let (Some(slot), Some(value)) =
887 (out.get_mut(to as usize), held.get(code as usize))
888 {
889 *slot = *value;
890 }
891 }
892 mark(piece.validity(), places);
893 continue;
894 }
895 let flat;
897 let piece = if piece.form() == Form::Flat {
898 piece
899 } else {
900 flat = piece.flatten()?;
903 &flat
904 };
905 let Some(Data::$variant(values)) = piece.data() else {
906 return Err(Error::internal(format!(
907 "a piece of {} laid into a column of {ty}",
908 piece.logical_type()
909 )));
910 };
911 if values.len() != len {
912 return Err(Error::internal(format!(
913 "a piece of {len} rows holds {} values",
914 values.len()
915 )));
916 }
917 for (value, &to) in values.iter().zip(places) {
918 if let Some(slot) = out.get_mut(to as usize) {
919 *slot = *value;
920 }
921 }
922 mark(piece.validity(), places);
923 }
924 let validity = match live {
925 None => Validity::AllValid,
926 Some(live) if !live.contains(&true) => {
927 return Ok(Some(Vector::constant(ty.clone(), Value::Null, rows)));
928 }
929 Some(live) => Validity::from_run(&live),
930 };
931 let data = Data::$variant(Buffer::from_vec(out));
932 Ok(Some(Vector::flat(ty.clone(), data)?.with_validity(validity)))
933 })+
934 _ => Ok(None),
935 }
936 };
937 }
938 crate::for_each_layout!(fixed, placed)
939}
940
941fn placed_strings(
956 ty: &LogicalType,
957 pieces: &[Vector],
958 inverse: &[u32],
959 range: Range<usize>,
960) -> Result<Option<Vector>> {
961 if !strings_placeable(ty, pieces) {
962 return Ok(None);
963 }
964 let first = range.start;
965 let rows = range.len();
966 let local = |to: u32| (to as usize).checked_sub(first).filter(|&at| at < rows);
968 let mut offsets = vec![0u64; rows + 1];
969 let mut places = inverse.iter();
970 for piece in pieces {
971 let (views, _) = piece.text_parts().unwrap_or_default();
972 for (view, &to) in views.iter().zip(places.by_ref()) {
973 if view.is_inline() {
974 continue;
975 }
976 if let Some(slot) = local(to).and_then(|at| offsets.get_mut(at + 1)) {
977 *slot = view.len() as u64;
978 }
979 }
980 }
981 let mut total = 0;
982 for offset in &mut offsets {
983 total += *offset;
984 *offset = total;
985 }
986 let mut arena =
987 vec![0u8; usize::try_from(total).map_err(|_| Error::internal("an arena too large"))?];
988 let mut placed = vec![StringView::empty(); rows];
989 let mut live = vec![true; rows];
990 let mut places = inverse.iter();
991 for piece in pieces {
992 let (views, from) = piece.text_parts().unwrap_or_default();
993 let validity = piece.validity();
994 for (row, (view, &to)) in views.iter().zip(places.by_ref()).enumerate() {
995 let Some(to) = local(to) else {
996 continue;
997 };
998 if !validity.is_valid(row) {
999 if let Some(slot) = live.get_mut(to) {
1000 *slot = false;
1001 }
1002 continue;
1003 }
1004 let (Some(bytes), Some(&at), Some(slot)) =
1005 (view.bytes_in(from), offsets.get(to), placed.get_mut(to))
1006 else {
1007 continue;
1008 };
1009 if view.is_inline() {
1010 *slot = *view;
1011 continue;
1012 }
1013 if let Some(into) = arena.get_mut(at as usize..at as usize + bytes.len()) {
1014 into.copy_from_slice(bytes);
1015 }
1016 *slot = StringView::over(bytes, at);
1017 }
1018 }
1019 let validity = if live.iter().all(|&valid| valid) {
1020 Validity::AllValid
1021 } else {
1022 Validity::from_run(&live)
1023 };
1024 let vector = Vector::string_views(ty.clone(), placed, Arc::new(Buffer::from_vec(arena)))?;
1025 Ok(Some(vector.with_validity(validity)))
1026}
1027
1028#[must_use]
1031pub fn strings_placeable(ty: &LogicalType, pieces: &[Vector]) -> bool {
1032 matches!(ty, LogicalType::Varchar | LogicalType::Blob)
1033 && pieces.iter().all(|piece| piece.text_parts().is_some())
1034}
1035
1036pub fn placed_string_rows(
1048 ty: &LogicalType,
1049 pieces: &[Vector],
1050 inverse: &[u32],
1051 range: Range<usize>,
1052) -> Result<Vector> {
1053 let rows: usize = pieces.iter().map(Vector::len).sum();
1054 if inverse.len() != rows || range.end > rows || range.start > range.end {
1055 return Err(Error::internal(format!(
1056 "rows {range:?} of {} places for {rows} rows",
1057 inverse.len()
1058 )));
1059 }
1060 placed_strings(ty, pieces, inverse, range)?
1061 .ok_or_else(|| Error::internal("a string column placed that is not flat views"))
1062}
1063
1064const ROWS_PER_MERGED_ENTRY: usize = 8;
1073
1074fn merged_dictionary(
1084 ty: &LogicalType,
1085 pieces: &[Vector],
1086 order: &[usize],
1087 inverse: Option<&[u32]>,
1088) -> Result<Option<Vector>> {
1089 if !matches!(ty, LogicalType::Varchar | LogicalType::Blob) || pieces.is_empty() {
1090 return Ok(None);
1091 }
1092 let rows: usize = pieces.iter().map(Vector::len).sum();
1093 let mut dictionaries: Vec<&Arc<Vector>> = Vec::new();
1094 let mut which = Vec::with_capacity(pieces.len());
1095 let mut entries = 0;
1096 for piece in pieces {
1097 let Some((_, values)) = piece.shared_dictionary_parts() else {
1098 return Ok(None);
1099 };
1100 if !matches!(piece.validity(), Validity::AllValid) {
1101 return Ok(None);
1102 }
1103 let at = match dictionaries.iter().position(|seen| Arc::ptr_eq(seen, values)) {
1104 Some(at) => at,
1105 None => {
1106 entries += values.len();
1107 if entries.saturating_mul(ROWS_PER_MERGED_ENTRY) > rows {
1108 return Ok(None);
1109 }
1110 dictionaries.push(values);
1111 dictionaries.len() - 1
1112 }
1113 };
1114 which.push(at);
1115 }
1116 let mut merged: HashMap<Option<&[u8]>, u32> = HashMap::new();
1118 let mut values = Vec::new();
1119 let mut remaps = Vec::with_capacity(dictionaries.len());
1120 for dictionary in &dictionaries {
1121 let mut remap = Vec::with_capacity(dictionary.len());
1122 for entry in 0..dictionary.len() {
1125 let next = u32::try_from(values.len())
1126 .map_err(|_| Error::internal("a merged dictionary past four billion entries"))?;
1127 let code = *merged.entry(dictionary.bytes_at(entry)).or_insert_with(|| {
1128 values.push(dictionary.value_at(entry));
1129 next
1130 });
1131 remap.push(code);
1132 }
1133 remaps.push(remap);
1134 }
1135 let mut laid = Vec::with_capacity(rows);
1136 for (piece, &at) in pieces.iter().zip(&which) {
1137 let (codes, _) = piece
1138 .dictionary_parts()
1139 .ok_or_else(|| Error::internal("a dictionary piece lost its dictionary"))?;
1140 let remap = &remaps[at];
1141 laid.extend(codes.iter().map(|&code| remap[code as usize]));
1142 }
1143 let codes = match inverse {
1146 Some(inverse) => {
1147 let mut codes = vec![0u32; order.len()];
1148 for (&code, &to) in laid.iter().zip(inverse) {
1149 if let Some(slot) = codes.get_mut(to as usize) {
1150 *slot = code;
1151 }
1152 }
1153 codes
1154 }
1155 None => order.iter().map(|&index| laid[index]).collect(),
1156 };
1157 let values = Vector::from_values(ty.clone(), &values)?;
1158 Ok(Some(Vector::stable_dictionary(codes, Arc::new(values))?))
1159}
1160
1161fn run_of(pieces: &[&Vector], rows: usize) -> Validity {
1167 if pieces.iter().all(|piece| matches!(piece.validity(), Validity::AllValid)) {
1168 return Validity::AllValid;
1169 }
1170 if pieces.iter().all(|piece| matches!(piece.validity(), Validity::AllInvalid)) {
1171 return Validity::AllInvalid;
1172 }
1173 let mut live = Vec::with_capacity(rows);
1174 for piece in pieces {
1175 for row in 0..piece.len() {
1178 live.push(!piece.is_null_at(row));
1179 }
1180 }
1181 Validity::from_run(&live)
1182}
1183
1184fn straight(at: &[usize]) -> bool {
1186 at.iter().enumerate().all(|(row, &index)| row == index)
1187}
1188
1189fn arenas_of<V: AsRef<Vector>>(pieces: &[V]) -> Arenas {
1191 let mut arenas = Arenas::default();
1192 for piece in pieces {
1193 if let Some(Data::Varlen(column)) = piece.as_ref().data() {
1194 arenas.count(column);
1195 }
1196 }
1197 arenas
1198}
1199
1200fn adjoined(pieces: &[&Vector]) -> Option<Data> {
1207 macro_rules! joined {
1208 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1209 match pieces.first()?.data()? {
1210 $(Data::$variant(first) => {
1211 if !first.is_shared() {
1212 return None;
1213 }
1214 let mut run = first.clone();
1215 for piece in &pieces[1..] {
1216 let Some(Data::$variant(next)) = piece.data() else { return None };
1217 run = run.joined(next)?;
1218 }
1219 Some(Data::$variant(run))
1220 })+
1221 Data::Varlen(first) => {
1222 if !first.is_paged() {
1223 return None;
1224 }
1225 let mut run = first.clone();
1226 for piece in &pieces[1..] {
1227 let Some(Data::Varlen(next)) = piece.data() else { return None };
1228 run = run.joined(next)?;
1229 }
1230 Some(Data::Varlen(run))
1231 }
1232 _ => None,
1233 }
1234 };
1235 }
1236 crate::for_each_layout!(fixed, joined)
1237}
1238
1239fn extend(into: &mut Data, from: &Data, arenas: &mut Arenas) -> Result<usize> {
1245 macro_rules! extended {
1246 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1247 match (&mut *into, from) {
1248 (_, Data::Empty) => Ok(0),
1251 $((Data::$variant(out), Data::$variant(values)) => {
1252 out.extend_from_slice(values.as_slice());
1253 Ok(values.len())
1254 })+
1255 (Data::Varlen(out), Data::Varlen(values)) => {
1258 out.push_column(values, arenas);
1259 Ok(values.len())
1260 }
1261 (out, from) => Err(Error::internal(format!(
1262 "a run of {:?} values cannot be laid after a run of {:?} ones",
1263 layout_of(from),
1264 layout_of(out)
1265 ))),
1266 }
1267 };
1268 }
1269 crate::for_each_layout!(fixed, extended)
1270}
1271
1272fn picked_codes(sources: &[&Vector], picks: &[(u32, u32)]) -> Result<Option<Vector>> {
1282 let mut shared: Option<&Arc<Vector>> = None;
1283 let mut runs = Vec::with_capacity(sources.len());
1284 for source in sources {
1285 let Some((codes, values)) = source.stable_dictionary_parts() else { return Ok(None) };
1286 if shared.is_some_and(|held| !Arc::ptr_eq(held, values)) {
1287 return Ok(None);
1288 }
1289 shared = Some(values);
1290 runs.push(codes);
1291 }
1292 let Some(values) = shared.filter(|values| !values.is_empty()) else { return Ok(None) };
1294 let mut live = Vec::with_capacity(picks.len());
1295 let mut codes = Vec::with_capacity(picks.len());
1296 for &(source, row) in picks {
1297 let code = sources.get(source as usize).and_then(|held| {
1298 let row = row as usize;
1299 let code = runs[source as usize].get(row)?;
1300 held.validity().is_valid(row).then_some(*code)
1301 });
1302 live.push(code.is_some());
1303 codes.push(code.unwrap_or(0));
1304 }
1305 let vector = Vector::stable_dictionary(codes, Arc::clone(values))?;
1306 Ok(Some(if live.iter().all(|&alive| alive) {
1307 vector
1308 } else {
1309 vector.with_validity(Validity::from_run(&live))
1310 }))
1311}
1312
1313#[cfg(test)]
1314mod tests {
1315 use super::*;
1316 use crate::{Chunk, Form};
1317
1318 fn values(vector: &Vector) -> Vec<Value> {
1320 (0..vector.len()).map(|row| vector.value_at(row)).collect()
1321 }
1322
1323 fn scattered(ty: &LogicalType, rows: usize, pieces: &[(Vec<u32>, Vector)]) -> Vector {
1328 let mut answers = vec![Value::Null; rows];
1329 for (positions, piece) in pieces {
1330 for (slot, &row) in positions.iter().enumerate() {
1331 answers[row as usize] = piece.value_at(slot);
1332 }
1333 }
1334 Vector::from_values(ty.clone(), &answers).expect("the reference builds")
1335 }
1336
1337 fn agrees(ty: &LogicalType, rows: usize, pieces: &[(Vec<u32>, Vector)]) -> Vector {
1339 let mut assembly = Assembly::new(ty.clone(), rows).expect("an assembly of this type");
1340 for (positions, piece) in pieces {
1341 assembly.place(positions, piece).expect("the piece is placed");
1342 }
1343 let built = assembly.finish().expect("the assembly finishes");
1344 assert_eq!(built.len(), rows, "an assembly of {rows} rows");
1345 assert_eq!(values(&built), values(&scattered(ty, rows, pieces)), "against the slow way");
1346 built
1347 }
1348
1349 #[test]
1350 fn two_pieces_interleave_back_into_the_order_the_rows_came_in() {
1351 let evens = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(0), Value::BigInt(2)])
1352 .expect("a vector");
1353 let odds = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1), Value::BigInt(3)])
1354 .expect("a vector");
1355 let built = agrees(&LogicalType::BigInt, 4, &[(vec![0, 2], evens), (vec![1, 3], odds)]);
1356 assert_eq!(
1357 values(&built),
1358 vec![Value::BigInt(0), Value::BigInt(1), Value::BigInt(2), Value::BigInt(3)]
1359 );
1360 }
1361
1362 #[test]
1363 fn a_row_no_piece_claims_is_null() {
1364 let piece =
1367 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(7)]).expect("a vector");
1368 let built = agrees(&LogicalType::BigInt, 3, &[(vec![1], piece)]);
1369 assert_eq!(values(&built), vec![Value::Null, Value::BigInt(7), Value::Null]);
1370 }
1371
1372 #[test]
1373 fn no_pieces_at_all_is_a_column_of_nulls_of_the_right_length() {
1374 let built = agrees(&LogicalType::Integer, 5, &[]);
1375 assert!(built.is_null_at(4), "every row of it is null");
1376 }
1377
1378 #[test]
1379 fn a_null_inside_a_piece_stays_null_where_the_piece_put_it() {
1380 let piece = Vector::from_values(
1383 LogicalType::BigInt,
1384 &[Value::BigInt(1), Value::Null, Value::BigInt(3)],
1385 )
1386 .expect("a vector");
1387 let built = agrees(&LogicalType::BigInt, 3, &[(vec![2, 0, 1], piece)]);
1388 assert!(built.is_null_at(0), "the null landed where the piece put it");
1389 assert_eq!(built.value_at(2), Value::BigInt(1));
1390 }
1391
1392 #[test]
1393 fn strings_are_assembled_without_going_through_a_value_each() {
1394 let left = Vector::from_values(
1395 LogicalType::Varchar,
1396 &[Value::Varchar("a short one".into()), Value::Varchar("another".into())],
1397 )
1398 .expect("a vector");
1399 let right = Vector::from_values(
1400 LogicalType::Varchar,
1401 &[Value::Varchar("a string that is far too long to live inline in a view".into())],
1402 )
1403 .expect("a vector");
1404 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 2], left), (vec![1], right)]);
1405 assert_eq!(built.value_at(0), Value::Varchar("a short one".into()));
1406 assert_eq!(
1407 built.value_at(1),
1408 Value::Varchar("a string that is far too long to live inline in a view".into())
1409 );
1410 assert_eq!(built.value_at(2), Value::Varchar("another".into()));
1411 }
1412
1413 #[test]
1414 fn strings_laid_end_to_end_in_order_come_back_as_views_over_the_arena_they_went_into() {
1415 let first = Vector::from_values(
1418 LogicalType::Varchar,
1419 &[Value::Varchar("one".into()), Value::Varchar("two".into())],
1420 )
1421 .expect("a vector");
1422 let second = Vector::from_values(
1423 LogicalType::Varchar,
1424 &[Value::Varchar("a third one long enough to be out of line".into())],
1425 )
1426 .expect("a vector");
1427 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 1], first), (vec![2], second)]);
1428 assert_eq!(built.form(), Form::StringView, "the bytes stay where they were appended");
1429 assert_eq!(
1430 built.value_at(2),
1431 Value::Varchar("a third one long enough to be out of line".into())
1432 );
1433 }
1434
1435 #[test]
1436 fn a_string_row_no_piece_claims_is_null_rather_than_empty() {
1437 let piece = Vector::from_values(
1440 LogicalType::Varchar,
1441 &[Value::Varchar("a value long enough to be out of line".into())],
1442 )
1443 .expect("a vector");
1444 let built = agrees(&LogicalType::Varchar, 3, &[(vec![2], piece)]);
1445 assert_eq!(built.value_at(0), Value::Null);
1446 assert_eq!(built.value_at(1), Value::Null);
1447 assert_eq!(
1448 built.value_at(2),
1449 Value::Varchar("a value long enough to be out of line".into())
1450 );
1451 }
1452
1453 #[test]
1454 fn a_constant_piece_is_written_out_rather_than_read_a_row_at_a_time() {
1455 let arm = Vector::from_values(LogicalType::Varchar, &[Value::Varchar("kept".into())])
1458 .expect("a vector");
1459 let otherwise = Vector::constant(LogicalType::Varchar, Value::Varchar("".into()), 3);
1460 let built = agrees(&LogicalType::Varchar, 4, &[(vec![2], arm), (vec![0, 1, 3], otherwise)]);
1461 assert_eq!(built.value_at(0), Value::Varchar("".into()));
1462 assert_eq!(built.value_at(2), Value::Varchar("kept".into()));
1463 }
1464
1465 #[test]
1466 fn a_dictionary_piece_is_walked_to_its_values() {
1467 let dictionary = Vector::from_values(
1470 LogicalType::Varchar,
1471 &[Value::Varchar("one".into()), Value::Varchar("two".into())],
1472 )
1473 .expect("a dictionary");
1474 let piece = Vector::dictionary(vec![1, 0, 1], dictionary).expect("a dictionary vector");
1475 let built = agrees(&LogicalType::Varchar, 3, &[(vec![0, 1, 2], piece)]);
1476 assert_eq!(
1477 values(&built),
1478 vec![
1479 Value::Varchar("two".into()),
1480 Value::Varchar("one".into()),
1481 Value::Varchar("two".into())
1482 ]
1483 );
1484 }
1485
1486 #[test]
1487 fn a_piece_placed_at_the_wrong_number_of_positions_is_an_error() {
1488 let piece =
1489 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1)]).expect("a vector");
1490 let mut assembly = Assembly::new(LogicalType::BigInt, 4).expect("an assembly");
1491 assert!(assembly.place(&[0, 1], &piece).is_err(), "two positions for one row");
1492 }
1493
1494 #[test]
1495 fn a_position_past_the_end_is_an_error_rather_than_a_lost_row() {
1496 let piece =
1497 Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1)]).expect("a vector");
1498 let mut assembly = Assembly::new(LogicalType::BigInt, 2).expect("an assembly");
1499 assert!(assembly.place(&[9], &piece).is_err(), "a row past the end of the assembly");
1500 }
1501
1502 #[test]
1503 fn a_piece_of_the_wrong_layout_is_an_error_rather_than_a_wrong_answer() {
1504 let piece =
1507 Vector::from_values(LogicalType::Varchar, &[Value::Varchar("x".into())]).expect("text");
1508 let mut assembly = Assembly::new(LogicalType::BigInt, 1).expect("an assembly");
1509 assert!(assembly.place(&[0], &piece).is_err(), "text laid after integers");
1510 }
1511
1512 #[test]
1513 fn every_layout_assembles_the_way_it_scatters() {
1514 let cases: Vec<(LogicalType, Vec<Value>)> = vec![
1517 (LogicalType::Boolean, vec![Value::Boolean(true), Value::Boolean(false)]),
1518 (LogicalType::TinyInt, vec![Value::TinyInt(1), Value::TinyInt(-2)]),
1519 (LogicalType::SmallInt, vec![Value::SmallInt(3), Value::SmallInt(-4)]),
1520 (LogicalType::Integer, vec![Value::Integer(5), Value::Integer(-6)]),
1521 (LogicalType::BigInt, vec![Value::BigInt(7), Value::BigInt(-8)]),
1522 (LogicalType::HugeInt, vec![Value::HugeInt(9), Value::HugeInt(-10)]),
1523 (LogicalType::UTinyInt, vec![Value::UTinyInt(11), Value::UTinyInt(12)]),
1524 (LogicalType::USmallInt, vec![Value::USmallInt(13), Value::USmallInt(14)]),
1525 (LogicalType::UInteger, vec![Value::UInteger(15), Value::UInteger(16)]),
1526 (LogicalType::UBigInt, vec![Value::UBigInt(17), Value::UBigInt(18)]),
1527 (LogicalType::Float, vec![Value::Float(1.5), Value::Float(-2.5)]),
1528 (LogicalType::Double, vec![Value::Double(3.5), Value::Double(-4.5)]),
1529 (
1530 LogicalType::Varchar,
1531 vec![Value::Varchar("first".into()), Value::Varchar("second".into())],
1532 ),
1533 (LogicalType::Date, vec![Value::Date(19), Value::Date(20)]),
1534 ];
1535 for (ty, pair) in cases {
1536 let left = Vector::from_values(ty.clone(), &pair[..1]).expect("a vector");
1537 let right = Vector::from_values(ty.clone(), &pair[1..]).expect("a vector");
1538 let built = agrees(&ty, 2, &[(vec![1], left), (vec![0], right)]);
1539 assert_eq!(built.value_at(0), pair[1], "{ty:?} at row 0");
1540 assert_eq!(built.value_at(1), pair[0], "{ty:?} at row 1");
1541 }
1542 }
1543
1544 #[test]
1545 fn an_assembly_is_a_chunk_column_like_any_other() {
1546 let piece = Vector::from_values(LogicalType::BigInt, &[Value::BigInt(1), Value::BigInt(2)])
1549 .expect("a vector");
1550 let built = agrees(&LogicalType::BigInt, 2, &[(vec![1, 0], piece)]);
1551 let chunk = Chunk::new(vec![built]).expect("a chunk of one column");
1552 assert_eq!(chunk.len(), 2, "two rows");
1553 }
1554
1555 fn all_of(pieces: &[Vector]) -> Vec<Value> {
1557 pieces.iter().flat_map(values).collect()
1558 }
1559
1560 fn laid(ty: &LogicalType, pieces: &[Vector]) -> Vector {
1562 let built = concat(ty, pieces).expect("the pieces lay").expect("this run lays");
1563 assert_eq!(built.len(), pieces.iter().map(Vector::len).sum::<usize>(), "the row count");
1564 assert_eq!(values(&built), all_of(pieces), "the values laid end to end");
1565 built
1566 }
1567
1568 #[test]
1569 fn pieces_laid_end_to_end_read_back_in_the_order_they_were_given() {
1570 let piece = |from: i64, to: i64| {
1571 let held: Vec<Value> = (from..to).map(Value::BigInt).collect();
1572 Vector::from_values(LogicalType::BigInt, &held).expect("a run of bigints")
1573 };
1574 let pieces = [piece(0, 4), piece(4, 9), piece(9, 10)];
1575 let built = laid(&LogicalType::BigInt, &pieces);
1576 assert_eq!(built.form(), Form::Flat, "a run of flat pieces lays flat");
1577 let window = built.slice(4, 5).expect("a window into the page");
1580 assert_eq!(values(&window), all_of(&pieces[1..2]), "the second piece, cut back out");
1581 }
1582
1583 #[test]
1586 fn neighbouring_windows_of_one_page_lay_without_a_copy() {
1587 let held: Vec<Value> =
1588 (0..20).map(|at| if at % 7 == 3 { Value::Null } else { Value::BigInt(at) }).collect();
1589 let page = Vector::from_values(LogicalType::BigInt, &held).expect("a run").into_pages();
1590 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1591 let address = |vector: &Vector| match vector.data() {
1592 Some(Data::Int64(run)) => run.as_slice().as_ptr() as usize,
1593 other => panic!("a bigint run laid as {other:?}"),
1594 };
1595 let built = laid(&LogicalType::BigInt, &[cut(2, 5), cut(7, 8), cut(15, 3)]);
1596 assert_eq!(address(&built), address(&page) + 2 * 8, "the neighbours were copied");
1597 let other = Vector::from_values(LogicalType::BigInt, &held).expect("a run").into_pages();
1599 let other_cut = other.slice(7, 3).expect("a window");
1600 for pieces in [
1601 vec![cut(2, 5), cut(8, 3)],
1602 vec![cut(7, 3), cut(2, 5)],
1603 vec![cut(2, 5), other_cut],
1604 vec![Vector::from_values(LogicalType::BigInt, &held[..4]).expect("owned"), cut(4, 2)],
1605 ] {
1606 let built = laid(&LogicalType::BigInt, &pieces);
1607 assert_ne!(address(&built), address(&page) + 2 * 8, "a copy was expected");
1608 }
1609 }
1610
1611 #[test]
1614 fn neighbouring_cuts_of_a_paged_string_column_lay_without_a_copy() {
1615 let held: Vec<Value> = (0..20)
1616 .map(|at| Value::Varchar(format!("a string long enough for the arena {at}")))
1617 .collect();
1618 let page = Vector::from_values(LogicalType::Varchar, &held).expect("a run").into_pages();
1619 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1620 let views = |vector: &Vector| match vector.data() {
1621 Some(Data::Varlen(column)) => column.views().as_ptr() as usize,
1622 other => panic!("a varchar run laid as {other:?}"),
1623 };
1624 let built = laid(&LogicalType::Varchar, &[cut(2, 5), cut(7, 8), cut(15, 3)]);
1625 assert_eq!(views(&built), views(&page) + 2 * size_of::<StringView>(), "views copied");
1626 let owned = Vector::from_values(LogicalType::Varchar, &held).expect("a run");
1627 let copied = laid(&LogicalType::Varchar, &[owned.slice(0, 4).expect("a cut"), cut(4, 2)]);
1628 assert_eq!(copied.len(), 6);
1629 }
1630
1631 #[test]
1632 fn a_null_in_a_piece_is_a_null_in_the_same_row_of_the_page() {
1633 let ty = LogicalType::Integer;
1634 let whole = Vector::from_values(ty.clone(), &[Value::Integer(1), Value::Integer(2)])
1635 .expect("no nulls");
1636 let holed =
1637 Vector::from_values(ty.clone(), &[Value::Null, Value::Integer(4)]).expect("one null");
1638 let built = laid(&ty, &[whole.clone(), holed.clone()]);
1639 assert!(!built.is_null_at(1), "a row that was not null became one");
1640 assert!(built.is_null_at(2), "the null did not come through");
1641 let clean = laid(&ty, &[whole.clone(), whole]);
1643 assert_eq!(clean.validity(), &Validity::AllValid, "a mask nothing needed");
1644 let empty = laid(&ty, &[holed.clone(), holed]);
1645 assert!(empty.is_null_at(0) && empty.is_null_at(2), "both nulls came through");
1646 }
1647
1648 #[test]
1650 fn strings_lay_into_one_arena_and_come_back_as_views() {
1651 let ty = LogicalType::Varchar;
1652 let word = |text: &str| {
1653 Vector::from_values(ty.clone(), &[Value::Varchar(text.to_string())]).expect("a string")
1654 };
1655 let pieces = [word("a string too long to sit inside a view"), word("short")];
1656 let built = laid(&ty, &pieces);
1657 assert_eq!(
1658 built.form(),
1659 Form::StringView,
1660 "a varchar page that is not views cuts by copying"
1661 );
1662 let window = built.slice(0, 1).expect("a window into the page");
1663 assert_eq!(values(&window), all_of(&pieces[..1]), "the long string, cut back out");
1664 }
1665
1666 #[test]
1667 fn stable_dictionary_pieces_sharing_values_lay_as_codes() {
1668 let ty = LogicalType::Varchar;
1669 let values = Arc::new(
1670 Vector::from_values(
1671 ty.clone(),
1672 &[Value::Varchar("a".to_string()), Value::Varchar("b".to_string())],
1673 )
1674 .expect("dictionary values"),
1675 );
1676 let first = Vector::stable_dictionary(vec![1, 0], Arc::clone(&values)).expect("codes");
1677 let second = Vector::stable_dictionary(vec![1], Arc::clone(&values)).expect("codes");
1678 let built = concat(&ty, &[first, second]).expect("no error").expect("shared codes lay");
1679 let (codes, held) = built.stable_dictionary_parts().expect("the stable form survives");
1680 assert_eq!(codes, &[1, 0, 1]);
1681 assert!(Arc::ptr_eq(held, &values));
1682 }
1683
1684 #[test]
1686 fn an_encoded_piece_is_left_alone_rather_than_flattened() {
1687 let ty = LogicalType::BigInt;
1688 let flat = Vector::from_values(ty.clone(), &[Value::BigInt(1)]).expect("a flat piece");
1689 let values = Vector::from_values(ty.clone(), &[Value::BigInt(7), Value::BigInt(8)])
1690 .expect("two distinct values");
1691 let coded = Vector::dictionary(vec![0, 1, 0], values).expect("a dictionary piece");
1692 let one = std::slice::from_ref(&coded);
1693 assert!(concat(&ty, one).expect("no error").is_none(), "a dictionary laid");
1694 assert!(
1695 concat(&ty, &[flat.clone(), coded]).expect("no error").is_none(),
1696 "a mixed run laid"
1697 );
1698 assert!(
1699 concat::<Vector>(&ty, &[]).expect("no error").is_none(),
1700 "nothing laid into something"
1701 );
1702 let other =
1705 Vector::from_values(LogicalType::Integer, &[Value::Integer(1)]).expect("an int");
1706 assert!(concat(&ty, &[flat, other]).expect("no error").is_none(), "two types laid");
1707 }
1708
1709 fn on_a_thread_each(count: usize, task: &(dyn Fn(usize) + Sync)) -> Result<()> {
1716 std::thread::scope(|scope| {
1717 let running: Vec<_> =
1718 (0..count).rev().map(|at| scope.spawn(move || task(at))).collect();
1719 for thread in running {
1720 thread.join().expect("a piece copier panicked");
1721 }
1722 });
1723 Ok(())
1724 }
1725
1726 fn owned_strings(pieces: usize, each: usize) -> Vec<Vector> {
1731 (0..pieces)
1732 .map(|piece| {
1733 let held: Vec<Value> = (0..each)
1734 .map(|row| match (piece + row) % 4 {
1735 0 => Value::Null,
1736 1 => Value::Varchar(format!("short {row}")),
1737 _ => Value::Varchar(format!(
1738 "a string of piece {piece} row {row} that is well past twelve bytes"
1739 )),
1740 })
1741 .collect();
1742 Vector::from_values(LogicalType::Varchar, &held).expect("a run of strings")
1743 })
1744 .collect()
1745 }
1746
1747 #[test]
1748 fn string_pieces_laid_on_many_threads_hold_the_same_strings_as_laid_on_one() {
1749 let ty = LogicalType::Varchar;
1750 let pieces = owned_strings(9, 7);
1751 let borrowed: Vec<&Vector> = pieces.iter().collect();
1755 assert!(apart(&ty, &borrowed).is_some(), "the parallel lay declined its own case");
1756 let serial = concat(&ty, &pieces).expect("no error").expect("owned arenas lay");
1757 let parallel = concat_on(&ty, &pieces, &on_a_thread_each)
1758 .expect("no error")
1759 .expect("owned arenas lay");
1760 assert_eq!(parallel.len(), serial.len(), "the row count");
1761 assert_eq!(values(¶llel), all_of(&pieces), "the values laid end to end");
1762 assert_eq!(values(¶llel), values(&serial), "the two paths disagree");
1763 assert_eq!(parallel.form(), serial.form(), "a different body came out");
1766 }
1767
1768 #[test]
1770 fn a_run_the_parallel_lay_does_not_own_is_left_to_the_serial_one() {
1771 let ty = LogicalType::Varchar;
1772 let pieces = owned_strings(3, 5);
1773 assert!(apart(&ty, &[&pieces[0]]).is_none(), "one piece was taken");
1774 let page = concat(&ty, &pieces).expect("no error").expect("a page").into_pages();
1777 let cut = |from: usize, len: usize| page.slice(from, len).expect("a window");
1778 let cuts = [cut(0, 4), cut(4, 6), cut(10, 5)];
1779 let borrowed: Vec<&Vector> = cuts.iter().collect();
1780 assert!(apart(&ty, &borrowed).is_none(), "cuts of one page were taken");
1781 let serial = concat(&ty, &cuts).expect("no error").expect("shared views lay");
1784 let parallel =
1785 concat_on(&ty, &cuts, &on_a_thread_each).expect("no error").expect("shared views");
1786 assert_eq!(values(¶llel), values(&serial), "the fall through changed the answer");
1787 }
1788
1789 #[test]
1792 fn a_piece_holding_more_arena_than_it_reads_is_left_to_the_serial_lay() {
1793 let ty = LogicalType::Varchar;
1794 let pieces = owned_strings(2, 8);
1795 let page = concat(&ty, &pieces).expect("no error").expect("a page");
1796 let thin = page.slice(2, 1).expect("a window").flatten().expect("flattened");
1799 let fat = page.slice(3, 1).expect("a window").flatten().expect("flattened");
1800 let held = [thin, fat];
1801 let borrowed: Vec<&Vector> = held.iter().collect();
1802 if borrowed.iter().all(|piece| match piece.data() {
1803 Some(Data::Varlen(column)) => !column.mostly_read(),
1804 _ => false,
1805 }) {
1806 assert!(apart(&ty, &borrowed).is_none(), "a mostly unread arena was taken");
1807 }
1808 let serial = concat(&ty, &held).expect("no error").expect("flat pieces lay");
1809 let parallel =
1810 concat_on(&ty, &held, &on_a_thread_each).expect("no error").expect("flat pieces");
1811 assert_eq!(values(¶llel), values(&serial), "the two paths disagree");
1812 }
1813
1814 #[test]
1818 fn fixed_width_pieces_laid_on_many_threads_hold_the_same_values_as_laid_on_one() {
1819 for ty in [LogicalType::BigInt, LogicalType::Integer, LogicalType::Double] {
1820 let pieces: Vec<Vector> = (0..9_i32)
1821 .map(|piece| {
1822 let rows = if piece == 4 { 1_234 } else { TILED_ROWS / 8 + 7 };
1823 let held: Vec<Value> = (0..rows)
1824 .map(|row| {
1825 let n = piece * 100_000 + i32::try_from(row).expect("fits");
1826 if piece % 3 == 1 && n % 5 == 0 {
1827 return Value::Null;
1828 }
1829 match ty {
1830 LogicalType::BigInt => Value::BigInt(i64::from(n)),
1831 LogicalType::Integer => Value::Integer(n),
1832 _ => Value::Double(f64::from(n) / 4.0),
1833 }
1834 })
1835 .collect();
1836 Vector::from_values(ty.clone(), &held).expect("a run of values")
1837 })
1838 .collect();
1839 let borrowed: Vec<&Vector> = pieces.iter().collect();
1840 let wide = tiled(&ty, &borrowed, &on_a_thread_each).expect("no error");
1841 let wide = wide.expect("long flat pieces are taken");
1842 let serial = concat(&ty, &pieces).expect("no error").expect("flat pieces lay");
1843 assert_eq!(values(&wide), all_of(&pieces), "{ty:?} laid end to end");
1844 assert_eq!(values(&wide), values(&serial), "{ty:?} the two paths disagree");
1845 let parallel = concat_on(&ty, &pieces, &on_a_thread_each).expect("no error");
1846 assert_eq!(
1847 values(¶llel.expect("lays")),
1848 values(&serial),
1849 "{ty:?} through concat_on"
1850 );
1851 assert!(tiled(&ty, &borrowed[..2], &on_a_thread_each).expect("no error").is_none());
1853 assert!(tiled(&ty, &borrowed[..1], &on_a_thread_each).expect("no error").is_none());
1854 }
1855 }
1856
1857 #[test]
1860 fn an_interleave_reads_the_pieces_in_the_order_it_is_given() {
1861 let words: Vec<Value> = ["a long enough word to leave the inline view", "b", "c"]
1862 .iter()
1863 .map(|word| Value::Varchar((*word).to_string()))
1864 .collect();
1865 let dictionary = Vector::from_values(LogicalType::Varchar, &words).expect("words");
1866 let strings = [
1867 Vector::dictionary(vec![2, 0, 1], dictionary).expect("a dictionary"),
1868 Vector::from_values(
1869 LogicalType::Varchar,
1870 &[Value::Null, Value::Varchar("another string past twelve bytes".to_string())],
1871 )
1872 .expect("flat"),
1873 ];
1874 let numbers = [
1875 Vector::from_values(
1876 LogicalType::BigInt,
1877 &[Value::BigInt(7), Value::Null, Value::BigInt(9)],
1878 )
1879 .expect("flat"),
1880 Vector::constant(LogicalType::BigInt, Value::BigInt(4), 1),
1881 Vector::constant(LogicalType::BigInt, Value::Null, 1),
1882 ];
1883 let lists = [
1884 Vector::from_values(
1885 LogicalType::List(Box::new(LogicalType::Integer)),
1886 &[
1887 Value::List { element: LogicalType::Integer, values: vec![Value::Integer(1)] },
1888 Value::Null,
1889 Value::List { element: LogicalType::Integer, values: vec![] },
1890 ],
1891 )
1892 .expect("lists"),
1893 Vector::from_values(
1894 LogicalType::List(Box::new(LogicalType::Integer)),
1895 &[
1896 Value::List {
1897 element: LogicalType::Integer,
1898 values: vec![Value::Integer(2), Value::Integer(3)],
1899 },
1900 Value::Null,
1901 ],
1902 )
1903 .expect("lists"),
1904 ];
1905 let order = [4, 0, 3, 1, 2, 3];
1906 for pieces in [&strings[..], &numbers[..], &lists[..]] {
1907 let ty = pieces[0].logical_type().clone();
1908 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
1909 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
1910 let got = interleave(&ty, pieces, &order).expect("an interleave");
1911 assert_eq!(values(&got), expected, "{ty}");
1912 }
1913 assert!(interleave(&LogicalType::BigInt, &numbers, &[5]).is_err(), "row 5 of 5 rows");
1914 let order = [4, 0, 3, 1, 2];
1917 let mut inverse = [0u32; 5];
1918 for (at, &row) in order.iter().enumerate() {
1919 inverse[row] = at as u32;
1920 }
1921 let texts: Vec<Value> = ["a string past the twelve bytes of a view", "short", "x"]
1922 .iter()
1923 .map(|text| Value::Varchar((*text).to_string()))
1924 .chain([Value::Varchar("another long string for the arena".to_string())])
1925 .collect();
1926 let valid = [
1927 Vector::from_values(LogicalType::Varchar, &texts[..2]).expect("flat"),
1928 Vector::from_values(LogicalType::Varchar, &texts[2..]).expect("flat"),
1929 Vector::constant(LogicalType::Varchar, Value::Varchar("one more".to_string()), 1),
1930 ];
1931 for pieces in [&strings[..], &numbers[..], &lists[..], &valid[..]] {
1932 let ty = pieces[0].logical_type().clone();
1933 let pulled = interleave(&ty, pieces, &order).expect("an interleave");
1934 let pushed =
1935 interleave_placed(&ty, pieces, &order, Some(&inverse)).expect("a placed one");
1936 assert_eq!(values(&pushed), values(&pulled), "{ty}");
1937 }
1938 assert!(
1939 interleave_placed(&LogicalType::BigInt, &numbers, &order, Some(&inverse[..4])).is_err(),
1940 "four places for five rows"
1941 );
1942 let untyped = [Vector::constant(LogicalType::Null, Value::Null, 3)];
1943 let got = interleave(&LogicalType::Null, &untyped, &[2, 0]).expect("an untyped null");
1944 assert_eq!(values(&got), vec![Value::Null, Value::Null]);
1945 }
1946
1947 #[test]
1950 fn a_fixed_width_column_is_written_to_its_places_from_pieces_of_any_form() {
1951 let ty = LogicalType::BigInt;
1952 let int = Value::BigInt;
1953 let flat = Vector::from_values(ty.clone(), &[int(1), Value::Null, int(3)]).expect("flat");
1954 let paged = Vector::from_values(ty.clone(), &[int(4), int(5)]).expect("flat").into_pages();
1955 let words = Vector::from_values(ty.clone(), &[int(70), int(80)]).expect("values");
1956 let coded = Vector::dictionary(vec![1, 0, 1], words).expect("coded");
1957 let nulled = Vector::from_values(ty.clone(), &[int(90), Value::Null]).expect("values");
1958 let chained = Vector::dictionary(vec![1, 0], nulled).expect("coded over nulls");
1959 let constant = Vector::constant(ty.clone(), int(6), 2);
1960 let pieces = [flat, paged, coded, chained, constant];
1961 let rows: usize = pieces.iter().map(Vector::len).sum();
1962 let order: Vec<usize> = (0..rows).map(|at| (at * 5 + 3) % rows).collect();
1963 let mut inverse = vec![0u32; rows];
1964 for (to, &from) in order.iter().enumerate() {
1965 inverse[from] = u32::try_from(to).expect("a small row");
1966 }
1967 let read = interleave_placed(&ty, &pieces, &order, None).expect("read through order");
1968 let written =
1969 interleave_placed(&ty, &pieces, &order, Some(&inverse)).expect("written to places");
1970 assert_eq!(values(&written), values(&read));
1971 assert_eq!(values(&written)[inverse[1] as usize], Value::Null, "the flat piece's null");
1972 assert_eq!(values(&written)[inverse[8] as usize], Value::Null, "the dictionary's null");
1973
1974 let nothing = Vector::from_values(ty.clone(), &[Value::Null, Value::Null]).expect("nulls");
1975 let written = interleave_placed(&ty, &[nothing], &[1, 0], Some(&[1, 0])).expect("nulls");
1976 assert_eq!(values(&written), [Value::Null, Value::Null]);
1977 }
1978
1979 #[test]
1980 fn placed_strings_are_laid_in_the_order_of_the_result() {
1981 let word = |text: &str| Value::Varchar(text.to_string());
1982 let flat = Vector::from_values(
1983 LogicalType::Varchar,
1984 &[word("the first string past twelve bytes"), Value::Null, word("short")],
1985 )
1986 .expect("flat");
1987 let arena = b"xxa second string past twelve bytesyy".to_vec();
1988 let views = vec![StringView::over(&arena[2..35], 2), StringView::inline("tiny")];
1989 let viewed =
1990 Vector::string_views(LogicalType::Varchar, views, Arc::new(Buffer::from_vec(arena)))
1991 .expect("views");
1992 let pieces = [flat, viewed];
1993 let order = [3, 0, 4, 2, 1];
1994 let mut inverse = vec![0u32; order.len()];
1995 for (to, &from) in order.iter().enumerate() {
1996 inverse[from] = u32::try_from(to).expect("a small row");
1997 }
1998 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
1999 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
2000 let got = interleave_placed(&LogicalType::Varchar, &pieces, &order, Some(&inverse))
2001 .expect("a placed interleave");
2002 assert_eq!(values(&got), expected);
2003 let (_, arena) = got.text_parts().expect("views");
2004 assert_eq!(
2005 arena, b"a second string past twelve bytesthe first string past twelve bytes",
2006 "the long strings in the order they come out, and nothing else"
2007 );
2008 assert!(strings_placeable(&LogicalType::Varchar, &pieces));
2009 for split in 0..=order.len() {
2010 let mut joined = Vec::new();
2011 for range in [0..split, split..order.len()] {
2012 let part = placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, range)
2013 .expect("a range of rows");
2014 joined.extend(values(&part));
2015 }
2016 assert_eq!(joined, expected, "split at {split}");
2017 }
2018 let (_, arena) = placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, 1..3)
2019 .expect("the middle rows")
2020 .text_parts()
2021 .map(|(views, arena)| (views.len(), arena.to_vec()))
2022 .expect("views");
2023 assert_eq!(arena, b"the first string past twelve bytes", "only the range's own strings");
2024 assert!(placed_string_rows(&LogicalType::Varchar, &pieces, &inverse, 4..6).is_err());
2025 }
2026
2027 #[test]
2028 fn an_interleave_of_dictionaries_merges_them_into_one() {
2029 let word = |text: &str| Value::Varchar(text.to_string());
2030 let first = [word("MAIL"), word("a word long enough to leave the inline view")];
2031 let second = [Value::Null, word("MAIL"), word("SHIP")];
2032 let first = Arc::new(Vector::from_values(LogicalType::Varchar, &first).expect("words"));
2033 let second = Arc::new(Vector::from_values(LogicalType::Varchar, &second).expect("words"));
2034 let over = |codes: Vec<u32>, dictionary: &Arc<Vector>| {
2035 Vector::dictionary_over(codes, Arc::clone(dictionary)).expect("a dictionary")
2036 };
2037 let pieces = [
2038 over((0..16).map(|row| row % 2).collect(), &first),
2039 over((0..16).map(|row| row % 3).collect(), &second),
2040 over(vec![1; 8], &first),
2041 ];
2042 let order: Vec<usize> = (0..40).rev().collect();
2043 let laid: Vec<Value> = pieces.iter().flat_map(values).collect();
2044 let expected: Vec<Value> = order.iter().map(|&index| laid[index].clone()).collect();
2045 let got = interleave(&LogicalType::Varchar, &pieces, &order).expect("an interleave");
2046 assert_eq!(values(&got), expected);
2047 let (_, merged) = got.stable_dictionary_parts().expect("one stable dictionary");
2048 assert_eq!(merged.len(), 4, "MAIL once, the long word, the null and SHIP");
2049 let mut inverse = vec![0u32; order.len()];
2050 for (to, &from) in order.iter().enumerate() {
2051 inverse[from] = u32::try_from(to).expect("a small row");
2052 }
2053 let placed = interleave_placed(&LogicalType::Varchar, &pieces, &order, Some(&inverse))
2054 .expect("a placed interleave");
2055 assert_eq!(values(&placed), expected, "placed codes land where pulled ones do");
2056 assert!(placed.stable_dictionary_parts().is_some(), "and stay one dictionary");
2057
2058 let mixed = [pieces[0].clone(), pieces[1].flatten().expect("flat")];
2059 let got = interleave(&LogicalType::Varchar, &mixed, &order[8..]).expect("an interleave");
2060 assert!(got.dictionary_parts().is_none(), "a flat piece gathers flat");
2061 let few = &pieces[..1];
2062 let got = interleave(&LogicalType::Varchar, few, &[3, 2]).expect("an interleave");
2063 assert_eq!(
2064 values(&got),
2065 vec![word("a word long enough to leave the inline view"), word("MAIL")]
2066 );
2067 }
2068
2069 #[test]
2070 fn a_pick_takes_each_row_from_the_source_it_names_and_is_null_where_none_is_named() {
2071 let ty = LogicalType::Integer;
2072 let left =
2073 Vector::from_values(ty.clone(), &[Value::Integer(1), Value::Null, Value::Integer(3)])
2074 .expect("left");
2075 let right = Vector::from_values(ty.clone(), &[Value::Integer(10), Value::Integer(20)])
2076 .expect("right");
2077 let picks = [(1, 1), (0, 0), (crate::NO_ROW, 0), (0, 1), (1, 0), (0, 2)];
2078 let out = picked(&ty, &[&left, &right], &picks).expect("picks").expect("flat sources");
2079 assert_eq!(
2080 values(&out),
2081 vec![
2082 Value::Integer(20),
2083 Value::Integer(1),
2084 Value::Null,
2085 Value::Null,
2086 Value::Integer(10),
2087 Value::Integer(3),
2088 ]
2089 );
2090 let word = |text: &str| Value::Varchar(text.to_string());
2091 let words =
2092 Vector::from_values(LogicalType::Varchar, &[word("a"), word("bb")]).expect("words");
2093 let out = picked(&LogicalType::Varchar, &[&words], &[(0, 1), (0, 0), (0, 1)])
2094 .expect("picks")
2095 .expect("flat source");
2096 assert_eq!(values(&out), vec![word("bb"), word("a"), word("bb")]);
2097 let coded = Vector::dictionary(vec![1, 1, 0], words.clone()).expect("a dictionary");
2098 let out = picked(&LogicalType::Varchar, &[&words, &coded], &[(1, 2), (0, 0), (1, 0)])
2099 .expect("picks")
2100 .expect("flat and dictionary sources");
2101 assert_eq!(values(&out), vec![word("a"), word("a"), word("bb")]);
2102 }
2103
2104 #[test]
2107 fn picks_over_one_shared_dictionary_stay_codes() {
2108 let word = |text: &str| Value::Varchar(text.to_string());
2109 let words = Arc::new(
2110 Vector::from_values(LogicalType::Varchar, &[word("a"), word("bb")]).expect("words"),
2111 );
2112 let first = Vector::stable_dictionary(vec![1, 0], Arc::clone(&words)).expect("codes");
2113 let second = Vector::stable_dictionary(vec![0, 1], Arc::clone(&words))
2114 .expect("codes")
2115 .with_validity(Validity::from_run(&[true, false]));
2116 let picks = [(1, 0), (0, 0), (crate::NO_ROW, 0), (1, 1), (0, 1)];
2117 let out = picked(&LogicalType::Varchar, &[&first, &second], &picks)
2118 .expect("picks")
2119 .expect("coded sources");
2120 let (_, held) = out.stable_dictionary_parts().expect("still codes");
2121 assert!(Arc::ptr_eq(held, &words), "the codes point somewhere else");
2122 assert_eq!(values(&out), vec![word("a"), word("bb"), Value::Null, Value::Null, word("a")]);
2123 let other = Arc::new(Vector::clone(&words));
2124 let apart = Vector::stable_dictionary(vec![1, 0], other).expect("codes");
2125 let out = picked(&LogicalType::Varchar, &[&first, &apart], &[(1, 0), (0, 0)])
2126 .expect("picks")
2127 .expect("dictionary sources");
2128 assert!(out.stable_dictionary_parts().is_none(), "two dictionaries are not one");
2129 assert_eq!(values(&out), vec![word("bb"), word("bb")]);
2130 }
2131}