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
167#[derive(Debug, Clone, PartialEq)]
169pub struct Vector {
170 ty: LogicalType,
171 len: usize,
172 validity: Validity,
173 body: Body,
174}
175
176#[derive(Debug, Clone, PartialEq)]
178enum Body {
179 Flat(Data),
180 Constant(Box<Value>),
181 Sequence {
182 start: i64,
183 step: i64,
184 },
185 Dictionary {
195 codes: Vec<u32>,
196 values: Arc<Vector>,
197 },
198}
199
200impl Vector {
201 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
209 let len = data.len();
210 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
211 return Err(Error::internal(format!(
212 "a {ty} vector cannot hold {:?} data",
213 layout_of(&data)
214 )));
215 }
216 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
217 }
218
219 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
231 let mut data = empty_data_for(&ty)?;
232 for value in values {
233 push_value(&mut data, value)?;
234 }
235 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
236 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
237 }
238
239 #[must_use]
244 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
245 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
246 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
247 }
248
249 #[must_use]
254 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
255 Self {
256 ty: LogicalType::BigInt,
257 len,
258 validity: Validity::AllValid,
259 body: Body::Sequence { start, step },
260 }
261 }
262
263 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
293 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
294 return Err(Error::internal(format!(
295 "dictionary code {bad} is past the end of a {} value dictionary",
296 values.len()
297 )));
298 }
299 let (codes, values) = compose(codes, values);
300 Ok(Self {
301 ty: values.ty.clone(),
302 len: codes.len(),
303 validity: Validity::AllValid,
304 body: Body::Dictionary { codes, values: Arc::new(values) },
305 })
306 }
307
308 #[must_use]
310 pub fn with_validity(mut self, validity: Validity) -> Self {
311 self.validity = validity;
312 self
313 }
314
315 #[must_use]
317 pub fn logical_type(&self) -> &LogicalType {
318 &self.ty
319 }
320
321 #[must_use]
323 pub fn len(&self) -> usize {
324 self.len
325 }
326
327 #[must_use]
329 pub fn is_empty(&self) -> bool {
330 self.len == 0
331 }
332
333 #[must_use]
335 pub fn validity(&self) -> &Validity {
336 &self.validity
337 }
338
339 #[must_use]
341 pub fn form(&self) -> Form {
342 match self.body {
343 Body::Flat(_) => Form::Flat,
344 Body::Constant(_) => Form::Constant,
345 Body::Sequence { .. } => Form::Sequence,
346 Body::Dictionary { .. } => Form::Dictionary,
347 }
348 }
349
350 #[must_use]
355 pub fn data(&self) -> Option<&Data> {
356 match &self.body {
357 Body::Flat(data) => Some(data),
358 _ => None,
359 }
360 }
361
362 #[must_use]
369 pub fn constant_value(&self) -> Option<&Value> {
370 match &self.body {
371 Body::Constant(value) => Some(value.as_ref()),
372 _ => None,
373 }
374 }
375
376 #[must_use]
390 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
391 match &self.body {
392 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
393 _ => None,
394 }
395 }
396
397 #[must_use]
399 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
400 match self.body {
401 Body::Sequence { start, step } => Some((start, step)),
402 _ => None,
403 }
404 }
405
406 #[must_use]
412 pub fn value_at(&self, index: usize) -> Value {
413 if index >= self.len || !self.validity.is_valid(index) {
414 return Value::Null;
415 }
416 match &self.body {
417 Body::Constant(value) => value.as_ref().clone(),
418 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
419 Body::Dictionary { codes, values } => match codes.get(index) {
420 Some(&code) => values.value_at(code as usize),
421 None => Value::Null,
422 },
423 Body::Flat(data) => value_from(&self.ty, data, index),
424 }
425 }
426
427 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
429 (0..self.len).map(|index| self.value_at(index))
430 }
431
432 pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
454 let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
455 if end > self.len {
456 return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
457 }
458 if at == 0 && len == self.len {
459 return Ok(self.clone());
460 }
461 let validity = Validity::from_iter(len, |row| self.validity.is_valid(at + row));
462 let body = match &self.body {
463 Body::Constant(value) => Body::Constant(value.clone()),
464 Body::Sequence { start, step } => {
465 Body::Sequence { start: start + step * at as i64, step: *step }
466 }
467 Body::Dictionary { codes, values } => {
468 Body::Dictionary { codes: codes[at..end].to_vec(), values: Arc::clone(values) }
469 }
470 Body::Flat(_) => {
474 let indices: Vec<u32> =
475 (at..end).map(|row| u32::try_from(row).unwrap_or(u32::MAX)).collect();
476 return self.gather(&indices);
477 }
478 };
479 Ok(Self { ty: self.ty.clone(), len, validity, body })
480 }
481
482 pub fn flatten(&self) -> Result<Self> {
493 if let Body::Flat(_) = self.body {
494 return Ok(self.clone());
495 }
496 self.copied((0..self.len).collect(), false)
497 }
498
499 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
515 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
516 }
517
518 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
525 let rows = at.len();
526 let (at, leaf) = self.resolve(at);
527 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
528 let validity = Validity::from_run(&live);
529 let body = match &leaf.body {
530 Body::Constant(value) => {
533 if constants_stay && matches!(validity, Validity::AllValid) {
534 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
535 }
536 let mut data = empty_data_for(&self.ty)?;
537 for &index in &at {
538 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
539 }
540 Body::Flat(data)
541 }
542 Body::Sequence { start, step } => Body::Flat(Data::Int64(
545 at.iter()
546 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
547 .collect(),
548 )),
549 Body::Flat(Data::Empty) => {
553 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
554 }
555 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
556 Body::Dictionary { .. } => {
558 return Err(Error::internal("a dictionary survived being resolved"));
559 }
560 };
561 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
562 }
563
564 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
570 let mut source = self;
571 loop {
572 for slot in &mut at {
573 if *slot >= source.len || !source.validity.is_valid(*slot) {
574 *slot = NOWHERE;
575 }
576 }
577 let Body::Dictionary { codes, values } = &source.body else {
578 return (at, source);
579 };
580 for slot in &mut at {
581 *slot = match codes.get(*slot) {
582 Some(&code) => code as usize,
583 None => NOWHERE,
584 };
585 }
586 source = values.as_ref();
587 }
588 }
589}
590
591impl AsRef<Vector> for Vector {
598 fn as_ref(&self) -> &Vector {
599 self
600 }
601}
602
603fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
615 if !matches!(values.validity, Validity::AllValid) {
618 return (codes, values);
619 }
620 let Vector { ty, len, validity, body } = values;
621 match body {
622 Body::Dictionary { codes: inner, values: leaf } => {
623 debug_assert!(
624 !matches!(leaf.body, Body::Dictionary { .. })
625 || !matches!(leaf.validity, Validity::AllValid),
626 "a dictionary was stacked on a dictionary without going through the constructor"
627 );
628 (codes.iter().map(|&code| inner[code as usize]).collect(), Arc::unwrap_or_clone(leaf))
633 }
634 body => (codes, Vector { ty, len, validity, body }),
635 }
636}
637
638const NOWHERE: usize = usize::MAX;
643
644fn copy_of(data: &Data, at: &[usize]) -> Data {
650 macro_rules! copied {
651 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
652 match data {
653 Data::Empty => Data::Empty,
654 $(Data::$variant(values) => {
655 let mut out = Buffer::with_capacity(at.len());
656 for &index in at {
657 out.push(values.get(index).copied().unwrap_or($zero));
660 }
661 Data::$variant(out)
662 })+
663 Data::Varlen(values) => {
667 let mut out = StringColumn::with_capacity(at.len());
668 let views = values.views();
673 out.reserve_bytes(
674 at.iter()
675 .filter_map(|&index| views.get(index))
676 .filter(|view| !view.is_inline())
677 .map(StringView::len)
678 .sum(),
679 );
680 for &index in at {
681 out.push_from(values, index);
682 }
683 Data::Varlen(out)
684 }
685 }
686 };
687 }
688 crate::for_each_layout!(fixed, copied)
689}
690
691fn layout_of(data: &Data) -> rudb_common::PhysicalType {
696 use rudb_common::PhysicalType as P;
697 macro_rules! layouts {
698 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
699 match data {
700 Data::Empty => P::Empty,
701 $(Data::$variant(_) => P::$variant,)+
702 }
703 };
704 }
705 crate::for_each_layout!(all, layouts)
706}
707
708fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
713 let signed = || data.signed_at(index);
714 let unsigned = || data.unsigned_at(index);
715 let value = match ty {
716 LogicalType::Boolean => match data {
717 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
718 _ => None,
719 },
720 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
721 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
722 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
723 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
724 LogicalType::HugeInt => signed().map(Value::HugeInt),
725 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
726 LogicalType::USmallInt => {
727 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
728 }
729 LogicalType::UInteger => {
730 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
731 }
732 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
733 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
734 LogicalType::Float => match data {
735 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
736 _ => None,
737 },
738 LogicalType::Double => match data {
739 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
740 _ => None,
741 },
742 LogicalType::Decimal { width, scale } => {
743 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
744 }
745 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
746 LogicalType::Blob | LogicalType::Bit => {
747 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
748 }
749 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
750 LogicalType::Time | LogicalType::TimeTz => {
751 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
752 }
753 LogicalType::Timestamp
754 | LogicalType::TimestampS
755 | LogicalType::TimestampMs
756 | LogicalType::TimestampNs
757 | LogicalType::TimestampTz => {
758 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
759 }
760 LogicalType::Interval => match data {
761 Data::Interval(v) => {
762 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
763 }
764 _ => None,
765 },
766 _ => None,
767 };
768 value.unwrap_or(Value::Null)
769}
770
771fn empty_data_for(ty: &LogicalType) -> Result<Data> {
773 use rudb_common::PhysicalType as P;
774 macro_rules! empties {
775 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
776 match ty.physical() {
777 P::Empty => Data::Empty,
778 $(P::$variant => Data::$variant(Buffer::new()),)+
779 P::Varlen => Data::Varlen(StringColumn::new()),
780 other => {
781 return Err(Error::not_implemented(format!(
782 "a flat vector of {other:?} data, which arrives with the storage layer"
783 )));
784 }
785 }
786 };
787 }
788 Ok(crate::for_each_layout!(fixed, empties))
789}
790
791fn push_value(data: &mut Data, value: &Value) -> Result<()> {
796 macro_rules! push {
797 ($vec:expr, $variant:path, $zero:expr) => {
798 match value {
799 Value::Null => $vec.push($zero),
800 $variant(x) => $vec.push(*x),
801 other => {
802 return Err(Error::internal(format!(
803 "{other:?} does not belong in this vector"
804 )));
805 }
806 }
807 };
808 }
809 macro_rules! decimal {
815 ($vec:expr, $ty:ty, $unscaled:expr) => {
816 match <$ty>::try_from(*$unscaled) {
817 Ok(x) => $vec.push(x),
818 Err(_) => {
819 return Err(Error::internal(format!(
820 "an unscaled decimal of {} does not fit the run its precision chose",
821 $unscaled
822 )));
823 }
824 }
825 };
826 }
827 match data {
828 Data::Empty => {}
829 Data::Bool(v) => push!(v, Value::Boolean, false),
830 Data::Int8(v) => push!(v, Value::TinyInt, 0),
831 Data::Int16(v) => match value {
832 Value::Null => v.push(0),
833 Value::SmallInt(x) => v.push(*x),
834 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
835 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
836 },
837 Data::Int32(v) => match value {
838 Value::Null => v.push(0),
839 Value::Integer(x) | Value::Date(x) => v.push(*x),
840 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
841 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
842 },
843 Data::Int64(v) => match value {
844 Value::Null => v.push(0),
845 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
846 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
847 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
848 },
849 Data::Int128(v) => match value {
850 Value::Null => v.push(0),
851 Value::HugeInt(x) => v.push(*x),
852 Value::Decimal { unscaled, .. } => v.push(*unscaled),
853 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
854 },
855 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
856 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
857 Data::UInt32(v) => push!(v, Value::UInteger, 0),
858 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
859 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
860 Data::Float32(v) => push!(v, Value::Float, 0.0),
861 Data::Float64(v) => push!(v, Value::Double, 0.0),
862 Data::Interval(v) => match value {
863 Value::Null => v.push((0, 0, 0)),
864 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
865 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
866 },
867 Data::Varlen(column) => match value {
868 Value::Null => {
869 column.push("");
870 }
871 Value::Varchar(text) => {
872 column.push(text);
873 }
874 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
878 Ok(text) => {
879 column.push(text);
880 }
881 Err(_) => {
882 return Err(Error::not_implemented(
883 "a blob that is not valid UTF-8, which needs the byte column from M2",
884 ));
885 }
886 },
887 other => return Err(Error::internal(format!("{other:?} is not a string"))),
888 },
889 }
890 Ok(())
891}
892
893#[cfg(test)]
894mod tests {
895 use std::sync::Arc;
896
897 use rudb_common::{LogicalType, Value};
898
899 use super::{Body, Data, Form, VECTOR_SIZE, Vector};
900 use crate::string::StringColumn;
901 use crate::validity::Validity;
902
903 fn integers(values: &[i32]) -> Vector {
904 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
905 }
906
907 #[test]
908 fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
909 let values = Vector::from_values(
910 LogicalType::Varchar,
911 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
912 )
913 .unwrap();
914 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
915
916 let piece = vector.slice(1, 3).unwrap();
917 assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
918 assert_eq!(piece.len(), 3);
919 assert_eq!(
920 piece.iter().collect::<Vec<_>>(),
921 [
922 Value::Varchar("blue".into()),
923 Value::Varchar("blue".into()),
924 Value::Varchar("red".into())
925 ]
926 );
927 assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
928 }
929
930 #[test]
931 fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
932 let values = Vector::from_values(
937 LogicalType::Varchar,
938 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
939 )
940 .unwrap();
941 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
942 let Body::Dictionary { values: whole, .. } = &vector.body else {
943 panic!("a dictionary vector holds a dictionary");
944 };
945
946 let piece = vector.slice(1, 3).unwrap();
947 let Body::Dictionary { codes, values: cut } = &piece.body else {
948 panic!("a slice of a dictionary is a dictionary");
949 };
950 assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
951 assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
952
953 let again = piece.slice(1, 2).unwrap();
955 let Body::Dictionary { values: cut, .. } = &again.body else {
956 panic!("a slice of a slice of a dictionary is a dictionary");
957 };
958 assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
959 assert_eq!(
960 again.iter().collect::<Vec<_>>(),
961 [Value::Varchar("blue".into()), Value::Varchar("red".into())]
962 );
963 }
964
965 #[test]
966 fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
967 let vector =
968 integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
969 let piece = vector.slice(1, 2).unwrap();
970 assert!(piece.validity().is_valid(0));
971 assert!(!piece.validity().is_valid(1));
972 assert_eq!(piece.value_at(1), Value::Null);
973 }
974
975 #[test]
976 fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
977 let vector = Vector::sequence(100, 5, 10);
978 let piece = vector.slice(3, 4).unwrap();
979 assert_eq!(piece.form(), Form::Sequence);
980 assert_eq!(
981 piece.iter().collect::<Vec<_>>(),
982 [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
983 );
984 }
985
986 #[test]
987 fn slicing_a_constant_is_a_shorter_constant() {
988 let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
989 let piece = vector.slice(2, 3).unwrap();
990 assert_eq!(piece.form(), Form::Constant);
991 assert_eq!(piece.len(), 3);
992 assert_eq!(piece.value_at(2), Value::Integer(9));
993 }
994
995 #[test]
996 fn slicing_the_whole_vector_hands_it_back_as_it_was() {
997 let vector = integers(&[1, 2, 3]);
998 assert_eq!(
999 vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
1000 [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1001 );
1002 }
1003
1004 #[test]
1005 fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
1006 let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
1007 assert!(error.to_string().contains("of a vector of 3"), "{error}");
1008 }
1009
1010 #[test]
1011 fn the_vector_size_is_the_one_the_design_is_built_around() {
1012 assert_eq!(VECTOR_SIZE, 1024);
1015 assert_eq!(VECTOR_SIZE / 64, 16);
1016 }
1017
1018 #[test]
1019 fn a_flat_vector_reads_back_what_was_put_in_it() {
1020 let vector = integers(&[1, 2, 3]);
1021 assert_eq!(vector.form(), Form::Flat);
1022 assert_eq!(vector.len(), 3);
1023 assert_eq!(vector.value_at(1), Value::Integer(2));
1024 assert_eq!(
1025 vector.iter().collect::<Vec<_>>(),
1026 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1027 );
1028 }
1029
1030 #[test]
1031 fn a_vector_built_from_values_reads_the_same_values_back() {
1032 let vector = Vector::from_values(
1033 LogicalType::Varchar,
1034 &[
1035 Value::Varchar("a".to_string()),
1036 Value::Null,
1037 Value::Varchar("a string too long to sit inside a view".to_string()),
1038 ],
1039 )
1040 .expect("strings and a null");
1041 assert_eq!(vector.len(), 3);
1042 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
1043 assert_eq!(vector.value_at(1), Value::Null);
1044 assert_eq!(
1045 vector.value_at(2),
1046 Value::Varchar("a string too long to sit inside a view".to_string())
1047 );
1048 }
1049
1050 #[test]
1053 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
1054 let vector = Vector::from_values(
1055 LogicalType::Integer,
1056 &[Value::Integer(1), Value::Null, Value::Integer(3)],
1057 )
1058 .expect("integers and a null");
1059 assert_eq!(vector.value_at(2), Value::Integer(3));
1060 assert!(vector.validity().has_nulls(3), "the middle one is null");
1061 }
1062
1063 #[test]
1064 fn a_value_the_type_cannot_hold_is_refused() {
1065 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
1066 assert!(wrong.is_err(), "a string is not an integer");
1067 }
1068
1069 #[test]
1070 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
1071 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
1073 assert!(wrong.is_err());
1074 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
1075 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
1076 }
1077
1078 #[test]
1079 fn a_constant_vector_costs_one_value_whatever_its_length() {
1080 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
1081 assert_eq!(vector.form(), Form::Constant);
1082 assert_eq!(vector.len(), VECTOR_SIZE);
1083 assert_eq!(vector.value_at(0), Value::Integer(7));
1084 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
1085 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
1086 }
1087
1088 #[test]
1089 fn a_constant_null_is_all_invalid_without_being_told() {
1090 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
1091 assert_eq!(vector.validity(), &Validity::AllInvalid);
1092 assert_eq!(vector.value_at(3), Value::Null);
1093 }
1094
1095 #[test]
1096 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
1097 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
1098 assert_eq!(vector.form(), Form::Sequence);
1099 assert_eq!(vector.value_at(0), Value::BigInt(100));
1100 assert_eq!(vector.value_at(923), Value::BigInt(1023));
1101 let stepped = Vector::sequence(0, 5, 4);
1102 assert_eq!(
1103 stepped.iter().collect::<Vec<_>>(),
1104 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
1105 );
1106 }
1107
1108 #[test]
1109 fn a_dictionary_vector_reads_through_its_codes() {
1110 let mut column = StringColumn::new();
1111 column.push("red");
1112 column.push("green");
1113 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1114 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
1115 assert_eq!(vector.form(), Form::Dictionary);
1116 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
1117 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
1118 assert_eq!(vector.len(), 4);
1119 }
1120
1121 #[test]
1122 fn a_dictionary_code_past_the_end_is_refused() {
1123 let values = integers(&[1, 2]);
1126 assert!(Vector::dictionary(vec![0, 2], values).is_err());
1127 }
1128
1129 #[test]
1130 fn every_form_flattens_to_the_same_values_it_reads_out() {
1131 let mut column = StringColumn::new();
1135 column.push("alpha");
1136 column.push("beta");
1137 let dictionary = Vector::dictionary(
1138 vec![1, 0, 1],
1139 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1140 )
1141 .unwrap();
1142 let cases = [
1143 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
1144 Vector::sequence(7, -2, 5),
1145 dictionary,
1146 ];
1147 for vector in cases {
1148 let flat = vector.flatten().unwrap();
1149 assert_eq!(flat.form(), Form::Flat);
1150 assert_eq!(flat.len(), vector.len());
1151 for index in 0..vector.len() {
1152 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
1153 }
1154 }
1155 }
1156
1157 #[test]
1158 fn a_null_still_occupies_a_position_after_flattening() {
1159 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
1163 let flat = vector.flatten().unwrap();
1164 assert_eq!(flat.value_at(0), Value::BigInt(0));
1165 assert_eq!(flat.value_at(1), Value::Null);
1166 assert_eq!(flat.value_at(2), Value::BigInt(2));
1167 assert_eq!(flat.value_at(3), Value::BigInt(3));
1168 }
1169
1170 #[test]
1175 fn a_null_behind_a_dictionary_survives_flattening() {
1176 let values =
1177 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1178 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1179 let flat = dictionary.flatten().unwrap();
1180 assert_eq!(flat.value_at(0), Value::Null);
1181 assert_eq!(flat.value_at(1), Value::Integer(3));
1182 assert_eq!(flat.value_at(2), Value::Null);
1183 }
1184
1185 #[test]
1188 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1189 let mut column = StringColumn::new();
1190 column.push("alpha");
1191 column.push("beta");
1192 column.push("gamma");
1193 let cases = [
1194 integers(&[10, 20, 30, 40]),
1195 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1196 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1197 Vector::sequence(100, -7, 4),
1198 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1199 Vector::dictionary(
1200 vec![2, 0, 1, 2],
1201 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1202 )
1203 .unwrap(),
1204 Vector::dictionary(
1205 vec![1, 0, 1, 0],
1206 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1207 .unwrap(),
1208 )
1209 .unwrap(),
1210 ];
1211 let wanted = [3_u32, 0, 2, 2, 1];
1212 for vector in cases {
1213 let gathered = vector.gather(&wanted).unwrap();
1214 assert_eq!(gathered.len(), wanted.len());
1215 assert_eq!(gathered.logical_type(), vector.logical_type());
1216 for (slot, &index) in wanted.iter().enumerate() {
1217 assert_eq!(
1218 gathered.value_at(slot),
1219 vector.value_at(index as usize),
1220 "slot {slot} of {:?}",
1221 vector.form()
1222 );
1223 }
1224 }
1225 }
1226
1227 #[test]
1231 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1232 let vector = integers(&[1, 2, 3]);
1233 let gathered = vector.gather(&[2, 9]).unwrap();
1234 assert_eq!(gathered.value_at(0), Value::Integer(3));
1235 assert_eq!(gathered.value_at(1), Value::Null);
1236 }
1237
1238 #[test]
1242 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1243 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1244 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1245 assert_eq!(gathered.len(), 3);
1246 assert_eq!(gathered.value_at(0), Value::Null);
1247 assert_eq!(gathered.value_at(2), Value::Null);
1248 }
1249
1250 #[test]
1253 fn gathering_a_constant_stays_a_constant() {
1254 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1255 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1256 assert_eq!(gathered.form(), Form::Constant);
1257 assert_eq!(gathered.len(), 3);
1258 assert_eq!(gathered.value_at(2), Value::Integer(4));
1259 }
1260
1261 #[test]
1266 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1267 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1268 .unwrap()
1269 .with_validity(Validity::from_iter(3, |index| index != 2));
1270 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1271 let gathered = outer.gather(&[0, 1]).unwrap();
1272 assert_eq!(gathered.form(), Form::Flat);
1273 assert_eq!(gathered.value_at(0), Value::Integer(8));
1274 assert_eq!(gathered.value_at(1), Value::Null);
1275 }
1276
1277 #[test]
1282 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1283 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1284 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1285 let (codes, values) = outer.dictionary_parts().unwrap();
1286 assert_eq!(codes, [1, 0]);
1287 assert_eq!(values.form(), Form::Flat);
1288 assert_eq!(outer.value_at(0), Value::Integer(8));
1289 assert_eq!(outer.value_at(1), Value::Integer(7));
1290 }
1291
1292 #[test]
1295 fn stacking_dictionaries_does_not_make_them_deeper() {
1296 let mut vector = integers(&[10, 20, 30, 40]);
1297 for _ in 0..4 {
1298 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1299 }
1300 let (codes, values) = vector.dictionary_parts().unwrap();
1301 assert_eq!(values.form(), Form::Flat);
1302 assert_eq!(codes, [0, 1, 2, 3]);
1303 assert_eq!(
1304 vector.iter().collect::<Vec<_>>(),
1305 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1306 );
1307 }
1308
1309 #[test]
1312 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1313 let values =
1314 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1315 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1316 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1317 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1318 assert_eq!(outer.value_at(0), Value::Null);
1319 assert_eq!(outer.value_at(1), Value::Integer(3));
1320 }
1321
1322 #[test]
1326 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1327 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1328 .unwrap()
1329 .with_validity(Validity::from_iter(3, |index| index != 1));
1330 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1331 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1332 assert_eq!(outer.value_at(0), Value::Null);
1333 assert_eq!(outer.value_at(1), Value::Integer(3));
1334 assert_eq!(outer.value_at(2), Value::Integer(1));
1335 }
1336
1337 #[test]
1338 fn flattening_a_flat_vector_is_the_same_vector() {
1339 let vector = integers(&[1, 2, 3]);
1340 assert_eq!(vector.flatten().unwrap(), vector);
1341 }
1342
1343 #[test]
1344 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1345 let ty = LogicalType::decimal(9, 2).unwrap();
1346 let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
1347 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1348 assert_eq!(vector.value_at(0).to_string(), "12.34");
1349 }
1350
1351 #[test]
1352 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1353 for (width, scale, unscaled) in
1356 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1357 {
1358 let ty = LogicalType::decimal(width, scale).unwrap();
1359 let value = Value::Decimal { unscaled, width, scale };
1360 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1361 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1362 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1363 }
1364 }
1365
1366 #[test]
1367 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1368 let ty = LogicalType::decimal(4, 1).unwrap();
1371 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1372 let error = Vector::from_values(ty, &[value]).unwrap_err();
1373 assert!(error.to_string().contains("does not fit"), "{error}");
1374 }
1375}