1use rudb_common::{Error, LogicalType, Result, Value};
19
20use crate::string::{StringColumn, StringView};
21use crate::validity::Validity;
22
23pub const VECTOR_SIZE: usize = 1024;
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44#[non_exhaustive]
45pub enum Form {
46 Flat,
48 Constant,
50 Sequence,
52 Dictionary,
54}
55
56#[derive(Debug, Clone, PartialEq)]
61#[non_exhaustive]
62pub enum Data {
63 Empty,
65 Bool(Vec<bool>),
67 Int8(Vec<i8>),
69 Int16(Vec<i16>),
71 Int32(Vec<i32>),
73 Int64(Vec<i64>),
75 Int128(Vec<i128>),
77 UInt8(Vec<u8>),
79 UInt16(Vec<u16>),
81 UInt32(Vec<u32>),
83 UInt64(Vec<u64>),
85 UInt128(Vec<u128>),
87 Float32(Vec<f32>),
89 Float64(Vec<f64>),
91 Interval(Vec<(i32, i32, i64)>),
93 Varlen(StringColumn),
95}
96
97impl Data {
98 #[must_use]
100 pub fn len(&self) -> usize {
101 match self {
102 Self::Empty => 0,
103 Self::Bool(v) => v.len(),
104 Self::Int8(v) => v.len(),
105 Self::Int16(v) => v.len(),
106 Self::Int32(v) => v.len(),
107 Self::Int64(v) => v.len(),
108 Self::Int128(v) => v.len(),
109 Self::UInt8(v) => v.len(),
110 Self::UInt16(v) => v.len(),
111 Self::UInt32(v) => v.len(),
112 Self::UInt64(v) => v.len(),
113 Self::UInt128(v) => v.len(),
114 Self::Float32(v) => v.len(),
115 Self::Float64(v) => v.len(),
116 Self::Interval(v) => v.len(),
117 Self::Varlen(v) => v.len(),
118 }
119 }
120
121 #[must_use]
123 pub fn is_empty(&self) -> bool {
124 self.len() == 0
125 }
126
127 #[must_use]
132 pub fn signed_at(&self, index: usize) -> Option<i128> {
133 match self {
134 Self::Int8(v) => v.get(index).map(|&x| i128::from(x)),
135 Self::Int16(v) => v.get(index).map(|&x| i128::from(x)),
136 Self::Int32(v) => v.get(index).map(|&x| i128::from(x)),
137 Self::Int64(v) => v.get(index).map(|&x| i128::from(x)),
138 Self::Int128(v) => v.get(index).copied(),
139 _ => None,
140 }
141 }
142
143 #[must_use]
145 pub fn unsigned_at(&self, index: usize) -> Option<u128> {
146 match self {
147 Self::UInt8(v) => v.get(index).map(|&x| u128::from(x)),
148 Self::UInt16(v) => v.get(index).map(|&x| u128::from(x)),
149 Self::UInt32(v) => v.get(index).map(|&x| u128::from(x)),
150 Self::UInt64(v) => v.get(index).map(|&x| u128::from(x)),
151 Self::UInt128(v) => v.get(index).copied(),
152 _ => None,
153 }
154 }
155
156 #[must_use]
158 pub fn str_at(&self, index: usize) -> Option<&str> {
159 match self {
160 Self::Varlen(column) => column.get(index),
161 _ => None,
162 }
163 }
164}
165
166#[derive(Debug, Clone, PartialEq)]
168pub struct Vector {
169 ty: LogicalType,
170 len: usize,
171 validity: Validity,
172 body: Body,
173}
174
175#[derive(Debug, Clone, PartialEq)]
177enum Body {
178 Flat(Data),
179 Constant(Box<Value>),
180 Sequence { start: i64, step: i64 },
181 Dictionary { codes: Vec<u32>, values: Box<Vector> },
182}
183
184impl Vector {
185 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
193 let len = data.len();
194 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
195 return Err(Error::internal(format!(
196 "a {ty} vector cannot hold {:?} data",
197 layout_of(&data)
198 )));
199 }
200 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
201 }
202
203 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
215 let mut data = empty_data_for(&ty)?;
216 for value in values {
217 push_value(&mut data, value)?;
218 }
219 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
220 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
221 }
222
223 #[must_use]
228 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
229 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
230 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
231 }
232
233 #[must_use]
238 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
239 Self {
240 ty: LogicalType::BigInt,
241 len,
242 validity: Validity::AllValid,
243 body: Body::Sequence { start, step },
244 }
245 }
246
247 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
277 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
278 return Err(Error::internal(format!(
279 "dictionary code {bad} is past the end of a {} value dictionary",
280 values.len()
281 )));
282 }
283 let (codes, values) = compose(codes, values);
284 Ok(Self {
285 ty: values.ty.clone(),
286 len: codes.len(),
287 validity: Validity::AllValid,
288 body: Body::Dictionary { codes, values: Box::new(values) },
289 })
290 }
291
292 #[must_use]
294 pub fn with_validity(mut self, validity: Validity) -> Self {
295 self.validity = validity;
296 self
297 }
298
299 #[must_use]
301 pub fn logical_type(&self) -> &LogicalType {
302 &self.ty
303 }
304
305 #[must_use]
307 pub fn len(&self) -> usize {
308 self.len
309 }
310
311 #[must_use]
313 pub fn is_empty(&self) -> bool {
314 self.len == 0
315 }
316
317 #[must_use]
319 pub fn validity(&self) -> &Validity {
320 &self.validity
321 }
322
323 #[must_use]
325 pub fn form(&self) -> Form {
326 match self.body {
327 Body::Flat(_) => Form::Flat,
328 Body::Constant(_) => Form::Constant,
329 Body::Sequence { .. } => Form::Sequence,
330 Body::Dictionary { .. } => Form::Dictionary,
331 }
332 }
333
334 #[must_use]
339 pub fn data(&self) -> Option<&Data> {
340 match &self.body {
341 Body::Flat(data) => Some(data),
342 _ => None,
343 }
344 }
345
346 #[must_use]
353 pub fn constant_value(&self) -> Option<&Value> {
354 match &self.body {
355 Body::Constant(value) => Some(value.as_ref()),
356 _ => None,
357 }
358 }
359
360 #[must_use]
374 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
375 match &self.body {
376 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
377 _ => None,
378 }
379 }
380
381 #[must_use]
383 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
384 match self.body {
385 Body::Sequence { start, step } => Some((start, step)),
386 _ => None,
387 }
388 }
389
390 #[must_use]
396 pub fn value_at(&self, index: usize) -> Value {
397 if index >= self.len || !self.validity.is_valid(index) {
398 return Value::Null;
399 }
400 match &self.body {
401 Body::Constant(value) => value.as_ref().clone(),
402 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
403 Body::Dictionary { codes, values } => match codes.get(index) {
404 Some(&code) => values.value_at(code as usize),
405 None => Value::Null,
406 },
407 Body::Flat(data) => value_from(&self.ty, data, index),
408 }
409 }
410
411 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
413 (0..self.len).map(|index| self.value_at(index))
414 }
415
416 pub fn flatten(&self) -> Result<Self> {
427 if let Body::Flat(_) = self.body {
428 return Ok(self.clone());
429 }
430 self.copied((0..self.len).collect(), false)
431 }
432
433 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
449 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
450 }
451
452 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
459 let rows = at.len();
460 let (at, leaf) = self.resolve(at);
461 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
462 let validity = Validity::from_run(&live);
463 let body = match &leaf.body {
464 Body::Constant(value) => {
467 if constants_stay && matches!(validity, Validity::AllValid) {
468 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
469 }
470 let mut data = empty_data_for(&self.ty)?;
471 for &index in &at {
472 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
473 }
474 Body::Flat(data)
475 }
476 Body::Sequence { start, step } => Body::Flat(Data::Int64(
479 at.iter()
480 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
481 .collect(),
482 )),
483 Body::Flat(Data::Empty) => {
487 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
488 }
489 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
490 Body::Dictionary { .. } => {
492 return Err(Error::internal("a dictionary survived being resolved"));
493 }
494 };
495 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
496 }
497
498 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
504 let mut source = self;
505 loop {
506 for slot in &mut at {
507 if *slot >= source.len || !source.validity.is_valid(*slot) {
508 *slot = NOWHERE;
509 }
510 }
511 let Body::Dictionary { codes, values } = &source.body else {
512 return (at, source);
513 };
514 for slot in &mut at {
515 *slot = match codes.get(*slot) {
516 Some(&code) => code as usize,
517 None => NOWHERE,
518 };
519 }
520 source = values.as_ref();
521 }
522 }
523}
524
525fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
537 if !matches!(values.validity, Validity::AllValid) {
540 return (codes, values);
541 }
542 let Vector { ty, len, validity, body } = values;
543 match body {
544 Body::Dictionary { codes: inner, values: leaf } => {
545 debug_assert!(
546 !matches!(leaf.body, Body::Dictionary { .. })
547 || !matches!(leaf.validity, Validity::AllValid),
548 "a dictionary was stacked on a dictionary without going through the constructor"
549 );
550 (codes.iter().map(|&code| inner[code as usize]).collect(), *leaf)
551 }
552 body => (codes, Vector { ty, len, validity, body }),
553 }
554}
555
556const NOWHERE: usize = usize::MAX;
561
562fn copy_of(data: &Data, at: &[usize]) -> Data {
568 macro_rules! copied {
569 ($values:expr, $variant:path, $zero:expr) => {{
570 let values = $values;
571 let mut out = Vec::with_capacity(at.len());
572 for &index in at {
573 out.push(values.get(index).copied().unwrap_or($zero));
576 }
577 $variant(out)
578 }};
579 }
580 match data {
581 Data::Empty => Data::Empty,
582 Data::Bool(values) => copied!(values, Data::Bool, false),
583 Data::Int8(values) => copied!(values, Data::Int8, 0),
584 Data::Int16(values) => copied!(values, Data::Int16, 0),
585 Data::Int32(values) => copied!(values, Data::Int32, 0),
586 Data::Int64(values) => copied!(values, Data::Int64, 0),
587 Data::Int128(values) => copied!(values, Data::Int128, 0),
588 Data::UInt8(values) => copied!(values, Data::UInt8, 0),
589 Data::UInt16(values) => copied!(values, Data::UInt16, 0),
590 Data::UInt32(values) => copied!(values, Data::UInt32, 0),
591 Data::UInt64(values) => copied!(values, Data::UInt64, 0),
592 Data::UInt128(values) => copied!(values, Data::UInt128, 0),
593 Data::Float32(values) => copied!(values, Data::Float32, 0.0),
594 Data::Float64(values) => copied!(values, Data::Float64, 0.0),
595 Data::Interval(values) => copied!(values, Data::Interval, (0, 0, 0)),
596 Data::Varlen(values) => {
599 let mut out = StringColumn::with_capacity(at.len());
600 let views = values.views();
604 out.reserve_bytes(
605 at.iter()
606 .filter_map(|&index| views.get(index))
607 .filter(|view| !view.is_inline())
608 .map(StringView::len)
609 .sum(),
610 );
611 for &index in at {
612 out.push(values.get(index).unwrap_or(""));
613 }
614 Data::Varlen(out)
615 }
616 }
617}
618
619fn layout_of(data: &Data) -> rudb_common::PhysicalType {
621 use rudb_common::PhysicalType as P;
622 match data {
623 Data::Empty => P::Empty,
624 Data::Bool(_) => P::Bool,
625 Data::Int8(_) => P::Int8,
626 Data::Int16(_) => P::Int16,
627 Data::Int32(_) => P::Int32,
628 Data::Int64(_) => P::Int64,
629 Data::Int128(_) => P::Int128,
630 Data::UInt8(_) => P::UInt8,
631 Data::UInt16(_) => P::UInt16,
632 Data::UInt32(_) => P::UInt32,
633 Data::UInt64(_) => P::UInt64,
634 Data::UInt128(_) => P::UInt128,
635 Data::Float32(_) => P::Float32,
636 Data::Float64(_) => P::Float64,
637 Data::Interval(_) => P::Interval,
638 Data::Varlen(_) => P::Varlen,
639 }
640}
641
642fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
647 let signed = || data.signed_at(index);
648 let unsigned = || data.unsigned_at(index);
649 let value = match ty {
650 LogicalType::Boolean => match data {
651 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
652 _ => None,
653 },
654 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
655 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
656 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
657 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
658 LogicalType::HugeInt => signed().map(Value::HugeInt),
659 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
660 LogicalType::USmallInt => {
661 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
662 }
663 LogicalType::UInteger => {
664 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
665 }
666 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
667 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
668 LogicalType::Float => match data {
669 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
670 _ => None,
671 },
672 LogicalType::Double => match data {
673 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
674 _ => None,
675 },
676 LogicalType::Decimal { width, scale } => {
677 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
678 }
679 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
680 LogicalType::Blob | LogicalType::Bit => {
681 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
682 }
683 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
684 LogicalType::Time | LogicalType::TimeTz => {
685 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
686 }
687 LogicalType::Timestamp
688 | LogicalType::TimestampS
689 | LogicalType::TimestampMs
690 | LogicalType::TimestampNs
691 | LogicalType::TimestampTz => {
692 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
693 }
694 LogicalType::Interval => match data {
695 Data::Interval(v) => {
696 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
697 }
698 _ => None,
699 },
700 _ => None,
701 };
702 value.unwrap_or(Value::Null)
703}
704
705fn empty_data_for(ty: &LogicalType) -> Result<Data> {
707 use rudb_common::PhysicalType as P;
708 Ok(match ty.physical() {
709 P::Empty => Data::Empty,
710 P::Bool => Data::Bool(Vec::new()),
711 P::Int8 => Data::Int8(Vec::new()),
712 P::Int16 => Data::Int16(Vec::new()),
713 P::Int32 => Data::Int32(Vec::new()),
714 P::Int64 => Data::Int64(Vec::new()),
715 P::Int128 => Data::Int128(Vec::new()),
716 P::UInt8 => Data::UInt8(Vec::new()),
717 P::UInt16 => Data::UInt16(Vec::new()),
718 P::UInt32 => Data::UInt32(Vec::new()),
719 P::UInt64 => Data::UInt64(Vec::new()),
720 P::UInt128 => Data::UInt128(Vec::new()),
721 P::Float32 => Data::Float32(Vec::new()),
722 P::Float64 => Data::Float64(Vec::new()),
723 P::Interval => Data::Interval(Vec::new()),
724 P::Varlen => Data::Varlen(StringColumn::new()),
725 other => {
726 return Err(Error::not_implemented(format!(
727 "a flat vector of {other:?} data, which arrives with the storage layer"
728 )));
729 }
730 })
731}
732
733fn push_value(data: &mut Data, value: &Value) -> Result<()> {
738 macro_rules! push {
739 ($vec:expr, $variant:path, $zero:expr) => {
740 match value {
741 Value::Null => $vec.push($zero),
742 $variant(x) => $vec.push(*x),
743 other => {
744 return Err(Error::internal(format!(
745 "{other:?} does not belong in this vector"
746 )));
747 }
748 }
749 };
750 }
751 macro_rules! decimal {
757 ($vec:expr, $ty:ty, $unscaled:expr) => {
758 match <$ty>::try_from(*$unscaled) {
759 Ok(x) => $vec.push(x),
760 Err(_) => {
761 return Err(Error::internal(format!(
762 "an unscaled decimal of {} does not fit the run its precision chose",
763 $unscaled
764 )));
765 }
766 }
767 };
768 }
769 match data {
770 Data::Empty => {}
771 Data::Bool(v) => push!(v, Value::Boolean, false),
772 Data::Int8(v) => push!(v, Value::TinyInt, 0),
773 Data::Int16(v) => match value {
774 Value::Null => v.push(0),
775 Value::SmallInt(x) => v.push(*x),
776 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
777 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
778 },
779 Data::Int32(v) => match value {
780 Value::Null => v.push(0),
781 Value::Integer(x) | Value::Date(x) => v.push(*x),
782 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
783 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
784 },
785 Data::Int64(v) => match value {
786 Value::Null => v.push(0),
787 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
788 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
789 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
790 },
791 Data::Int128(v) => match value {
792 Value::Null => v.push(0),
793 Value::HugeInt(x) => v.push(*x),
794 Value::Decimal { unscaled, .. } => v.push(*unscaled),
795 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
796 },
797 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
798 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
799 Data::UInt32(v) => push!(v, Value::UInteger, 0),
800 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
801 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
802 Data::Float32(v) => push!(v, Value::Float, 0.0),
803 Data::Float64(v) => push!(v, Value::Double, 0.0),
804 Data::Interval(v) => match value {
805 Value::Null => v.push((0, 0, 0)),
806 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
807 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
808 },
809 Data::Varlen(column) => match value {
810 Value::Null => {
811 column.push("");
812 }
813 Value::Varchar(text) => {
814 column.push(text);
815 }
816 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
820 Ok(text) => {
821 column.push(text);
822 }
823 Err(_) => {
824 return Err(Error::not_implemented(
825 "a blob that is not valid UTF-8, which needs the byte column from M2",
826 ));
827 }
828 },
829 other => return Err(Error::internal(format!("{other:?} is not a string"))),
830 },
831 }
832 Ok(())
833}
834
835#[cfg(test)]
836mod tests {
837 use rudb_common::{LogicalType, Value};
838
839 use super::{Data, Form, VECTOR_SIZE, Vector};
840 use crate::string::StringColumn;
841 use crate::validity::Validity;
842
843 fn integers(values: &[i32]) -> Vector {
844 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec())).unwrap()
845 }
846
847 #[test]
848 fn the_vector_size_is_the_one_the_design_is_built_around() {
849 assert_eq!(VECTOR_SIZE, 1024);
852 assert_eq!(VECTOR_SIZE / 64, 16);
853 }
854
855 #[test]
856 fn a_flat_vector_reads_back_what_was_put_in_it() {
857 let vector = integers(&[1, 2, 3]);
858 assert_eq!(vector.form(), Form::Flat);
859 assert_eq!(vector.len(), 3);
860 assert_eq!(vector.value_at(1), Value::Integer(2));
861 assert_eq!(
862 vector.iter().collect::<Vec<_>>(),
863 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
864 );
865 }
866
867 #[test]
868 fn a_vector_built_from_values_reads_the_same_values_back() {
869 let vector = Vector::from_values(
870 LogicalType::Varchar,
871 &[
872 Value::Varchar("a".to_string()),
873 Value::Null,
874 Value::Varchar("a string too long to sit inside a view".to_string()),
875 ],
876 )
877 .expect("strings and a null");
878 assert_eq!(vector.len(), 3);
879 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
880 assert_eq!(vector.value_at(1), Value::Null);
881 assert_eq!(
882 vector.value_at(2),
883 Value::Varchar("a string too long to sit inside a view".to_string())
884 );
885 }
886
887 #[test]
890 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
891 let vector = Vector::from_values(
892 LogicalType::Integer,
893 &[Value::Integer(1), Value::Null, Value::Integer(3)],
894 )
895 .expect("integers and a null");
896 assert_eq!(vector.value_at(2), Value::Integer(3));
897 assert!(vector.validity().has_nulls(3), "the middle one is null");
898 }
899
900 #[test]
901 fn a_value_the_type_cannot_hold_is_refused() {
902 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
903 assert!(wrong.is_err(), "a string is not an integer");
904 }
905
906 #[test]
907 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
908 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1]));
910 assert!(wrong.is_err());
911 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1]));
912 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
913 }
914
915 #[test]
916 fn a_constant_vector_costs_one_value_whatever_its_length() {
917 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
918 assert_eq!(vector.form(), Form::Constant);
919 assert_eq!(vector.len(), VECTOR_SIZE);
920 assert_eq!(vector.value_at(0), Value::Integer(7));
921 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
922 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
923 }
924
925 #[test]
926 fn a_constant_null_is_all_invalid_without_being_told() {
927 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
928 assert_eq!(vector.validity(), &Validity::AllInvalid);
929 assert_eq!(vector.value_at(3), Value::Null);
930 }
931
932 #[test]
933 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
934 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
935 assert_eq!(vector.form(), Form::Sequence);
936 assert_eq!(vector.value_at(0), Value::BigInt(100));
937 assert_eq!(vector.value_at(923), Value::BigInt(1023));
938 let stepped = Vector::sequence(0, 5, 4);
939 assert_eq!(
940 stepped.iter().collect::<Vec<_>>(),
941 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
942 );
943 }
944
945 #[test]
946 fn a_dictionary_vector_reads_through_its_codes() {
947 let mut column = StringColumn::new();
948 column.push("red");
949 column.push("green");
950 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
951 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
952 assert_eq!(vector.form(), Form::Dictionary);
953 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
954 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
955 assert_eq!(vector.len(), 4);
956 }
957
958 #[test]
959 fn a_dictionary_code_past_the_end_is_refused() {
960 let values = integers(&[1, 2]);
963 assert!(Vector::dictionary(vec![0, 2], values).is_err());
964 }
965
966 #[test]
967 fn every_form_flattens_to_the_same_values_it_reads_out() {
968 let mut column = StringColumn::new();
972 column.push("alpha");
973 column.push("beta");
974 let dictionary = Vector::dictionary(
975 vec![1, 0, 1],
976 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
977 )
978 .unwrap();
979 let cases = [
980 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
981 Vector::sequence(7, -2, 5),
982 dictionary,
983 ];
984 for vector in cases {
985 let flat = vector.flatten().unwrap();
986 assert_eq!(flat.form(), Form::Flat);
987 assert_eq!(flat.len(), vector.len());
988 for index in 0..vector.len() {
989 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
990 }
991 }
992 }
993
994 #[test]
995 fn a_null_still_occupies_a_position_after_flattening() {
996 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
1000 let flat = vector.flatten().unwrap();
1001 assert_eq!(flat.value_at(0), Value::BigInt(0));
1002 assert_eq!(flat.value_at(1), Value::Null);
1003 assert_eq!(flat.value_at(2), Value::BigInt(2));
1004 assert_eq!(flat.value_at(3), Value::BigInt(3));
1005 }
1006
1007 #[test]
1012 fn a_null_behind_a_dictionary_survives_flattening() {
1013 let values =
1014 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1015 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1016 let flat = dictionary.flatten().unwrap();
1017 assert_eq!(flat.value_at(0), Value::Null);
1018 assert_eq!(flat.value_at(1), Value::Integer(3));
1019 assert_eq!(flat.value_at(2), Value::Null);
1020 }
1021
1022 #[test]
1025 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1026 let mut column = StringColumn::new();
1027 column.push("alpha");
1028 column.push("beta");
1029 column.push("gamma");
1030 let cases = [
1031 integers(&[10, 20, 30, 40]),
1032 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1033 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1034 Vector::sequence(100, -7, 4),
1035 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1036 Vector::dictionary(
1037 vec![2, 0, 1, 2],
1038 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1039 )
1040 .unwrap(),
1041 Vector::dictionary(
1042 vec![1, 0, 1, 0],
1043 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1044 .unwrap(),
1045 )
1046 .unwrap(),
1047 ];
1048 let wanted = [3_u32, 0, 2, 2, 1];
1049 for vector in cases {
1050 let gathered = vector.gather(&wanted).unwrap();
1051 assert_eq!(gathered.len(), wanted.len());
1052 assert_eq!(gathered.logical_type(), vector.logical_type());
1053 for (slot, &index) in wanted.iter().enumerate() {
1054 assert_eq!(
1055 gathered.value_at(slot),
1056 vector.value_at(index as usize),
1057 "slot {slot} of {:?}",
1058 vector.form()
1059 );
1060 }
1061 }
1062 }
1063
1064 #[test]
1068 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1069 let vector = integers(&[1, 2, 3]);
1070 let gathered = vector.gather(&[2, 9]).unwrap();
1071 assert_eq!(gathered.value_at(0), Value::Integer(3));
1072 assert_eq!(gathered.value_at(1), Value::Null);
1073 }
1074
1075 #[test]
1079 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1080 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1081 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1082 assert_eq!(gathered.len(), 3);
1083 assert_eq!(gathered.value_at(0), Value::Null);
1084 assert_eq!(gathered.value_at(2), Value::Null);
1085 }
1086
1087 #[test]
1090 fn gathering_a_constant_stays_a_constant() {
1091 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1092 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1093 assert_eq!(gathered.form(), Form::Constant);
1094 assert_eq!(gathered.len(), 3);
1095 assert_eq!(gathered.value_at(2), Value::Integer(4));
1096 }
1097
1098 #[test]
1103 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1104 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1105 .unwrap()
1106 .with_validity(Validity::from_iter(3, |index| index != 2));
1107 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1108 let gathered = outer.gather(&[0, 1]).unwrap();
1109 assert_eq!(gathered.form(), Form::Flat);
1110 assert_eq!(gathered.value_at(0), Value::Integer(8));
1111 assert_eq!(gathered.value_at(1), Value::Null);
1112 }
1113
1114 #[test]
1119 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1120 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1121 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1122 let (codes, values) = outer.dictionary_parts().unwrap();
1123 assert_eq!(codes, [1, 0]);
1124 assert_eq!(values.form(), Form::Flat);
1125 assert_eq!(outer.value_at(0), Value::Integer(8));
1126 assert_eq!(outer.value_at(1), Value::Integer(7));
1127 }
1128
1129 #[test]
1132 fn stacking_dictionaries_does_not_make_them_deeper() {
1133 let mut vector = integers(&[10, 20, 30, 40]);
1134 for _ in 0..4 {
1135 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1136 }
1137 let (codes, values) = vector.dictionary_parts().unwrap();
1138 assert_eq!(values.form(), Form::Flat);
1139 assert_eq!(codes, [0, 1, 2, 3]);
1140 assert_eq!(
1141 vector.iter().collect::<Vec<_>>(),
1142 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1143 );
1144 }
1145
1146 #[test]
1149 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1150 let values =
1151 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1152 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1153 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1154 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1155 assert_eq!(outer.value_at(0), Value::Null);
1156 assert_eq!(outer.value_at(1), Value::Integer(3));
1157 }
1158
1159 #[test]
1163 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1164 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1165 .unwrap()
1166 .with_validity(Validity::from_iter(3, |index| index != 1));
1167 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1168 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1169 assert_eq!(outer.value_at(0), Value::Null);
1170 assert_eq!(outer.value_at(1), Value::Integer(3));
1171 assert_eq!(outer.value_at(2), Value::Integer(1));
1172 }
1173
1174 #[test]
1175 fn flattening_a_flat_vector_is_the_same_vector() {
1176 let vector = integers(&[1, 2, 3]);
1177 assert_eq!(vector.flatten().unwrap(), vector);
1178 }
1179
1180 #[test]
1181 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1182 let ty = LogicalType::decimal(9, 2).unwrap();
1183 let vector = Vector::flat(ty, Data::Int32(vec![1234])).unwrap();
1184 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1185 assert_eq!(vector.value_at(0).to_string(), "12.34");
1186 }
1187
1188 #[test]
1189 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1190 for (width, scale, unscaled) in
1193 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1194 {
1195 let ty = LogicalType::decimal(width, scale).unwrap();
1196 let value = Value::Decimal { unscaled, width, scale };
1197 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1198 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1199 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1200 }
1201 }
1202
1203 #[test]
1204 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1205 let ty = LogicalType::decimal(4, 1).unwrap();
1208 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1209 let error = Vector::from_values(ty, &[value]).unwrap_err();
1210 assert!(error.to_string().contains("does not fit"), "{error}");
1211 }
1212}