1use std::sync::Arc;
19
20use rudb_common::{Error, LogicalType, Result, Value};
21
22use crate::buffer::Buffer;
23use crate::string::{StringColumn, StringView};
24use crate::validity::Validity;
25
26pub const VECTOR_SIZE: usize = 1024;
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47#[non_exhaustive]
48pub enum Form {
49 Flat,
51 Constant,
53 Sequence,
55 Dictionary,
57}
58
59#[derive(Debug, Clone, PartialEq)]
64#[non_exhaustive]
65pub enum Data {
66 Empty,
68 Bool(Buffer<bool>),
70 Int8(Buffer<i8>),
72 Int16(Buffer<i16>),
74 Int32(Buffer<i32>),
76 Int64(Buffer<i64>),
78 Int128(Buffer<i128>),
80 UInt8(Buffer<u8>),
82 UInt16(Buffer<u16>),
84 UInt32(Buffer<u32>),
86 UInt64(Buffer<u64>),
88 UInt128(Buffer<u128>),
90 Float32(Buffer<f32>),
92 Float64(Buffer<f64>),
94 Interval(Buffer<(i32, i32, i64)>),
96 Varlen(StringColumn),
98}
99
100impl Data {
101 #[must_use]
108 pub fn len(&self) -> usize {
109 macro_rules! lengths {
110 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
111 match self {
112 Self::Empty => 0,
113 $(Self::$variant(values) => values.len(),)+
114 }
115 };
116 }
117 crate::for_each_layout!(all, lengths)
118 }
119
120 #[must_use]
122 pub fn is_empty(&self) -> bool {
123 self.len() == 0
124 }
125
126 #[must_use]
131 pub fn signed_at(&self, index: usize) -> Option<i128> {
132 macro_rules! widened {
133 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
134 match self {
135 $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
136 _ => None,
137 }
138 };
139 }
140 crate::for_each_layout!(signed, widened)
141 }
142
143 #[must_use]
145 pub fn unsigned_at(&self, index: usize) -> Option<u128> {
146 macro_rules! widened {
147 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
148 match self {
149 $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
150 _ => None,
151 }
152 };
153 }
154 crate::for_each_layout!(unsigned, widened)
155 }
156
157 #[must_use]
159 pub fn str_at(&self, index: usize) -> Option<&str> {
160 match self {
161 Self::Varlen(column) => column.get(index),
162 _ => None,
163 }
164 }
165
166 #[must_use]
171 pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
172 match self {
173 Self::Varlen(column) => column.bytes(index),
174 _ => None,
175 }
176 }
177}
178
179#[derive(Debug, Clone, PartialEq)]
181pub struct Vector {
182 ty: LogicalType,
183 len: usize,
184 validity: Validity,
185 body: Body,
186}
187
188#[derive(Debug, Clone, PartialEq)]
190enum Body {
191 Flat(Data),
192 Constant(Box<Value>),
193 Sequence {
194 start: i64,
195 step: i64,
196 },
197 Dictionary {
207 codes: Vec<u32>,
208 values: Arc<Vector>,
209 },
210}
211
212impl Vector {
213 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
221 let len = data.len();
222 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
223 return Err(Error::internal(format!(
224 "a {ty} vector cannot hold {:?} data",
225 layout_of(&data)
226 )));
227 }
228 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
229 }
230
231 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
243 let mut data = empty_data_for(&ty)?;
244 for value in values {
245 push_value(&mut data, value)?;
246 }
247 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
248 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
249 }
250
251 #[must_use]
256 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
257 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
258 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
259 }
260
261 #[must_use]
266 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
267 Self {
268 ty: LogicalType::BigInt,
269 len,
270 validity: Validity::AllValid,
271 body: Body::Sequence { start, step },
272 }
273 }
274
275 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
305 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
306 return Err(Error::internal(format!(
307 "dictionary code {bad} is past the end of a {} value dictionary",
308 values.len()
309 )));
310 }
311 let (codes, values) = compose(codes, values);
312 Ok(Self {
313 ty: values.ty.clone(),
314 len: codes.len(),
315 validity: Validity::AllValid,
316 body: Body::Dictionary { codes, values: Arc::new(values) },
317 })
318 }
319
320 #[must_use]
322 pub fn with_validity(mut self, validity: Validity) -> Self {
323 self.validity = validity;
324 self
325 }
326
327 #[must_use]
329 pub fn logical_type(&self) -> &LogicalType {
330 &self.ty
331 }
332
333 #[must_use]
335 pub fn len(&self) -> usize {
336 self.len
337 }
338
339 #[must_use]
341 pub fn is_empty(&self) -> bool {
342 self.len == 0
343 }
344
345 #[must_use]
347 pub fn validity(&self) -> &Validity {
348 &self.validity
349 }
350
351 #[must_use]
353 pub fn form(&self) -> Form {
354 match self.body {
355 Body::Flat(_) => Form::Flat,
356 Body::Constant(_) => Form::Constant,
357 Body::Sequence { .. } => Form::Sequence,
358 Body::Dictionary { .. } => Form::Dictionary,
359 }
360 }
361
362 #[must_use]
367 pub fn data(&self) -> Option<&Data> {
368 match &self.body {
369 Body::Flat(data) => Some(data),
370 _ => None,
371 }
372 }
373
374 #[must_use]
381 pub fn constant_value(&self) -> Option<&Value> {
382 match &self.body {
383 Body::Constant(value) => Some(value.as_ref()),
384 _ => None,
385 }
386 }
387
388 #[must_use]
402 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
403 match &self.body {
404 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
405 _ => None,
406 }
407 }
408
409 #[must_use]
411 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
412 match self.body {
413 Body::Sequence { start, step } => Some((start, step)),
414 _ => None,
415 }
416 }
417
418 #[must_use]
424 pub fn value_at(&self, index: usize) -> Value {
425 if index >= self.len || !self.validity.is_valid(index) {
426 return Value::Null;
427 }
428 match &self.body {
429 Body::Constant(value) => value.as_ref().clone(),
430 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
431 Body::Dictionary { codes, values } => match codes.get(index) {
432 Some(&code) => values.value_at(code as usize),
433 None => Value::Null,
434 },
435 Body::Flat(data) => value_from(&self.ty, data, index),
436 }
437 }
438
439 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
441 (0..self.len).map(|index| self.value_at(index))
442 }
443
444 pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
466 let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
467 if end > self.len {
468 return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
469 }
470 if at == 0 && len == self.len {
471 return Ok(self.clone());
472 }
473 let validity = Validity::from_iter(len, |row| self.validity.is_valid(at + row));
474 let body = match &self.body {
475 Body::Constant(value) => Body::Constant(value.clone()),
476 Body::Sequence { start, step } => {
477 Body::Sequence { start: start + step * at as i64, step: *step }
478 }
479 Body::Dictionary { codes, values } => {
480 Body::Dictionary { codes: codes[at..end].to_vec(), values: Arc::clone(values) }
481 }
482 Body::Flat(_) => {
486 let indices: Vec<u32> =
487 (at..end).map(|row| u32::try_from(row).unwrap_or(u32::MAX)).collect();
488 return self.gather(&indices);
489 }
490 };
491 Ok(Self { ty: self.ty.clone(), len, validity, body })
492 }
493
494 pub fn flatten(&self) -> Result<Self> {
505 if let Body::Flat(_) = self.body {
506 return Ok(self.clone());
507 }
508 self.copied((0..self.len).collect(), false)
509 }
510
511 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
527 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
528 }
529
530 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
537 let rows = at.len();
538 let (at, leaf) = self.resolve(at);
539 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
540 let validity = Validity::from_run(&live);
541 let body = match &leaf.body {
542 Body::Constant(value) => {
545 if constants_stay && matches!(validity, Validity::AllValid) {
546 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
547 }
548 let mut data = empty_data_for(&self.ty)?;
549 for &index in &at {
550 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
551 }
552 Body::Flat(data)
553 }
554 Body::Sequence { start, step } => Body::Flat(Data::Int64(
557 at.iter()
558 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
559 .collect(),
560 )),
561 Body::Flat(Data::Empty) => {
565 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
566 }
567 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
568 Body::Dictionary { .. } => {
570 return Err(Error::internal("a dictionary survived being resolved"));
571 }
572 };
573 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
574 }
575
576 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
582 let mut source = self;
583 loop {
584 for slot in &mut at {
585 if *slot >= source.len || !source.validity.is_valid(*slot) {
586 *slot = NOWHERE;
587 }
588 }
589 let Body::Dictionary { codes, values } = &source.body else {
590 return (at, source);
591 };
592 for slot in &mut at {
593 *slot = match codes.get(*slot) {
594 Some(&code) => code as usize,
595 None => NOWHERE,
596 };
597 }
598 source = values.as_ref();
599 }
600 }
601}
602
603impl AsRef<Vector> for Vector {
610 fn as_ref(&self) -> &Vector {
611 self
612 }
613}
614
615fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
627 if !matches!(values.validity, Validity::AllValid) {
630 return (codes, values);
631 }
632 let Vector { ty, len, validity, body } = values;
633 match body {
634 Body::Dictionary { codes: inner, values: leaf } => {
635 debug_assert!(
636 !matches!(leaf.body, Body::Dictionary { .. })
637 || !matches!(leaf.validity, Validity::AllValid),
638 "a dictionary was stacked on a dictionary without going through the constructor"
639 );
640 (codes.iter().map(|&code| inner[code as usize]).collect(), Arc::unwrap_or_clone(leaf))
645 }
646 body => (codes, Vector { ty, len, validity, body }),
647 }
648}
649
650const NOWHERE: usize = usize::MAX;
655
656fn copy_of(data: &Data, at: &[usize]) -> Data {
662 macro_rules! copied {
663 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
664 match data {
665 Data::Empty => Data::Empty,
666 $(Data::$variant(values) => {
667 let mut out = Buffer::with_capacity(at.len());
668 for &index in at {
669 out.push(values.get(index).copied().unwrap_or($zero));
672 }
673 Data::$variant(out)
674 })+
675 Data::Varlen(values) => {
679 let mut out = StringColumn::with_capacity(at.len());
680 let views = values.views();
685 out.reserve_bytes(
686 at.iter()
687 .filter_map(|&index| views.get(index))
688 .filter(|view| !view.is_inline())
689 .map(StringView::len)
690 .sum(),
691 );
692 for &index in at {
693 out.push_from(values, index);
694 }
695 Data::Varlen(out)
696 }
697 }
698 };
699 }
700 crate::for_each_layout!(fixed, copied)
701}
702
703fn layout_of(data: &Data) -> rudb_common::PhysicalType {
708 use rudb_common::PhysicalType as P;
709 macro_rules! layouts {
710 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
711 match data {
712 Data::Empty => P::Empty,
713 $(Data::$variant(_) => P::$variant,)+
714 }
715 };
716 }
717 crate::for_each_layout!(all, layouts)
718}
719
720fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
725 let signed = || data.signed_at(index);
726 let unsigned = || data.unsigned_at(index);
727 let value = match ty {
728 LogicalType::Boolean => match data {
729 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
730 _ => None,
731 },
732 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
733 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
734 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
735 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
736 LogicalType::HugeInt => signed().map(Value::HugeInt),
737 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
738 LogicalType::USmallInt => {
739 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
740 }
741 LogicalType::UInteger => {
742 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
743 }
744 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
745 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
746 LogicalType::Float => match data {
747 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
748 _ => None,
749 },
750 LogicalType::Double => match data {
751 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
752 _ => None,
753 },
754 LogicalType::Decimal { width, scale } => {
755 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
756 }
757 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
758 LogicalType::Blob | LogicalType::Bit => {
759 data.bytes_at(index).map(|bytes| Value::Blob(bytes.to_vec()))
760 }
761 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
762 LogicalType::Time | LogicalType::TimeTz => {
763 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
764 }
765 LogicalType::Timestamp
766 | LogicalType::TimestampS
767 | LogicalType::TimestampMs
768 | LogicalType::TimestampNs
769 | LogicalType::TimestampTz => {
770 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
771 }
772 LogicalType::Interval => match data {
773 Data::Interval(v) => {
774 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
775 }
776 _ => None,
777 },
778 _ => None,
779 };
780 value.unwrap_or(Value::Null)
781}
782
783fn empty_data_for(ty: &LogicalType) -> Result<Data> {
785 use rudb_common::PhysicalType as P;
786 macro_rules! empties {
787 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
788 match ty.physical() {
789 P::Empty => Data::Empty,
790 $(P::$variant => Data::$variant(Buffer::new()),)+
791 P::Varlen => Data::Varlen(StringColumn::new()),
792 other => {
793 return Err(Error::not_implemented(format!(
794 "a flat vector of {other:?} data, which arrives with the storage layer"
795 )));
796 }
797 }
798 };
799 }
800 Ok(crate::for_each_layout!(fixed, empties))
801}
802
803fn push_value(data: &mut Data, value: &Value) -> Result<()> {
808 macro_rules! push {
809 ($vec:expr, $variant:path, $zero:expr) => {
810 match value {
811 Value::Null => $vec.push($zero),
812 $variant(x) => $vec.push(*x),
813 other => {
814 return Err(Error::internal(format!(
815 "{other:?} does not belong in this vector"
816 )));
817 }
818 }
819 };
820 }
821 macro_rules! decimal {
827 ($vec:expr, $ty:ty, $unscaled:expr) => {
828 match <$ty>::try_from(*$unscaled) {
829 Ok(x) => $vec.push(x),
830 Err(_) => {
831 return Err(Error::internal(format!(
832 "an unscaled decimal of {} does not fit the run its precision chose",
833 $unscaled
834 )));
835 }
836 }
837 };
838 }
839 match data {
840 Data::Empty => {}
841 Data::Bool(v) => push!(v, Value::Boolean, false),
842 Data::Int8(v) => push!(v, Value::TinyInt, 0),
843 Data::Int16(v) => match value {
844 Value::Null => v.push(0),
845 Value::SmallInt(x) => v.push(*x),
846 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
847 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
848 },
849 Data::Int32(v) => match value {
850 Value::Null => v.push(0),
851 Value::Integer(x) | Value::Date(x) => v.push(*x),
852 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
853 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
854 },
855 Data::Int64(v) => match value {
856 Value::Null => v.push(0),
857 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
858 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
859 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
860 },
861 Data::Int128(v) => match value {
862 Value::Null => v.push(0),
863 Value::HugeInt(x) => v.push(*x),
864 Value::Decimal { unscaled, .. } => v.push(*unscaled),
865 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
866 },
867 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
868 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
869 Data::UInt32(v) => push!(v, Value::UInteger, 0),
870 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
871 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
872 Data::Float32(v) => push!(v, Value::Float, 0.0),
873 Data::Float64(v) => push!(v, Value::Double, 0.0),
874 Data::Interval(v) => match value {
875 Value::Null => v.push((0, 0, 0)),
876 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
877 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
878 },
879 Data::Varlen(column) => match value {
880 Value::Null => {
881 column.push("");
882 }
883 Value::Varchar(text) => {
884 column.push(text);
885 }
886 Value::Blob(bytes) => {
890 column.push_bytes(bytes);
891 }
892 other => return Err(Error::internal(format!("{other:?} is not a string"))),
893 },
894 }
895 Ok(())
896}
897
898#[cfg(test)]
899mod tests {
900 use std::sync::Arc;
901
902 use rudb_common::{LogicalType, Value};
903
904 use super::{Body, Data, Form, VECTOR_SIZE, Vector};
905 use crate::string::StringColumn;
906 use crate::validity::Validity;
907
908 fn integers(values: &[i32]) -> Vector {
909 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
910 }
911
912 #[test]
913 fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
914 let values = Vector::from_values(
915 LogicalType::Varchar,
916 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
917 )
918 .unwrap();
919 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
920
921 let piece = vector.slice(1, 3).unwrap();
922 assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
923 assert_eq!(piece.len(), 3);
924 assert_eq!(
925 piece.iter().collect::<Vec<_>>(),
926 [
927 Value::Varchar("blue".into()),
928 Value::Varchar("blue".into()),
929 Value::Varchar("red".into())
930 ]
931 );
932 assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
933 }
934
935 #[test]
936 fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
937 let values = Vector::from_values(
942 LogicalType::Varchar,
943 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
944 )
945 .unwrap();
946 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
947 let Body::Dictionary { values: whole, .. } = &vector.body else {
948 panic!("a dictionary vector holds a dictionary");
949 };
950
951 let piece = vector.slice(1, 3).unwrap();
952 let Body::Dictionary { codes, values: cut } = &piece.body else {
953 panic!("a slice of a dictionary is a dictionary");
954 };
955 assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
956 assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
957
958 let again = piece.slice(1, 2).unwrap();
960 let Body::Dictionary { values: cut, .. } = &again.body else {
961 panic!("a slice of a slice of a dictionary is a dictionary");
962 };
963 assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
964 assert_eq!(
965 again.iter().collect::<Vec<_>>(),
966 [Value::Varchar("blue".into()), Value::Varchar("red".into())]
967 );
968 }
969
970 #[test]
971 fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
972 let vector =
973 integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
974 let piece = vector.slice(1, 2).unwrap();
975 assert!(piece.validity().is_valid(0));
976 assert!(!piece.validity().is_valid(1));
977 assert_eq!(piece.value_at(1), Value::Null);
978 }
979
980 #[test]
981 fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
982 let vector = Vector::sequence(100, 5, 10);
983 let piece = vector.slice(3, 4).unwrap();
984 assert_eq!(piece.form(), Form::Sequence);
985 assert_eq!(
986 piece.iter().collect::<Vec<_>>(),
987 [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
988 );
989 }
990
991 #[test]
992 fn slicing_a_constant_is_a_shorter_constant() {
993 let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
994 let piece = vector.slice(2, 3).unwrap();
995 assert_eq!(piece.form(), Form::Constant);
996 assert_eq!(piece.len(), 3);
997 assert_eq!(piece.value_at(2), Value::Integer(9));
998 }
999
1000 #[test]
1001 fn slicing_the_whole_vector_hands_it_back_as_it_was() {
1002 let vector = integers(&[1, 2, 3]);
1003 assert_eq!(
1004 vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
1005 [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1006 );
1007 }
1008
1009 #[test]
1010 fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
1011 let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
1012 assert!(error.to_string().contains("of a vector of 3"), "{error}");
1013 }
1014
1015 #[test]
1016 fn the_vector_size_is_the_one_the_design_is_built_around() {
1017 assert_eq!(VECTOR_SIZE, 1024);
1020 assert_eq!(VECTOR_SIZE / 64, 16);
1021 }
1022
1023 #[test]
1024 fn a_flat_vector_reads_back_what_was_put_in_it() {
1025 let vector = integers(&[1, 2, 3]);
1026 assert_eq!(vector.form(), Form::Flat);
1027 assert_eq!(vector.len(), 3);
1028 assert_eq!(vector.value_at(1), Value::Integer(2));
1029 assert_eq!(
1030 vector.iter().collect::<Vec<_>>(),
1031 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1032 );
1033 }
1034
1035 #[test]
1036 fn a_vector_built_from_values_reads_the_same_values_back() {
1037 let vector = Vector::from_values(
1038 LogicalType::Varchar,
1039 &[
1040 Value::Varchar("a".to_string()),
1041 Value::Null,
1042 Value::Varchar("a string too long to sit inside a view".to_string()),
1043 ],
1044 )
1045 .expect("strings and a null");
1046 assert_eq!(vector.len(), 3);
1047 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
1048 assert_eq!(vector.value_at(1), Value::Null);
1049 assert_eq!(
1050 vector.value_at(2),
1051 Value::Varchar("a string too long to sit inside a view".to_string())
1052 );
1053 }
1054
1055 #[test]
1058 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
1059 let vector = Vector::from_values(
1060 LogicalType::Integer,
1061 &[Value::Integer(1), Value::Null, Value::Integer(3)],
1062 )
1063 .expect("integers and a null");
1064 assert_eq!(vector.value_at(2), Value::Integer(3));
1065 assert!(vector.validity().has_nulls(3), "the middle one is null");
1066 }
1067
1068 #[test]
1069 fn a_value_the_type_cannot_hold_is_refused() {
1070 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
1071 assert!(wrong.is_err(), "a string is not an integer");
1072 }
1073
1074 #[test]
1075 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
1076 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
1078 assert!(wrong.is_err());
1079 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
1080 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
1081 }
1082
1083 #[test]
1084 fn a_constant_vector_costs_one_value_whatever_its_length() {
1085 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
1086 assert_eq!(vector.form(), Form::Constant);
1087 assert_eq!(vector.len(), VECTOR_SIZE);
1088 assert_eq!(vector.value_at(0), Value::Integer(7));
1089 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
1090 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
1091 }
1092
1093 #[test]
1094 fn a_constant_null_is_all_invalid_without_being_told() {
1095 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
1096 assert_eq!(vector.validity(), &Validity::AllInvalid);
1097 assert_eq!(vector.value_at(3), Value::Null);
1098 }
1099
1100 #[test]
1101 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
1102 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
1103 assert_eq!(vector.form(), Form::Sequence);
1104 assert_eq!(vector.value_at(0), Value::BigInt(100));
1105 assert_eq!(vector.value_at(923), Value::BigInt(1023));
1106 let stepped = Vector::sequence(0, 5, 4);
1107 assert_eq!(
1108 stepped.iter().collect::<Vec<_>>(),
1109 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
1110 );
1111 }
1112
1113 #[test]
1114 fn a_dictionary_vector_reads_through_its_codes() {
1115 let mut column = StringColumn::new();
1116 column.push("red");
1117 column.push("green");
1118 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1119 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
1120 assert_eq!(vector.form(), Form::Dictionary);
1121 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
1122 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
1123 assert_eq!(vector.len(), 4);
1124 }
1125
1126 #[test]
1127 fn a_dictionary_code_past_the_end_is_refused() {
1128 let values = integers(&[1, 2]);
1131 assert!(Vector::dictionary(vec![0, 2], values).is_err());
1132 }
1133
1134 #[test]
1135 fn every_form_flattens_to_the_same_values_it_reads_out() {
1136 let mut column = StringColumn::new();
1140 column.push("alpha");
1141 column.push("beta");
1142 let dictionary = Vector::dictionary(
1143 vec![1, 0, 1],
1144 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1145 )
1146 .unwrap();
1147 let cases = [
1148 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
1149 Vector::sequence(7, -2, 5),
1150 dictionary,
1151 ];
1152 for vector in cases {
1153 let flat = vector.flatten().unwrap();
1154 assert_eq!(flat.form(), Form::Flat);
1155 assert_eq!(flat.len(), vector.len());
1156 for index in 0..vector.len() {
1157 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
1158 }
1159 }
1160 }
1161
1162 #[test]
1163 fn a_null_still_occupies_a_position_after_flattening() {
1164 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
1168 let flat = vector.flatten().unwrap();
1169 assert_eq!(flat.value_at(0), Value::BigInt(0));
1170 assert_eq!(flat.value_at(1), Value::Null);
1171 assert_eq!(flat.value_at(2), Value::BigInt(2));
1172 assert_eq!(flat.value_at(3), Value::BigInt(3));
1173 }
1174
1175 #[test]
1180 fn a_null_behind_a_dictionary_survives_flattening() {
1181 let values =
1182 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1183 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1184 let flat = dictionary.flatten().unwrap();
1185 assert_eq!(flat.value_at(0), Value::Null);
1186 assert_eq!(flat.value_at(1), Value::Integer(3));
1187 assert_eq!(flat.value_at(2), Value::Null);
1188 }
1189
1190 #[test]
1193 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1194 let mut column = StringColumn::new();
1195 column.push("alpha");
1196 column.push("beta");
1197 column.push("gamma");
1198 let cases = [
1199 integers(&[10, 20, 30, 40]),
1200 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1201 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1202 Vector::sequence(100, -7, 4),
1203 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1204 Vector::dictionary(
1205 vec![2, 0, 1, 2],
1206 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1207 )
1208 .unwrap(),
1209 Vector::dictionary(
1210 vec![1, 0, 1, 0],
1211 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1212 .unwrap(),
1213 )
1214 .unwrap(),
1215 ];
1216 let wanted = [3_u32, 0, 2, 2, 1];
1217 for vector in cases {
1218 let gathered = vector.gather(&wanted).unwrap();
1219 assert_eq!(gathered.len(), wanted.len());
1220 assert_eq!(gathered.logical_type(), vector.logical_type());
1221 for (slot, &index) in wanted.iter().enumerate() {
1222 assert_eq!(
1223 gathered.value_at(slot),
1224 vector.value_at(index as usize),
1225 "slot {slot} of {:?}",
1226 vector.form()
1227 );
1228 }
1229 }
1230 }
1231
1232 #[test]
1236 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1237 let vector = integers(&[1, 2, 3]);
1238 let gathered = vector.gather(&[2, 9]).unwrap();
1239 assert_eq!(gathered.value_at(0), Value::Integer(3));
1240 assert_eq!(gathered.value_at(1), Value::Null);
1241 }
1242
1243 #[test]
1247 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1248 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1249 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1250 assert_eq!(gathered.len(), 3);
1251 assert_eq!(gathered.value_at(0), Value::Null);
1252 assert_eq!(gathered.value_at(2), Value::Null);
1253 }
1254
1255 #[test]
1258 fn gathering_a_constant_stays_a_constant() {
1259 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1260 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1261 assert_eq!(gathered.form(), Form::Constant);
1262 assert_eq!(gathered.len(), 3);
1263 assert_eq!(gathered.value_at(2), Value::Integer(4));
1264 }
1265
1266 #[test]
1271 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1272 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1273 .unwrap()
1274 .with_validity(Validity::from_iter(3, |index| index != 2));
1275 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1276 let gathered = outer.gather(&[0, 1]).unwrap();
1277 assert_eq!(gathered.form(), Form::Flat);
1278 assert_eq!(gathered.value_at(0), Value::Integer(8));
1279 assert_eq!(gathered.value_at(1), Value::Null);
1280 }
1281
1282 #[test]
1287 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1288 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1289 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1290 let (codes, values) = outer.dictionary_parts().unwrap();
1291 assert_eq!(codes, [1, 0]);
1292 assert_eq!(values.form(), Form::Flat);
1293 assert_eq!(outer.value_at(0), Value::Integer(8));
1294 assert_eq!(outer.value_at(1), Value::Integer(7));
1295 }
1296
1297 #[test]
1300 fn stacking_dictionaries_does_not_make_them_deeper() {
1301 let mut vector = integers(&[10, 20, 30, 40]);
1302 for _ in 0..4 {
1303 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1304 }
1305 let (codes, values) = vector.dictionary_parts().unwrap();
1306 assert_eq!(values.form(), Form::Flat);
1307 assert_eq!(codes, [0, 1, 2, 3]);
1308 assert_eq!(
1309 vector.iter().collect::<Vec<_>>(),
1310 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1311 );
1312 }
1313
1314 #[test]
1317 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1318 let values =
1319 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1320 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1321 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1322 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1323 assert_eq!(outer.value_at(0), Value::Null);
1324 assert_eq!(outer.value_at(1), Value::Integer(3));
1325 }
1326
1327 #[test]
1331 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1332 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1333 .unwrap()
1334 .with_validity(Validity::from_iter(3, |index| index != 1));
1335 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1336 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1337 assert_eq!(outer.value_at(0), Value::Null);
1338 assert_eq!(outer.value_at(1), Value::Integer(3));
1339 assert_eq!(outer.value_at(2), Value::Integer(1));
1340 }
1341
1342 #[test]
1343 fn flattening_a_flat_vector_is_the_same_vector() {
1344 let vector = integers(&[1, 2, 3]);
1345 assert_eq!(vector.flatten().unwrap(), vector);
1346 }
1347
1348 #[test]
1349 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1350 let ty = LogicalType::decimal(9, 2).unwrap();
1351 let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
1352 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1353 assert_eq!(vector.value_at(0).to_string(), "12.34");
1354 }
1355
1356 #[test]
1357 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1358 for (width, scale, unscaled) in
1361 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1362 {
1363 let ty = LogicalType::decimal(width, scale).unwrap();
1364 let value = Value::Decimal { unscaled, width, scale };
1365 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1366 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1367 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1368 }
1369 }
1370
1371 #[test]
1376 fn a_blob_holds_bytes_that_are_not_text() {
1377 let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
1378 let values = [
1379 bytes(b"a\xffb"),
1380 bytes(b"\x00\x01\x02"),
1381 Value::Null,
1382 bytes(b"\xed\xa0\x80 and long enough to leave the view"),
1383 bytes(b""),
1384 ];
1385 let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
1386 for (index, value) in values.iter().enumerate() {
1387 assert_eq!(&vector.value_at(index), value, "row {index}");
1388 }
1389 }
1390
1391 #[test]
1392 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1393 let ty = LogicalType::decimal(4, 1).unwrap();
1396 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1397 let error = Vector::from_values(ty, &[value]).unwrap_err();
1398 assert!(error.to_string().contains("does not fit"), "{error}");
1399 }
1400}