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]
132 pub fn footprint(&self) -> usize {
133 macro_rules! sizes {
134 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
135 match self {
136 Self::Empty => 0,
137 $(Self::$variant(values) => values.footprint(),)+
138 }
139 };
140 }
141 crate::for_each_layout!(all, sizes)
142 }
143
144 #[must_use]
149 pub fn signed_at(&self, index: usize) -> Option<i128> {
150 macro_rules! widened {
151 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
152 match self {
153 $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
154 _ => None,
155 }
156 };
157 }
158 crate::for_each_layout!(signed, widened)
159 }
160
161 #[must_use]
163 pub fn unsigned_at(&self, index: usize) -> Option<u128> {
164 macro_rules! widened {
165 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
166 match self {
167 $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
168 _ => None,
169 }
170 };
171 }
172 crate::for_each_layout!(unsigned, widened)
173 }
174
175 #[must_use]
177 pub fn str_at(&self, index: usize) -> Option<&str> {
178 match self {
179 Self::Varlen(column) => column.get(index),
180 _ => None,
181 }
182 }
183
184 #[must_use]
189 pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
190 match self {
191 Self::Varlen(column) => column.bytes(index),
192 _ => None,
193 }
194 }
195}
196
197#[derive(Debug, Clone, PartialEq)]
199pub struct Vector {
200 ty: LogicalType,
201 len: usize,
202 validity: Validity,
203 body: Body,
204}
205
206#[derive(Debug, Clone, PartialEq)]
208enum Body {
209 Flat(Data),
210 Constant(Box<Value>),
211 Sequence {
212 start: i64,
213 step: i64,
214 },
215 Dictionary {
225 codes: Vec<u32>,
226 values: Arc<Vector>,
227 },
228}
229
230impl Vector {
231 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
239 let len = data.len();
240 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
241 return Err(Error::internal(format!(
242 "a {ty} vector cannot hold {:?} data",
243 layout_of(&data)
244 )));
245 }
246 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
247 }
248
249 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
261 let mut data = empty_data_for(&ty)?;
262 for value in values {
263 push_value(&mut data, value)?;
264 }
265 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
266 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
267 }
268
269 #[must_use]
274 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
275 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
276 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
277 }
278
279 #[must_use]
284 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
285 Self {
286 ty: LogicalType::BigInt,
287 len,
288 validity: Validity::AllValid,
289 body: Body::Sequence { start, step },
290 }
291 }
292
293 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
323 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
324 return Err(Error::internal(format!(
325 "dictionary code {bad} is past the end of a {} value dictionary",
326 values.len()
327 )));
328 }
329 let (codes, values) = compose(codes, values);
330 Ok(Self {
331 ty: values.ty.clone(),
332 len: codes.len(),
333 validity: Validity::AllValid,
334 body: Body::Dictionary { codes, values: Arc::new(values) },
335 })
336 }
337
338 #[must_use]
340 pub fn with_validity(mut self, validity: Validity) -> Self {
341 self.validity = validity;
342 self
343 }
344
345 #[must_use]
347 pub fn logical_type(&self) -> &LogicalType {
348 &self.ty
349 }
350
351 #[must_use]
353 pub fn len(&self) -> usize {
354 self.len
355 }
356
357 #[must_use]
359 pub fn is_empty(&self) -> bool {
360 self.len == 0
361 }
362
363 #[must_use]
375 pub fn footprint(&self) -> usize {
376 let body = match &self.body {
377 Body::Flat(data) => data.footprint(),
378 Body::Constant(value) => value.footprint(),
379 Body::Sequence { .. } => 0,
380 Body::Dictionary { codes, values } => {
381 codes.capacity() * size_of::<u32>() + values.footprint()
382 }
383 };
384 size_of::<Self>() + self.validity.footprint() + body
385 }
386
387 #[must_use]
389 pub fn validity(&self) -> &Validity {
390 &self.validity
391 }
392
393 #[must_use]
395 pub fn form(&self) -> Form {
396 match self.body {
397 Body::Flat(_) => Form::Flat,
398 Body::Constant(_) => Form::Constant,
399 Body::Sequence { .. } => Form::Sequence,
400 Body::Dictionary { .. } => Form::Dictionary,
401 }
402 }
403
404 #[must_use]
409 pub fn data(&self) -> Option<&Data> {
410 match &self.body {
411 Body::Flat(data) => Some(data),
412 _ => None,
413 }
414 }
415
416 #[must_use]
423 pub fn constant_value(&self) -> Option<&Value> {
424 match &self.body {
425 Body::Constant(value) => Some(value.as_ref()),
426 _ => None,
427 }
428 }
429
430 #[must_use]
444 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
445 match &self.body {
446 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
447 _ => None,
448 }
449 }
450
451 #[must_use]
453 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
454 match self.body {
455 Body::Sequence { start, step } => Some((start, step)),
456 _ => None,
457 }
458 }
459
460 #[must_use]
466 pub fn value_at(&self, index: usize) -> Value {
467 if index >= self.len || !self.validity.is_valid(index) {
468 return Value::Null;
469 }
470 match &self.body {
471 Body::Constant(value) => value.as_ref().clone(),
472 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
473 Body::Dictionary { codes, values } => match codes.get(index) {
474 Some(&code) => values.value_at(code as usize),
475 None => Value::Null,
476 },
477 Body::Flat(data) => value_from(&self.ty, data, index),
478 }
479 }
480
481 #[must_use]
491 pub fn text_at(&self, index: usize) -> Option<&str> {
492 if self.ty != LogicalType::Varchar || index >= self.len || !self.validity.is_valid(index) {
493 return None;
494 }
495 match &self.body {
496 Body::Flat(data) => data.str_at(index),
497 Body::Dictionary { codes, values } => {
498 values.text_at(usize::try_from(*codes.get(index)?).ok()?)
499 }
500 _ => None,
501 }
502 }
503
504 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
506 (0..self.len).map(|index| self.value_at(index))
507 }
508
509 pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
531 let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
532 if end > self.len {
533 return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
534 }
535 if at == 0 && len == self.len {
536 return Ok(self.clone());
537 }
538 let validity = Validity::from_iter(len, |row| self.validity.is_valid(at + row));
539 let body = match &self.body {
540 Body::Constant(value) => Body::Constant(value.clone()),
541 Body::Sequence { start, step } => {
542 Body::Sequence { start: start + step * at as i64, step: *step }
543 }
544 Body::Dictionary { codes, values } => {
545 Body::Dictionary { codes: codes[at..end].to_vec(), values: Arc::clone(values) }
546 }
547 Body::Flat(_) => {
551 let indices: Vec<u32> =
552 (at..end).map(|row| u32::try_from(row).unwrap_or(u32::MAX)).collect();
553 return self.gather(&indices);
554 }
555 };
556 Ok(Self { ty: self.ty.clone(), len, validity, body })
557 }
558
559 pub fn flatten(&self) -> Result<Self> {
570 if let Body::Flat(_) = self.body {
571 return Ok(self.clone());
572 }
573 self.copied((0..self.len).collect(), false)
574 }
575
576 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
592 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
593 }
594
595 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
602 let rows = at.len();
603 let (at, leaf) = self.resolve(at);
604 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
605 let validity = Validity::from_run(&live);
606 let body = match &leaf.body {
607 Body::Constant(value) => {
610 if constants_stay && matches!(validity, Validity::AllValid) {
611 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
612 }
613 let mut data = empty_data_for(&self.ty)?;
614 for &index in &at {
615 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
616 }
617 Body::Flat(data)
618 }
619 Body::Sequence { start, step } => Body::Flat(Data::Int64(
622 at.iter()
623 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
624 .collect(),
625 )),
626 Body::Flat(Data::Empty) => {
630 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
631 }
632 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
633 Body::Dictionary { .. } => {
635 return Err(Error::internal("a dictionary survived being resolved"));
636 }
637 };
638 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
639 }
640
641 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
647 let mut source = self;
648 loop {
649 for slot in &mut at {
650 if *slot >= source.len || !source.validity.is_valid(*slot) {
651 *slot = NOWHERE;
652 }
653 }
654 let Body::Dictionary { codes, values } = &source.body else {
655 return (at, source);
656 };
657 for slot in &mut at {
658 *slot = match codes.get(*slot) {
659 Some(&code) => code as usize,
660 None => NOWHERE,
661 };
662 }
663 source = values.as_ref();
664 }
665 }
666}
667
668impl AsRef<Vector> for Vector {
675 fn as_ref(&self) -> &Vector {
676 self
677 }
678}
679
680fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
692 if !matches!(values.validity, Validity::AllValid) {
695 return (codes, values);
696 }
697 let Vector { ty, len, validity, body } = values;
698 match body {
699 Body::Dictionary { codes: inner, values: leaf } => {
700 debug_assert!(
701 !matches!(leaf.body, Body::Dictionary { .. })
702 || !matches!(leaf.validity, Validity::AllValid),
703 "a dictionary was stacked on a dictionary without going through the constructor"
704 );
705 (codes.iter().map(|&code| inner[code as usize]).collect(), Arc::unwrap_or_clone(leaf))
710 }
711 body => (codes, Vector { ty, len, validity, body }),
712 }
713}
714
715const NOWHERE: usize = usize::MAX;
720
721fn copy_of(data: &Data, at: &[usize]) -> Data {
727 macro_rules! copied {
728 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
729 match data {
730 Data::Empty => Data::Empty,
731 $(Data::$variant(values) => {
732 let mut out = Buffer::with_capacity(at.len());
733 for &index in at {
734 out.push(values.get(index).copied().unwrap_or($zero));
737 }
738 Data::$variant(out)
739 })+
740 Data::Varlen(values) => {
744 let mut out = StringColumn::with_capacity(at.len());
745 let views = values.views();
750 out.reserve_bytes(
751 at.iter()
752 .filter_map(|&index| views.get(index))
753 .filter(|view| !view.is_inline())
754 .map(StringView::len)
755 .sum(),
756 );
757 for &index in at {
758 out.push_from(values, index);
759 }
760 Data::Varlen(out)
761 }
762 }
763 };
764 }
765 crate::for_each_layout!(fixed, copied)
766}
767
768fn layout_of(data: &Data) -> rudb_common::PhysicalType {
773 use rudb_common::PhysicalType as P;
774 macro_rules! layouts {
775 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
776 match data {
777 Data::Empty => P::Empty,
778 $(Data::$variant(_) => P::$variant,)+
779 }
780 };
781 }
782 crate::for_each_layout!(all, layouts)
783}
784
785fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
790 let signed = || data.signed_at(index);
791 let unsigned = || data.unsigned_at(index);
792 let value = match ty {
793 LogicalType::Boolean => match data {
794 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
795 _ => None,
796 },
797 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
798 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
799 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
800 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
801 LogicalType::HugeInt => signed().map(Value::HugeInt),
802 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
803 LogicalType::USmallInt => {
804 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
805 }
806 LogicalType::UInteger => {
807 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
808 }
809 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
810 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
811 LogicalType::Float => match data {
812 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
813 _ => None,
814 },
815 LogicalType::Double => match data {
816 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
817 _ => None,
818 },
819 LogicalType::Decimal { width, scale } => {
820 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
821 }
822 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
823 LogicalType::Blob | LogicalType::Bit => {
824 data.bytes_at(index).map(|bytes| Value::Blob(bytes.to_vec()))
825 }
826 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
827 LogicalType::Time | LogicalType::TimeTz => {
828 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
829 }
830 LogicalType::Timestamp
831 | LogicalType::TimestampS
832 | LogicalType::TimestampMs
833 | LogicalType::TimestampNs
834 | LogicalType::TimestampTz => {
835 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
836 }
837 LogicalType::Interval => match data {
838 Data::Interval(v) => {
839 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
840 }
841 _ => None,
842 },
843 _ => None,
844 };
845 value.unwrap_or(Value::Null)
846}
847
848fn empty_data_for(ty: &LogicalType) -> Result<Data> {
850 use rudb_common::PhysicalType as P;
851 macro_rules! empties {
852 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
853 match ty.physical() {
854 P::Empty => Data::Empty,
855 $(P::$variant => Data::$variant(Buffer::new()),)+
856 P::Varlen => Data::Varlen(StringColumn::new()),
857 other => {
858 return Err(Error::not_implemented(format!(
859 "a flat vector of {other:?} data, which arrives with the storage layer"
860 )));
861 }
862 }
863 };
864 }
865 Ok(crate::for_each_layout!(fixed, empties))
866}
867
868fn push_value(data: &mut Data, value: &Value) -> Result<()> {
873 macro_rules! push {
874 ($vec:expr, $variant:path, $zero:expr) => {
875 match value {
876 Value::Null => $vec.push($zero),
877 $variant(x) => $vec.push(*x),
878 other => {
879 return Err(Error::internal(format!(
880 "{other:?} does not belong in this vector"
881 )));
882 }
883 }
884 };
885 }
886 macro_rules! decimal {
892 ($vec:expr, $ty:ty, $unscaled:expr) => {
893 match <$ty>::try_from(*$unscaled) {
894 Ok(x) => $vec.push(x),
895 Err(_) => {
896 return Err(Error::internal(format!(
897 "an unscaled decimal of {} does not fit the run its precision chose",
898 $unscaled
899 )));
900 }
901 }
902 };
903 }
904 match data {
905 Data::Empty => {}
906 Data::Bool(v) => push!(v, Value::Boolean, false),
907 Data::Int8(v) => push!(v, Value::TinyInt, 0),
908 Data::Int16(v) => match value {
909 Value::Null => v.push(0),
910 Value::SmallInt(x) => v.push(*x),
911 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
912 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
913 },
914 Data::Int32(v) => match value {
915 Value::Null => v.push(0),
916 Value::Integer(x) | Value::Date(x) => v.push(*x),
917 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
918 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
919 },
920 Data::Int64(v) => match value {
921 Value::Null => v.push(0),
922 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
923 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
924 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
925 },
926 Data::Int128(v) => match value {
927 Value::Null => v.push(0),
928 Value::HugeInt(x) => v.push(*x),
929 Value::Decimal { unscaled, .. } => v.push(*unscaled),
930 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
931 },
932 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
933 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
934 Data::UInt32(v) => push!(v, Value::UInteger, 0),
935 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
936 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
937 Data::Float32(v) => push!(v, Value::Float, 0.0),
938 Data::Float64(v) => push!(v, Value::Double, 0.0),
939 Data::Interval(v) => match value {
940 Value::Null => v.push((0, 0, 0)),
941 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
942 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
943 },
944 Data::Varlen(column) => match value {
945 Value::Null => {
946 column.push("");
947 }
948 Value::Varchar(text) => {
949 column.push(text);
950 }
951 Value::Blob(bytes) => {
955 column.push_bytes(bytes);
956 }
957 other => return Err(Error::internal(format!("{other:?} is not a string"))),
958 },
959 }
960 Ok(())
961}
962
963#[cfg(test)]
964mod tests {
965 use std::sync::Arc;
966
967 use rudb_common::{LogicalType, Value};
968
969 use super::{Body, Data, Form, VECTOR_SIZE, Vector};
970 use crate::string::StringColumn;
971 use crate::validity::Validity;
972
973 fn integers(values: &[i32]) -> Vector {
974 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
975 }
976
977 #[test]
978 fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
979 let values = Vector::from_values(
980 LogicalType::Varchar,
981 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
982 )
983 .unwrap();
984 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
985
986 let piece = vector.slice(1, 3).unwrap();
987 assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
988 assert_eq!(piece.len(), 3);
989 assert_eq!(
990 piece.iter().collect::<Vec<_>>(),
991 [
992 Value::Varchar("blue".into()),
993 Value::Varchar("blue".into()),
994 Value::Varchar("red".into())
995 ]
996 );
997 assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
998 }
999
1000 #[test]
1001 fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
1002 let values = Vector::from_values(
1007 LogicalType::Varchar,
1008 &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
1009 )
1010 .unwrap();
1011 let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
1012 let Body::Dictionary { values: whole, .. } = &vector.body else {
1013 panic!("a dictionary vector holds a dictionary");
1014 };
1015
1016 let piece = vector.slice(1, 3).unwrap();
1017 let Body::Dictionary { codes, values: cut } = &piece.body else {
1018 panic!("a slice of a dictionary is a dictionary");
1019 };
1020 assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
1021 assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
1022
1023 let again = piece.slice(1, 2).unwrap();
1025 let Body::Dictionary { values: cut, .. } = &again.body else {
1026 panic!("a slice of a slice of a dictionary is a dictionary");
1027 };
1028 assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
1029 assert_eq!(
1030 again.iter().collect::<Vec<_>>(),
1031 [Value::Varchar("blue".into()), Value::Varchar("red".into())]
1032 );
1033 }
1034
1035 #[test]
1036 fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
1037 let vector =
1038 integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
1039 let piece = vector.slice(1, 2).unwrap();
1040 assert!(piece.validity().is_valid(0));
1041 assert!(!piece.validity().is_valid(1));
1042 assert_eq!(piece.value_at(1), Value::Null);
1043 }
1044
1045 #[test]
1046 fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
1047 let vector = Vector::sequence(100, 5, 10);
1048 let piece = vector.slice(3, 4).unwrap();
1049 assert_eq!(piece.form(), Form::Sequence);
1050 assert_eq!(
1051 piece.iter().collect::<Vec<_>>(),
1052 [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
1053 );
1054 }
1055
1056 #[test]
1057 fn slicing_a_constant_is_a_shorter_constant() {
1058 let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
1059 let piece = vector.slice(2, 3).unwrap();
1060 assert_eq!(piece.form(), Form::Constant);
1061 assert_eq!(piece.len(), 3);
1062 assert_eq!(piece.value_at(2), Value::Integer(9));
1063 }
1064
1065 #[test]
1066 fn slicing_the_whole_vector_hands_it_back_as_it_was() {
1067 let vector = integers(&[1, 2, 3]);
1068 assert_eq!(
1069 vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
1070 [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1071 );
1072 }
1073
1074 #[test]
1075 fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
1076 let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
1077 assert!(error.to_string().contains("of a vector of 3"), "{error}");
1078 }
1079
1080 #[test]
1081 fn the_vector_size_is_the_one_the_design_is_built_around() {
1082 assert_eq!(VECTOR_SIZE, 1024);
1085 assert_eq!(VECTOR_SIZE / 64, 16);
1086 }
1087
1088 #[test]
1089 fn a_flat_vector_reads_back_what_was_put_in_it() {
1090 let vector = integers(&[1, 2, 3]);
1091 assert_eq!(vector.form(), Form::Flat);
1092 assert_eq!(vector.len(), 3);
1093 assert_eq!(vector.value_at(1), Value::Integer(2));
1094 assert_eq!(
1095 vector.iter().collect::<Vec<_>>(),
1096 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1097 );
1098 }
1099
1100 #[test]
1101 fn a_vector_built_from_values_reads_the_same_values_back() {
1102 let vector = Vector::from_values(
1103 LogicalType::Varchar,
1104 &[
1105 Value::Varchar("a".to_string()),
1106 Value::Null,
1107 Value::Varchar("a string too long to sit inside a view".to_string()),
1108 ],
1109 )
1110 .expect("strings and a null");
1111 assert_eq!(vector.len(), 3);
1112 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
1113 assert_eq!(vector.value_at(1), Value::Null);
1114 assert_eq!(
1115 vector.value_at(2),
1116 Value::Varchar("a string too long to sit inside a view".to_string())
1117 );
1118 }
1119
1120 #[test]
1123 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
1124 let vector = Vector::from_values(
1125 LogicalType::Integer,
1126 &[Value::Integer(1), Value::Null, Value::Integer(3)],
1127 )
1128 .expect("integers and a null");
1129 assert_eq!(vector.value_at(2), Value::Integer(3));
1130 assert!(vector.validity().has_nulls(3), "the middle one is null");
1131 }
1132
1133 #[test]
1134 fn a_value_the_type_cannot_hold_is_refused() {
1135 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
1136 assert!(wrong.is_err(), "a string is not an integer");
1137 }
1138
1139 #[test]
1140 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
1141 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
1143 assert!(wrong.is_err());
1144 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
1145 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
1146 }
1147
1148 #[test]
1149 fn a_constant_vector_costs_one_value_whatever_its_length() {
1150 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
1151 assert_eq!(vector.form(), Form::Constant);
1152 assert_eq!(vector.len(), VECTOR_SIZE);
1153 assert_eq!(vector.value_at(0), Value::Integer(7));
1154 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
1155 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
1156 }
1157
1158 #[test]
1159 fn a_constant_null_is_all_invalid_without_being_told() {
1160 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
1161 assert_eq!(vector.validity(), &Validity::AllInvalid);
1162 assert_eq!(vector.value_at(3), Value::Null);
1163 }
1164
1165 #[test]
1166 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
1167 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
1168 assert_eq!(vector.form(), Form::Sequence);
1169 assert_eq!(vector.value_at(0), Value::BigInt(100));
1170 assert_eq!(vector.value_at(923), Value::BigInt(1023));
1171 let stepped = Vector::sequence(0, 5, 4);
1172 assert_eq!(
1173 stepped.iter().collect::<Vec<_>>(),
1174 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
1175 );
1176 }
1177
1178 #[test]
1179 fn a_dictionary_vector_reads_through_its_codes() {
1180 let mut column = StringColumn::new();
1181 column.push("red");
1182 column.push("green");
1183 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1184 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
1185 assert_eq!(vector.form(), Form::Dictionary);
1186 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
1187 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
1188 assert_eq!(vector.len(), 4);
1189 }
1190
1191 #[test]
1194 fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
1195 let mut column = StringColumn::new();
1196 column.push("red");
1197 column.push("green");
1198 column.push("");
1199 let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1200 for index in 0..flat.len() {
1201 assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
1202 }
1203 let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
1204 for index in 0..dictionary.len() {
1205 assert_eq!(
1206 dictionary.text_at(index).map(str::to_string),
1207 text_of(&dictionary.value_at(index))
1208 );
1209 }
1210 assert_eq!(dictionary.text_at(4), None, "past the end");
1211 }
1212
1213 #[test]
1217 fn text_is_refused_where_it_is_not_stored_as_itself() {
1218 let nulls =
1219 Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
1220 .unwrap();
1221 assert_eq!(nulls.text_at(0), Some("red"));
1222 assert_eq!(nulls.text_at(1), None, "a null has no text");
1223 let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
1224 assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
1225 assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
1226 let mut bytes = StringColumn::new();
1227 bytes.push("red");
1228 let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
1229 assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
1230 }
1231
1232 fn text_of(value: &Value) -> Option<String> {
1234 match value {
1235 Value::Varchar(text) => Some(text.clone()),
1236 _ => None,
1237 }
1238 }
1239
1240 #[test]
1241 fn a_dictionary_code_past_the_end_is_refused() {
1242 let values = integers(&[1, 2]);
1245 assert!(Vector::dictionary(vec![0, 2], values).is_err());
1246 }
1247
1248 #[test]
1249 fn every_form_flattens_to_the_same_values_it_reads_out() {
1250 let mut column = StringColumn::new();
1254 column.push("alpha");
1255 column.push("beta");
1256 let dictionary = Vector::dictionary(
1257 vec![1, 0, 1],
1258 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1259 )
1260 .unwrap();
1261 let cases = [
1262 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
1263 Vector::sequence(7, -2, 5),
1264 dictionary,
1265 ];
1266 for vector in cases {
1267 let flat = vector.flatten().unwrap();
1268 assert_eq!(flat.form(), Form::Flat);
1269 assert_eq!(flat.len(), vector.len());
1270 for index in 0..vector.len() {
1271 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
1272 }
1273 }
1274 }
1275
1276 #[test]
1277 fn a_null_still_occupies_a_position_after_flattening() {
1278 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
1282 let flat = vector.flatten().unwrap();
1283 assert_eq!(flat.value_at(0), Value::BigInt(0));
1284 assert_eq!(flat.value_at(1), Value::Null);
1285 assert_eq!(flat.value_at(2), Value::BigInt(2));
1286 assert_eq!(flat.value_at(3), Value::BigInt(3));
1287 }
1288
1289 #[test]
1294 fn a_null_behind_a_dictionary_survives_flattening() {
1295 let values =
1296 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1297 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1298 let flat = dictionary.flatten().unwrap();
1299 assert_eq!(flat.value_at(0), Value::Null);
1300 assert_eq!(flat.value_at(1), Value::Integer(3));
1301 assert_eq!(flat.value_at(2), Value::Null);
1302 }
1303
1304 #[test]
1307 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1308 let mut column = StringColumn::new();
1309 column.push("alpha");
1310 column.push("beta");
1311 column.push("gamma");
1312 let cases = [
1313 integers(&[10, 20, 30, 40]),
1314 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1315 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1316 Vector::sequence(100, -7, 4),
1317 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1318 Vector::dictionary(
1319 vec![2, 0, 1, 2],
1320 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1321 )
1322 .unwrap(),
1323 Vector::dictionary(
1324 vec![1, 0, 1, 0],
1325 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1326 .unwrap(),
1327 )
1328 .unwrap(),
1329 ];
1330 let wanted = [3_u32, 0, 2, 2, 1];
1331 for vector in cases {
1332 let gathered = vector.gather(&wanted).unwrap();
1333 assert_eq!(gathered.len(), wanted.len());
1334 assert_eq!(gathered.logical_type(), vector.logical_type());
1335 for (slot, &index) in wanted.iter().enumerate() {
1336 assert_eq!(
1337 gathered.value_at(slot),
1338 vector.value_at(index as usize),
1339 "slot {slot} of {:?}",
1340 vector.form()
1341 );
1342 }
1343 }
1344 }
1345
1346 #[test]
1350 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1351 let vector = integers(&[1, 2, 3]);
1352 let gathered = vector.gather(&[2, 9]).unwrap();
1353 assert_eq!(gathered.value_at(0), Value::Integer(3));
1354 assert_eq!(gathered.value_at(1), Value::Null);
1355 }
1356
1357 #[test]
1361 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1362 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1363 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1364 assert_eq!(gathered.len(), 3);
1365 assert_eq!(gathered.value_at(0), Value::Null);
1366 assert_eq!(gathered.value_at(2), Value::Null);
1367 }
1368
1369 #[test]
1372 fn gathering_a_constant_stays_a_constant() {
1373 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1374 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1375 assert_eq!(gathered.form(), Form::Constant);
1376 assert_eq!(gathered.len(), 3);
1377 assert_eq!(gathered.value_at(2), Value::Integer(4));
1378 }
1379
1380 #[test]
1385 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1386 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1387 .unwrap()
1388 .with_validity(Validity::from_iter(3, |index| index != 2));
1389 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1390 let gathered = outer.gather(&[0, 1]).unwrap();
1391 assert_eq!(gathered.form(), Form::Flat);
1392 assert_eq!(gathered.value_at(0), Value::Integer(8));
1393 assert_eq!(gathered.value_at(1), Value::Null);
1394 }
1395
1396 #[test]
1401 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1402 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1403 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1404 let (codes, values) = outer.dictionary_parts().unwrap();
1405 assert_eq!(codes, [1, 0]);
1406 assert_eq!(values.form(), Form::Flat);
1407 assert_eq!(outer.value_at(0), Value::Integer(8));
1408 assert_eq!(outer.value_at(1), Value::Integer(7));
1409 }
1410
1411 #[test]
1414 fn stacking_dictionaries_does_not_make_them_deeper() {
1415 let mut vector = integers(&[10, 20, 30, 40]);
1416 for _ in 0..4 {
1417 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1418 }
1419 let (codes, values) = vector.dictionary_parts().unwrap();
1420 assert_eq!(values.form(), Form::Flat);
1421 assert_eq!(codes, [0, 1, 2, 3]);
1422 assert_eq!(
1423 vector.iter().collect::<Vec<_>>(),
1424 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1425 );
1426 }
1427
1428 #[test]
1431 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1432 let values =
1433 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1434 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1435 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1436 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1437 assert_eq!(outer.value_at(0), Value::Null);
1438 assert_eq!(outer.value_at(1), Value::Integer(3));
1439 }
1440
1441 #[test]
1445 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1446 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1447 .unwrap()
1448 .with_validity(Validity::from_iter(3, |index| index != 1));
1449 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1450 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1451 assert_eq!(outer.value_at(0), Value::Null);
1452 assert_eq!(outer.value_at(1), Value::Integer(3));
1453 assert_eq!(outer.value_at(2), Value::Integer(1));
1454 }
1455
1456 #[test]
1457 fn flattening_a_flat_vector_is_the_same_vector() {
1458 let vector = integers(&[1, 2, 3]);
1459 assert_eq!(vector.flatten().unwrap(), vector);
1460 }
1461
1462 #[test]
1463 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1464 let ty = LogicalType::decimal(9, 2).unwrap();
1465 let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
1466 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1467 assert_eq!(vector.value_at(0).to_string(), "12.34");
1468 }
1469
1470 #[test]
1471 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1472 for (width, scale, unscaled) in
1475 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1476 {
1477 let ty = LogicalType::decimal(width, scale).unwrap();
1478 let value = Value::Decimal { unscaled, width, scale };
1479 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1480 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1481 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1482 }
1483 }
1484
1485 #[test]
1490 fn a_blob_holds_bytes_that_are_not_text() {
1491 let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
1492 let values = [
1493 bytes(b"a\xffb"),
1494 bytes(b"\x00\x01\x02"),
1495 Value::Null,
1496 bytes(b"\xed\xa0\x80 and long enough to leave the view"),
1497 bytes(b""),
1498 ];
1499 let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
1500 for (index, value) in values.iter().enumerate() {
1501 assert_eq!(&vector.value_at(index), value, "row {index}");
1502 }
1503 }
1504
1505 #[test]
1506 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1507 let ty = LogicalType::decimal(4, 1).unwrap();
1510 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1511 let error = Vector::from_values(ty, &[value]).unwrap_err();
1512 assert!(error.to_string().contains("does not fit"), "{error}");
1513 }
1514
1515 #[test]
1516 fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
1517 let flat = integers(&[1; 1000]);
1518 assert!(
1519 flat.footprint() >= 4000,
1520 "a thousand i32 are four thousand bytes: {}",
1521 flat.footprint()
1522 );
1523 let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
1526 assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
1527 let sequence = Vector::sequence(0, 1, 1_000_000);
1528 assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
1529 }
1530
1531 #[test]
1532 fn a_string_vector_costs_the_bytes_of_its_long_strings() {
1533 let short =
1534 Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
1535 let long = "a string well past the sixteen bytes a view holds inline".to_string();
1536 let spilled =
1537 Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
1538 assert!(
1539 spilled.footprint() >= short.footprint() + long.len(),
1540 "the arena is counted: {} against {}",
1541 spilled.footprint(),
1542 short.footprint()
1543 );
1544 }
1545}