1use rudb_common::{Error, LogicalType, Result, Value};
19
20use crate::buffer::Buffer;
21use crate::string::{StringColumn, StringView};
22use crate::validity::Validity;
23
24pub const VECTOR_SIZE: usize = 1024;
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45#[non_exhaustive]
46pub enum Form {
47 Flat,
49 Constant,
51 Sequence,
53 Dictionary,
55}
56
57#[derive(Debug, Clone, PartialEq)]
62#[non_exhaustive]
63pub enum Data {
64 Empty,
66 Bool(Buffer<bool>),
68 Int8(Buffer<i8>),
70 Int16(Buffer<i16>),
72 Int32(Buffer<i32>),
74 Int64(Buffer<i64>),
76 Int128(Buffer<i128>),
78 UInt8(Buffer<u8>),
80 UInt16(Buffer<u16>),
82 UInt32(Buffer<u32>),
84 UInt64(Buffer<u64>),
86 UInt128(Buffer<u128>),
88 Float32(Buffer<f32>),
90 Float64(Buffer<f64>),
92 Interval(Buffer<(i32, i32, i64)>),
94 Varlen(StringColumn),
96}
97
98impl Data {
99 #[must_use]
106 pub fn len(&self) -> usize {
107 macro_rules! lengths {
108 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
109 match self {
110 Self::Empty => 0,
111 $(Self::$variant(values) => values.len(),)+
112 }
113 };
114 }
115 crate::for_each_layout!(all, lengths)
116 }
117
118 #[must_use]
120 pub fn is_empty(&self) -> bool {
121 self.len() == 0
122 }
123
124 #[must_use]
129 pub fn signed_at(&self, index: usize) -> Option<i128> {
130 macro_rules! widened {
131 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
132 match self {
133 $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
134 _ => None,
135 }
136 };
137 }
138 crate::for_each_layout!(signed, widened)
139 }
140
141 #[must_use]
143 pub fn unsigned_at(&self, index: usize) -> Option<u128> {
144 macro_rules! widened {
145 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
146 match self {
147 $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
148 _ => None,
149 }
150 };
151 }
152 crate::for_each_layout!(unsigned, widened)
153 }
154
155 #[must_use]
157 pub fn str_at(&self, index: usize) -> Option<&str> {
158 match self {
159 Self::Varlen(column) => column.get(index),
160 _ => None,
161 }
162 }
163}
164
165#[derive(Debug, Clone, PartialEq)]
167pub struct Vector {
168 ty: LogicalType,
169 len: usize,
170 validity: Validity,
171 body: Body,
172}
173
174#[derive(Debug, Clone, PartialEq)]
176enum Body {
177 Flat(Data),
178 Constant(Box<Value>),
179 Sequence { start: i64, step: i64 },
180 Dictionary { codes: Vec<u32>, values: Box<Vector> },
181}
182
183impl Vector {
184 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
192 let len = data.len();
193 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
194 return Err(Error::internal(format!(
195 "a {ty} vector cannot hold {:?} data",
196 layout_of(&data)
197 )));
198 }
199 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
200 }
201
202 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
214 let mut data = empty_data_for(&ty)?;
215 for value in values {
216 push_value(&mut data, value)?;
217 }
218 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
219 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
220 }
221
222 #[must_use]
227 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
228 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
229 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
230 }
231
232 #[must_use]
237 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
238 Self {
239 ty: LogicalType::BigInt,
240 len,
241 validity: Validity::AllValid,
242 body: Body::Sequence { start, step },
243 }
244 }
245
246 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
276 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
277 return Err(Error::internal(format!(
278 "dictionary code {bad} is past the end of a {} value dictionary",
279 values.len()
280 )));
281 }
282 let (codes, values) = compose(codes, values);
283 Ok(Self {
284 ty: values.ty.clone(),
285 len: codes.len(),
286 validity: Validity::AllValid,
287 body: Body::Dictionary { codes, values: Box::new(values) },
288 })
289 }
290
291 #[must_use]
293 pub fn with_validity(mut self, validity: Validity) -> Self {
294 self.validity = validity;
295 self
296 }
297
298 #[must_use]
300 pub fn logical_type(&self) -> &LogicalType {
301 &self.ty
302 }
303
304 #[must_use]
306 pub fn len(&self) -> usize {
307 self.len
308 }
309
310 #[must_use]
312 pub fn is_empty(&self) -> bool {
313 self.len == 0
314 }
315
316 #[must_use]
318 pub fn validity(&self) -> &Validity {
319 &self.validity
320 }
321
322 #[must_use]
324 pub fn form(&self) -> Form {
325 match self.body {
326 Body::Flat(_) => Form::Flat,
327 Body::Constant(_) => Form::Constant,
328 Body::Sequence { .. } => Form::Sequence,
329 Body::Dictionary { .. } => Form::Dictionary,
330 }
331 }
332
333 #[must_use]
338 pub fn data(&self) -> Option<&Data> {
339 match &self.body {
340 Body::Flat(data) => Some(data),
341 _ => None,
342 }
343 }
344
345 #[must_use]
352 pub fn constant_value(&self) -> Option<&Value> {
353 match &self.body {
354 Body::Constant(value) => Some(value.as_ref()),
355 _ => None,
356 }
357 }
358
359 #[must_use]
373 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
374 match &self.body {
375 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
376 _ => None,
377 }
378 }
379
380 #[must_use]
382 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
383 match self.body {
384 Body::Sequence { start, step } => Some((start, step)),
385 _ => None,
386 }
387 }
388
389 #[must_use]
395 pub fn value_at(&self, index: usize) -> Value {
396 if index >= self.len || !self.validity.is_valid(index) {
397 return Value::Null;
398 }
399 match &self.body {
400 Body::Constant(value) => value.as_ref().clone(),
401 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
402 Body::Dictionary { codes, values } => match codes.get(index) {
403 Some(&code) => values.value_at(code as usize),
404 None => Value::Null,
405 },
406 Body::Flat(data) => value_from(&self.ty, data, index),
407 }
408 }
409
410 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
412 (0..self.len).map(|index| self.value_at(index))
413 }
414
415 pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
437 let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
438 if end > self.len {
439 return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
440 }
441 if at == 0 && len == self.len {
442 return Ok(self.clone());
443 }
444 let validity = Validity::from_iter(len, |row| self.validity.is_valid(at + row));
445 let body = match &self.body {
446 Body::Constant(value) => Body::Constant(value.clone()),
447 Body::Sequence { start, step } => {
448 Body::Sequence { start: start + step * at as i64, step: *step }
449 }
450 Body::Dictionary { codes, values } => Body::Dictionary {
451 codes: codes[at..end].to_vec(),
452 values: Box::new(values.as_ref().clone()),
453 },
454 Body::Flat(_) => {
458 let indices: Vec<u32> =
459 (at..end).map(|row| u32::try_from(row).unwrap_or(u32::MAX)).collect();
460 return self.gather(&indices);
461 }
462 };
463 Ok(Self { ty: self.ty.clone(), len, validity, body })
464 }
465
466 pub fn flatten(&self) -> Result<Self> {
477 if let Body::Flat(_) = self.body {
478 return Ok(self.clone());
479 }
480 self.copied((0..self.len).collect(), false)
481 }
482
483 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
499 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
500 }
501
502 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
509 let rows = at.len();
510 let (at, leaf) = self.resolve(at);
511 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
512 let validity = Validity::from_run(&live);
513 let body = match &leaf.body {
514 Body::Constant(value) => {
517 if constants_stay && matches!(validity, Validity::AllValid) {
518 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
519 }
520 let mut data = empty_data_for(&self.ty)?;
521 for &index in &at {
522 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
523 }
524 Body::Flat(data)
525 }
526 Body::Sequence { start, step } => Body::Flat(Data::Int64(
529 at.iter()
530 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
531 .collect(),
532 )),
533 Body::Flat(Data::Empty) => {
537 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
538 }
539 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
540 Body::Dictionary { .. } => {
542 return Err(Error::internal("a dictionary survived being resolved"));
543 }
544 };
545 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
546 }
547
548 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
554 let mut source = self;
555 loop {
556 for slot in &mut at {
557 if *slot >= source.len || !source.validity.is_valid(*slot) {
558 *slot = NOWHERE;
559 }
560 }
561 let Body::Dictionary { codes, values } = &source.body else {
562 return (at, source);
563 };
564 for slot in &mut at {
565 *slot = match codes.get(*slot) {
566 Some(&code) => code as usize,
567 None => NOWHERE,
568 };
569 }
570 source = values.as_ref();
571 }
572 }
573}
574
575impl AsRef<Vector> for Vector {
582 fn as_ref(&self) -> &Vector {
583 self
584 }
585}
586
587fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
599 if !matches!(values.validity, Validity::AllValid) {
602 return (codes, values);
603 }
604 let Vector { ty, len, validity, body } = values;
605 match body {
606 Body::Dictionary { codes: inner, values: leaf } => {
607 debug_assert!(
608 !matches!(leaf.body, Body::Dictionary { .. })
609 || !matches!(leaf.validity, Validity::AllValid),
610 "a dictionary was stacked on a dictionary without going through the constructor"
611 );
612 (codes.iter().map(|&code| inner[code as usize]).collect(), *leaf)
613 }
614 body => (codes, Vector { ty, len, validity, body }),
615 }
616}
617
618const NOWHERE: usize = usize::MAX;
623
624fn copy_of(data: &Data, at: &[usize]) -> Data {
630 macro_rules! copied {
631 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
632 match data {
633 Data::Empty => Data::Empty,
634 $(Data::$variant(values) => {
635 let mut out = Buffer::with_capacity(at.len());
636 for &index in at {
637 out.push(values.get(index).copied().unwrap_or($zero));
640 }
641 Data::$variant(out)
642 })+
643 Data::Varlen(values) => {
647 let mut out = StringColumn::with_capacity(at.len());
648 let views = values.views();
653 out.reserve_bytes(
654 at.iter()
655 .filter_map(|&index| views.get(index))
656 .filter(|view| !view.is_inline())
657 .map(StringView::len)
658 .sum(),
659 );
660 for &index in at {
661 out.push(values.get(index).unwrap_or(""));
662 }
663 Data::Varlen(out)
664 }
665 }
666 };
667 }
668 crate::for_each_layout!(fixed, copied)
669}
670
671fn layout_of(data: &Data) -> rudb_common::PhysicalType {
676 use rudb_common::PhysicalType as P;
677 macro_rules! layouts {
678 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
679 match data {
680 Data::Empty => P::Empty,
681 $(Data::$variant(_) => P::$variant,)+
682 }
683 };
684 }
685 crate::for_each_layout!(all, layouts)
686}
687
688fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
693 let signed = || data.signed_at(index);
694 let unsigned = || data.unsigned_at(index);
695 let value = match ty {
696 LogicalType::Boolean => match data {
697 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
698 _ => None,
699 },
700 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
701 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
702 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
703 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
704 LogicalType::HugeInt => signed().map(Value::HugeInt),
705 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
706 LogicalType::USmallInt => {
707 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
708 }
709 LogicalType::UInteger => {
710 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
711 }
712 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
713 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
714 LogicalType::Float => match data {
715 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
716 _ => None,
717 },
718 LogicalType::Double => match data {
719 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
720 _ => None,
721 },
722 LogicalType::Decimal { width, scale } => {
723 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
724 }
725 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
726 LogicalType::Blob | LogicalType::Bit => {
727 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
728 }
729 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
730 LogicalType::Time | LogicalType::TimeTz => {
731 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
732 }
733 LogicalType::Timestamp
734 | LogicalType::TimestampS
735 | LogicalType::TimestampMs
736 | LogicalType::TimestampNs
737 | LogicalType::TimestampTz => {
738 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
739 }
740 LogicalType::Interval => match data {
741 Data::Interval(v) => {
742 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
743 }
744 _ => None,
745 },
746 _ => None,
747 };
748 value.unwrap_or(Value::Null)
749}
750
751fn empty_data_for(ty: &LogicalType) -> Result<Data> {
753 use rudb_common::PhysicalType as P;
754 macro_rules! empties {
755 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
756 match ty.physical() {
757 P::Empty => Data::Empty,
758 $(P::$variant => Data::$variant(Buffer::new()),)+
759 P::Varlen => Data::Varlen(StringColumn::new()),
760 other => {
761 return Err(Error::not_implemented(format!(
762 "a flat vector of {other:?} data, which arrives with the storage layer"
763 )));
764 }
765 }
766 };
767 }
768 Ok(crate::for_each_layout!(fixed, empties))
769}
770
771fn push_value(data: &mut Data, value: &Value) -> Result<()> {
776 macro_rules! push {
777 ($vec:expr, $variant:path, $zero:expr) => {
778 match value {
779 Value::Null => $vec.push($zero),
780 $variant(x) => $vec.push(*x),
781 other => {
782 return Err(Error::internal(format!(
783 "{other:?} does not belong in this vector"
784 )));
785 }
786 }
787 };
788 }
789 macro_rules! decimal {
795 ($vec:expr, $ty:ty, $unscaled:expr) => {
796 match <$ty>::try_from(*$unscaled) {
797 Ok(x) => $vec.push(x),
798 Err(_) => {
799 return Err(Error::internal(format!(
800 "an unscaled decimal of {} does not fit the run its precision chose",
801 $unscaled
802 )));
803 }
804 }
805 };
806 }
807 match data {
808 Data::Empty => {}
809 Data::Bool(v) => push!(v, Value::Boolean, false),
810 Data::Int8(v) => push!(v, Value::TinyInt, 0),
811 Data::Int16(v) => match value {
812 Value::Null => v.push(0),
813 Value::SmallInt(x) => v.push(*x),
814 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
815 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
816 },
817 Data::Int32(v) => match value {
818 Value::Null => v.push(0),
819 Value::Integer(x) | Value::Date(x) => v.push(*x),
820 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
821 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
822 },
823 Data::Int64(v) => match value {
824 Value::Null => v.push(0),
825 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
826 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
827 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
828 },
829 Data::Int128(v) => match value {
830 Value::Null => v.push(0),
831 Value::HugeInt(x) => v.push(*x),
832 Value::Decimal { unscaled, .. } => v.push(*unscaled),
833 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
834 },
835 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
836 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
837 Data::UInt32(v) => push!(v, Value::UInteger, 0),
838 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
839 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
840 Data::Float32(v) => push!(v, Value::Float, 0.0),
841 Data::Float64(v) => push!(v, Value::Double, 0.0),
842 Data::Interval(v) => match value {
843 Value::Null => v.push((0, 0, 0)),
844 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
845 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
846 },
847 Data::Varlen(column) => match value {
848 Value::Null => {
849 column.push("");
850 }
851 Value::Varchar(text) => {
852 column.push(text);
853 }
854 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
858 Ok(text) => {
859 column.push(text);
860 }
861 Err(_) => {
862 return Err(Error::not_implemented(
863 "a blob that is not valid UTF-8, which needs the byte column from M2",
864 ));
865 }
866 },
867 other => return Err(Error::internal(format!("{other:?} is not a string"))),
868 },
869 }
870 Ok(())
871}
872
873#[cfg(test)]
874mod tests {
875 use rudb_common::{LogicalType, Value};
876
877 use super::{Data, Form, VECTOR_SIZE, Vector};
878 use crate::string::StringColumn;
879 use crate::validity::Validity;
880
881 fn integers(values: &[i32]) -> Vector {
882 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
883 }
884
885 #[test]
886 fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
887 let values = Vector::from_values(
888 LogicalType::Varchar,
889 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
890 )
891 .unwrap();
892 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
893
894 let piece = vector.slice(1, 3).unwrap();
895 assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
896 assert_eq!(piece.len(), 3);
897 assert_eq!(
898 piece.iter().collect::<Vec<_>>(),
899 [
900 Value::Varchar("blue".into()),
901 Value::Varchar("blue".into()),
902 Value::Varchar("red".into())
903 ]
904 );
905 assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
906 }
907
908 #[test]
909 fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
910 let vector =
911 integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
912 let piece = vector.slice(1, 2).unwrap();
913 assert!(piece.validity().is_valid(0));
914 assert!(!piece.validity().is_valid(1));
915 assert_eq!(piece.value_at(1), Value::Null);
916 }
917
918 #[test]
919 fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
920 let vector = Vector::sequence(100, 5, 10);
921 let piece = vector.slice(3, 4).unwrap();
922 assert_eq!(piece.form(), Form::Sequence);
923 assert_eq!(
924 piece.iter().collect::<Vec<_>>(),
925 [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
926 );
927 }
928
929 #[test]
930 fn slicing_a_constant_is_a_shorter_constant() {
931 let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
932 let piece = vector.slice(2, 3).unwrap();
933 assert_eq!(piece.form(), Form::Constant);
934 assert_eq!(piece.len(), 3);
935 assert_eq!(piece.value_at(2), Value::Integer(9));
936 }
937
938 #[test]
939 fn slicing_the_whole_vector_hands_it_back_as_it_was() {
940 let vector = integers(&[1, 2, 3]);
941 assert_eq!(
942 vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
943 [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
944 );
945 }
946
947 #[test]
948 fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
949 let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
950 assert!(error.to_string().contains("of a vector of 3"), "{error}");
951 }
952
953 #[test]
954 fn the_vector_size_is_the_one_the_design_is_built_around() {
955 assert_eq!(VECTOR_SIZE, 1024);
958 assert_eq!(VECTOR_SIZE / 64, 16);
959 }
960
961 #[test]
962 fn a_flat_vector_reads_back_what_was_put_in_it() {
963 let vector = integers(&[1, 2, 3]);
964 assert_eq!(vector.form(), Form::Flat);
965 assert_eq!(vector.len(), 3);
966 assert_eq!(vector.value_at(1), Value::Integer(2));
967 assert_eq!(
968 vector.iter().collect::<Vec<_>>(),
969 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
970 );
971 }
972
973 #[test]
974 fn a_vector_built_from_values_reads_the_same_values_back() {
975 let vector = Vector::from_values(
976 LogicalType::Varchar,
977 &[
978 Value::Varchar("a".to_string()),
979 Value::Null,
980 Value::Varchar("a string too long to sit inside a view".to_string()),
981 ],
982 )
983 .expect("strings and a null");
984 assert_eq!(vector.len(), 3);
985 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
986 assert_eq!(vector.value_at(1), Value::Null);
987 assert_eq!(
988 vector.value_at(2),
989 Value::Varchar("a string too long to sit inside a view".to_string())
990 );
991 }
992
993 #[test]
996 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
997 let vector = Vector::from_values(
998 LogicalType::Integer,
999 &[Value::Integer(1), Value::Null, Value::Integer(3)],
1000 )
1001 .expect("integers and a null");
1002 assert_eq!(vector.value_at(2), Value::Integer(3));
1003 assert!(vector.validity().has_nulls(3), "the middle one is null");
1004 }
1005
1006 #[test]
1007 fn a_value_the_type_cannot_hold_is_refused() {
1008 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
1009 assert!(wrong.is_err(), "a string is not an integer");
1010 }
1011
1012 #[test]
1013 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
1014 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
1016 assert!(wrong.is_err());
1017 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
1018 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
1019 }
1020
1021 #[test]
1022 fn a_constant_vector_costs_one_value_whatever_its_length() {
1023 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
1024 assert_eq!(vector.form(), Form::Constant);
1025 assert_eq!(vector.len(), VECTOR_SIZE);
1026 assert_eq!(vector.value_at(0), Value::Integer(7));
1027 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
1028 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
1029 }
1030
1031 #[test]
1032 fn a_constant_null_is_all_invalid_without_being_told() {
1033 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
1034 assert_eq!(vector.validity(), &Validity::AllInvalid);
1035 assert_eq!(vector.value_at(3), Value::Null);
1036 }
1037
1038 #[test]
1039 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
1040 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
1041 assert_eq!(vector.form(), Form::Sequence);
1042 assert_eq!(vector.value_at(0), Value::BigInt(100));
1043 assert_eq!(vector.value_at(923), Value::BigInt(1023));
1044 let stepped = Vector::sequence(0, 5, 4);
1045 assert_eq!(
1046 stepped.iter().collect::<Vec<_>>(),
1047 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
1048 );
1049 }
1050
1051 #[test]
1052 fn a_dictionary_vector_reads_through_its_codes() {
1053 let mut column = StringColumn::new();
1054 column.push("red");
1055 column.push("green");
1056 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1057 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
1058 assert_eq!(vector.form(), Form::Dictionary);
1059 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
1060 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
1061 assert_eq!(vector.len(), 4);
1062 }
1063
1064 #[test]
1065 fn a_dictionary_code_past_the_end_is_refused() {
1066 let values = integers(&[1, 2]);
1069 assert!(Vector::dictionary(vec![0, 2], values).is_err());
1070 }
1071
1072 #[test]
1073 fn every_form_flattens_to_the_same_values_it_reads_out() {
1074 let mut column = StringColumn::new();
1078 column.push("alpha");
1079 column.push("beta");
1080 let dictionary = Vector::dictionary(
1081 vec![1, 0, 1],
1082 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1083 )
1084 .unwrap();
1085 let cases = [
1086 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
1087 Vector::sequence(7, -2, 5),
1088 dictionary,
1089 ];
1090 for vector in cases {
1091 let flat = vector.flatten().unwrap();
1092 assert_eq!(flat.form(), Form::Flat);
1093 assert_eq!(flat.len(), vector.len());
1094 for index in 0..vector.len() {
1095 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
1096 }
1097 }
1098 }
1099
1100 #[test]
1101 fn a_null_still_occupies_a_position_after_flattening() {
1102 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
1106 let flat = vector.flatten().unwrap();
1107 assert_eq!(flat.value_at(0), Value::BigInt(0));
1108 assert_eq!(flat.value_at(1), Value::Null);
1109 assert_eq!(flat.value_at(2), Value::BigInt(2));
1110 assert_eq!(flat.value_at(3), Value::BigInt(3));
1111 }
1112
1113 #[test]
1118 fn a_null_behind_a_dictionary_survives_flattening() {
1119 let values =
1120 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1121 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1122 let flat = dictionary.flatten().unwrap();
1123 assert_eq!(flat.value_at(0), Value::Null);
1124 assert_eq!(flat.value_at(1), Value::Integer(3));
1125 assert_eq!(flat.value_at(2), Value::Null);
1126 }
1127
1128 #[test]
1131 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1132 let mut column = StringColumn::new();
1133 column.push("alpha");
1134 column.push("beta");
1135 column.push("gamma");
1136 let cases = [
1137 integers(&[10, 20, 30, 40]),
1138 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1139 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1140 Vector::sequence(100, -7, 4),
1141 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1142 Vector::dictionary(
1143 vec![2, 0, 1, 2],
1144 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1145 )
1146 .unwrap(),
1147 Vector::dictionary(
1148 vec![1, 0, 1, 0],
1149 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1150 .unwrap(),
1151 )
1152 .unwrap(),
1153 ];
1154 let wanted = [3_u32, 0, 2, 2, 1];
1155 for vector in cases {
1156 let gathered = vector.gather(&wanted).unwrap();
1157 assert_eq!(gathered.len(), wanted.len());
1158 assert_eq!(gathered.logical_type(), vector.logical_type());
1159 for (slot, &index) in wanted.iter().enumerate() {
1160 assert_eq!(
1161 gathered.value_at(slot),
1162 vector.value_at(index as usize),
1163 "slot {slot} of {:?}",
1164 vector.form()
1165 );
1166 }
1167 }
1168 }
1169
1170 #[test]
1174 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1175 let vector = integers(&[1, 2, 3]);
1176 let gathered = vector.gather(&[2, 9]).unwrap();
1177 assert_eq!(gathered.value_at(0), Value::Integer(3));
1178 assert_eq!(gathered.value_at(1), Value::Null);
1179 }
1180
1181 #[test]
1185 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1186 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1187 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1188 assert_eq!(gathered.len(), 3);
1189 assert_eq!(gathered.value_at(0), Value::Null);
1190 assert_eq!(gathered.value_at(2), Value::Null);
1191 }
1192
1193 #[test]
1196 fn gathering_a_constant_stays_a_constant() {
1197 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1198 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1199 assert_eq!(gathered.form(), Form::Constant);
1200 assert_eq!(gathered.len(), 3);
1201 assert_eq!(gathered.value_at(2), Value::Integer(4));
1202 }
1203
1204 #[test]
1209 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1210 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1211 .unwrap()
1212 .with_validity(Validity::from_iter(3, |index| index != 2));
1213 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1214 let gathered = outer.gather(&[0, 1]).unwrap();
1215 assert_eq!(gathered.form(), Form::Flat);
1216 assert_eq!(gathered.value_at(0), Value::Integer(8));
1217 assert_eq!(gathered.value_at(1), Value::Null);
1218 }
1219
1220 #[test]
1225 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1226 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1227 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1228 let (codes, values) = outer.dictionary_parts().unwrap();
1229 assert_eq!(codes, [1, 0]);
1230 assert_eq!(values.form(), Form::Flat);
1231 assert_eq!(outer.value_at(0), Value::Integer(8));
1232 assert_eq!(outer.value_at(1), Value::Integer(7));
1233 }
1234
1235 #[test]
1238 fn stacking_dictionaries_does_not_make_them_deeper() {
1239 let mut vector = integers(&[10, 20, 30, 40]);
1240 for _ in 0..4 {
1241 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1242 }
1243 let (codes, values) = vector.dictionary_parts().unwrap();
1244 assert_eq!(values.form(), Form::Flat);
1245 assert_eq!(codes, [0, 1, 2, 3]);
1246 assert_eq!(
1247 vector.iter().collect::<Vec<_>>(),
1248 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1249 );
1250 }
1251
1252 #[test]
1255 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1256 let values =
1257 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1258 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1259 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1260 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1261 assert_eq!(outer.value_at(0), Value::Null);
1262 assert_eq!(outer.value_at(1), Value::Integer(3));
1263 }
1264
1265 #[test]
1269 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1270 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1271 .unwrap()
1272 .with_validity(Validity::from_iter(3, |index| index != 1));
1273 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1274 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1275 assert_eq!(outer.value_at(0), Value::Null);
1276 assert_eq!(outer.value_at(1), Value::Integer(3));
1277 assert_eq!(outer.value_at(2), Value::Integer(1));
1278 }
1279
1280 #[test]
1281 fn flattening_a_flat_vector_is_the_same_vector() {
1282 let vector = integers(&[1, 2, 3]);
1283 assert_eq!(vector.flatten().unwrap(), vector);
1284 }
1285
1286 #[test]
1287 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1288 let ty = LogicalType::decimal(9, 2).unwrap();
1289 let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
1290 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1291 assert_eq!(vector.value_at(0).to_string(), "12.34");
1292 }
1293
1294 #[test]
1295 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1296 for (width, scale, unscaled) in
1299 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1300 {
1301 let ty = LogicalType::decimal(width, scale).unwrap();
1302 let value = Value::Decimal { unscaled, width, scale };
1303 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1304 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1305 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1306 }
1307 }
1308
1309 #[test]
1310 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1311 let ty = LogicalType::decimal(4, 1).unwrap();
1314 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1315 let error = Vector::from_values(ty, &[value]).unwrap_err();
1316 assert!(error.to_string().contains("does not fit"), "{error}");
1317 }
1318}