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 flatten(&self) -> Result<Self> {
426 if let Body::Flat(_) = self.body {
427 return Ok(self.clone());
428 }
429 self.copied((0..self.len).collect(), false)
430 }
431
432 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
448 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
449 }
450
451 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
458 let rows = at.len();
459 let (at, leaf) = self.resolve(at);
460 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
461 let validity = Validity::from_run(&live);
462 let body = match &leaf.body {
463 Body::Constant(value) => {
466 if constants_stay && matches!(validity, Validity::AllValid) {
467 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
468 }
469 let mut data = empty_data_for(&self.ty)?;
470 for &index in &at {
471 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
472 }
473 Body::Flat(data)
474 }
475 Body::Sequence { start, step } => Body::Flat(Data::Int64(
478 at.iter()
479 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
480 .collect(),
481 )),
482 Body::Flat(Data::Empty) => {
486 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
487 }
488 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
489 Body::Dictionary { .. } => {
491 return Err(Error::internal("a dictionary survived being resolved"));
492 }
493 };
494 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
495 }
496
497 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
503 let mut source = self;
504 loop {
505 for slot in &mut at {
506 if *slot >= source.len || !source.validity.is_valid(*slot) {
507 *slot = NOWHERE;
508 }
509 }
510 let Body::Dictionary { codes, values } = &source.body else {
511 return (at, source);
512 };
513 for slot in &mut at {
514 *slot = match codes.get(*slot) {
515 Some(&code) => code as usize,
516 None => NOWHERE,
517 };
518 }
519 source = values.as_ref();
520 }
521 }
522}
523
524fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
536 if !matches!(values.validity, Validity::AllValid) {
539 return (codes, values);
540 }
541 let Vector { ty, len, validity, body } = values;
542 match body {
543 Body::Dictionary { codes: inner, values: leaf } => {
544 debug_assert!(
545 !matches!(leaf.body, Body::Dictionary { .. })
546 || !matches!(leaf.validity, Validity::AllValid),
547 "a dictionary was stacked on a dictionary without going through the constructor"
548 );
549 (codes.iter().map(|&code| inner[code as usize]).collect(), *leaf)
550 }
551 body => (codes, Vector { ty, len, validity, body }),
552 }
553}
554
555const NOWHERE: usize = usize::MAX;
560
561fn copy_of(data: &Data, at: &[usize]) -> Data {
567 macro_rules! copied {
568 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
569 match data {
570 Data::Empty => Data::Empty,
571 $(Data::$variant(values) => {
572 let mut out = Buffer::with_capacity(at.len());
573 for &index in at {
574 out.push(values.get(index).copied().unwrap_or($zero));
577 }
578 Data::$variant(out)
579 })+
580 Data::Varlen(values) => {
584 let mut out = StringColumn::with_capacity(at.len());
585 let views = values.views();
590 out.reserve_bytes(
591 at.iter()
592 .filter_map(|&index| views.get(index))
593 .filter(|view| !view.is_inline())
594 .map(StringView::len)
595 .sum(),
596 );
597 for &index in at {
598 out.push(values.get(index).unwrap_or(""));
599 }
600 Data::Varlen(out)
601 }
602 }
603 };
604 }
605 crate::for_each_layout!(fixed, copied)
606}
607
608fn layout_of(data: &Data) -> rudb_common::PhysicalType {
613 use rudb_common::PhysicalType as P;
614 macro_rules! layouts {
615 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
616 match data {
617 Data::Empty => P::Empty,
618 $(Data::$variant(_) => P::$variant,)+
619 }
620 };
621 }
622 crate::for_each_layout!(all, layouts)
623}
624
625fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
630 let signed = || data.signed_at(index);
631 let unsigned = || data.unsigned_at(index);
632 let value = match ty {
633 LogicalType::Boolean => match data {
634 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
635 _ => None,
636 },
637 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
638 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
639 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
640 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
641 LogicalType::HugeInt => signed().map(Value::HugeInt),
642 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
643 LogicalType::USmallInt => {
644 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
645 }
646 LogicalType::UInteger => {
647 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
648 }
649 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
650 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
651 LogicalType::Float => match data {
652 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
653 _ => None,
654 },
655 LogicalType::Double => match data {
656 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
657 _ => None,
658 },
659 LogicalType::Decimal { width, scale } => {
660 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
661 }
662 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
663 LogicalType::Blob | LogicalType::Bit => {
664 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
665 }
666 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
667 LogicalType::Time | LogicalType::TimeTz => {
668 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
669 }
670 LogicalType::Timestamp
671 | LogicalType::TimestampS
672 | LogicalType::TimestampMs
673 | LogicalType::TimestampNs
674 | LogicalType::TimestampTz => {
675 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
676 }
677 LogicalType::Interval => match data {
678 Data::Interval(v) => {
679 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
680 }
681 _ => None,
682 },
683 _ => None,
684 };
685 value.unwrap_or(Value::Null)
686}
687
688fn empty_data_for(ty: &LogicalType) -> Result<Data> {
690 use rudb_common::PhysicalType as P;
691 macro_rules! empties {
692 ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
693 match ty.physical() {
694 P::Empty => Data::Empty,
695 $(P::$variant => Data::$variant(Buffer::new()),)+
696 P::Varlen => Data::Varlen(StringColumn::new()),
697 other => {
698 return Err(Error::not_implemented(format!(
699 "a flat vector of {other:?} data, which arrives with the storage layer"
700 )));
701 }
702 }
703 };
704 }
705 Ok(crate::for_each_layout!(fixed, empties))
706}
707
708fn push_value(data: &mut Data, value: &Value) -> Result<()> {
713 macro_rules! push {
714 ($vec:expr, $variant:path, $zero:expr) => {
715 match value {
716 Value::Null => $vec.push($zero),
717 $variant(x) => $vec.push(*x),
718 other => {
719 return Err(Error::internal(format!(
720 "{other:?} does not belong in this vector"
721 )));
722 }
723 }
724 };
725 }
726 macro_rules! decimal {
732 ($vec:expr, $ty:ty, $unscaled:expr) => {
733 match <$ty>::try_from(*$unscaled) {
734 Ok(x) => $vec.push(x),
735 Err(_) => {
736 return Err(Error::internal(format!(
737 "an unscaled decimal of {} does not fit the run its precision chose",
738 $unscaled
739 )));
740 }
741 }
742 };
743 }
744 match data {
745 Data::Empty => {}
746 Data::Bool(v) => push!(v, Value::Boolean, false),
747 Data::Int8(v) => push!(v, Value::TinyInt, 0),
748 Data::Int16(v) => match value {
749 Value::Null => v.push(0),
750 Value::SmallInt(x) => v.push(*x),
751 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
752 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
753 },
754 Data::Int32(v) => match value {
755 Value::Null => v.push(0),
756 Value::Integer(x) | Value::Date(x) => v.push(*x),
757 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
758 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
759 },
760 Data::Int64(v) => match value {
761 Value::Null => v.push(0),
762 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
763 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
764 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
765 },
766 Data::Int128(v) => match value {
767 Value::Null => v.push(0),
768 Value::HugeInt(x) => v.push(*x),
769 Value::Decimal { unscaled, .. } => v.push(*unscaled),
770 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
771 },
772 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
773 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
774 Data::UInt32(v) => push!(v, Value::UInteger, 0),
775 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
776 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
777 Data::Float32(v) => push!(v, Value::Float, 0.0),
778 Data::Float64(v) => push!(v, Value::Double, 0.0),
779 Data::Interval(v) => match value {
780 Value::Null => v.push((0, 0, 0)),
781 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
782 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
783 },
784 Data::Varlen(column) => match value {
785 Value::Null => {
786 column.push("");
787 }
788 Value::Varchar(text) => {
789 column.push(text);
790 }
791 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
795 Ok(text) => {
796 column.push(text);
797 }
798 Err(_) => {
799 return Err(Error::not_implemented(
800 "a blob that is not valid UTF-8, which needs the byte column from M2",
801 ));
802 }
803 },
804 other => return Err(Error::internal(format!("{other:?} is not a string"))),
805 },
806 }
807 Ok(())
808}
809
810#[cfg(test)]
811mod tests {
812 use rudb_common::{LogicalType, Value};
813
814 use super::{Data, Form, VECTOR_SIZE, Vector};
815 use crate::string::StringColumn;
816 use crate::validity::Validity;
817
818 fn integers(values: &[i32]) -> Vector {
819 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
820 }
821
822 #[test]
823 fn the_vector_size_is_the_one_the_design_is_built_around() {
824 assert_eq!(VECTOR_SIZE, 1024);
827 assert_eq!(VECTOR_SIZE / 64, 16);
828 }
829
830 #[test]
831 fn a_flat_vector_reads_back_what_was_put_in_it() {
832 let vector = integers(&[1, 2, 3]);
833 assert_eq!(vector.form(), Form::Flat);
834 assert_eq!(vector.len(), 3);
835 assert_eq!(vector.value_at(1), Value::Integer(2));
836 assert_eq!(
837 vector.iter().collect::<Vec<_>>(),
838 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
839 );
840 }
841
842 #[test]
843 fn a_vector_built_from_values_reads_the_same_values_back() {
844 let vector = Vector::from_values(
845 LogicalType::Varchar,
846 &[
847 Value::Varchar("a".to_string()),
848 Value::Null,
849 Value::Varchar("a string too long to sit inside a view".to_string()),
850 ],
851 )
852 .expect("strings and a null");
853 assert_eq!(vector.len(), 3);
854 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
855 assert_eq!(vector.value_at(1), Value::Null);
856 assert_eq!(
857 vector.value_at(2),
858 Value::Varchar("a string too long to sit inside a view".to_string())
859 );
860 }
861
862 #[test]
865 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
866 let vector = Vector::from_values(
867 LogicalType::Integer,
868 &[Value::Integer(1), Value::Null, Value::Integer(3)],
869 )
870 .expect("integers and a null");
871 assert_eq!(vector.value_at(2), Value::Integer(3));
872 assert!(vector.validity().has_nulls(3), "the middle one is null");
873 }
874
875 #[test]
876 fn a_value_the_type_cannot_hold_is_refused() {
877 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
878 assert!(wrong.is_err(), "a string is not an integer");
879 }
880
881 #[test]
882 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
883 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
885 assert!(wrong.is_err());
886 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
887 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
888 }
889
890 #[test]
891 fn a_constant_vector_costs_one_value_whatever_its_length() {
892 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
893 assert_eq!(vector.form(), Form::Constant);
894 assert_eq!(vector.len(), VECTOR_SIZE);
895 assert_eq!(vector.value_at(0), Value::Integer(7));
896 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
897 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
898 }
899
900 #[test]
901 fn a_constant_null_is_all_invalid_without_being_told() {
902 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
903 assert_eq!(vector.validity(), &Validity::AllInvalid);
904 assert_eq!(vector.value_at(3), Value::Null);
905 }
906
907 #[test]
908 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
909 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
910 assert_eq!(vector.form(), Form::Sequence);
911 assert_eq!(vector.value_at(0), Value::BigInt(100));
912 assert_eq!(vector.value_at(923), Value::BigInt(1023));
913 let stepped = Vector::sequence(0, 5, 4);
914 assert_eq!(
915 stepped.iter().collect::<Vec<_>>(),
916 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
917 );
918 }
919
920 #[test]
921 fn a_dictionary_vector_reads_through_its_codes() {
922 let mut column = StringColumn::new();
923 column.push("red");
924 column.push("green");
925 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
926 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
927 assert_eq!(vector.form(), Form::Dictionary);
928 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
929 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
930 assert_eq!(vector.len(), 4);
931 }
932
933 #[test]
934 fn a_dictionary_code_past_the_end_is_refused() {
935 let values = integers(&[1, 2]);
938 assert!(Vector::dictionary(vec![0, 2], values).is_err());
939 }
940
941 #[test]
942 fn every_form_flattens_to_the_same_values_it_reads_out() {
943 let mut column = StringColumn::new();
947 column.push("alpha");
948 column.push("beta");
949 let dictionary = Vector::dictionary(
950 vec![1, 0, 1],
951 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
952 )
953 .unwrap();
954 let cases = [
955 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
956 Vector::sequence(7, -2, 5),
957 dictionary,
958 ];
959 for vector in cases {
960 let flat = vector.flatten().unwrap();
961 assert_eq!(flat.form(), Form::Flat);
962 assert_eq!(flat.len(), vector.len());
963 for index in 0..vector.len() {
964 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
965 }
966 }
967 }
968
969 #[test]
970 fn a_null_still_occupies_a_position_after_flattening() {
971 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
975 let flat = vector.flatten().unwrap();
976 assert_eq!(flat.value_at(0), Value::BigInt(0));
977 assert_eq!(flat.value_at(1), Value::Null);
978 assert_eq!(flat.value_at(2), Value::BigInt(2));
979 assert_eq!(flat.value_at(3), Value::BigInt(3));
980 }
981
982 #[test]
987 fn a_null_behind_a_dictionary_survives_flattening() {
988 let values =
989 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
990 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
991 let flat = dictionary.flatten().unwrap();
992 assert_eq!(flat.value_at(0), Value::Null);
993 assert_eq!(flat.value_at(1), Value::Integer(3));
994 assert_eq!(flat.value_at(2), Value::Null);
995 }
996
997 #[test]
1000 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
1001 let mut column = StringColumn::new();
1002 column.push("alpha");
1003 column.push("beta");
1004 column.push("gamma");
1005 let cases = [
1006 integers(&[10, 20, 30, 40]),
1007 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
1008 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
1009 Vector::sequence(100, -7, 4),
1010 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
1011 Vector::dictionary(
1012 vec![2, 0, 1, 2],
1013 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
1014 )
1015 .unwrap(),
1016 Vector::dictionary(
1017 vec![1, 0, 1, 0],
1018 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
1019 .unwrap(),
1020 )
1021 .unwrap(),
1022 ];
1023 let wanted = [3_u32, 0, 2, 2, 1];
1024 for vector in cases {
1025 let gathered = vector.gather(&wanted).unwrap();
1026 assert_eq!(gathered.len(), wanted.len());
1027 assert_eq!(gathered.logical_type(), vector.logical_type());
1028 for (slot, &index) in wanted.iter().enumerate() {
1029 assert_eq!(
1030 gathered.value_at(slot),
1031 vector.value_at(index as usize),
1032 "slot {slot} of {:?}",
1033 vector.form()
1034 );
1035 }
1036 }
1037 }
1038
1039 #[test]
1043 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1044 let vector = integers(&[1, 2, 3]);
1045 let gathered = vector.gather(&[2, 9]).unwrap();
1046 assert_eq!(gathered.value_at(0), Value::Integer(3));
1047 assert_eq!(gathered.value_at(1), Value::Null);
1048 }
1049
1050 #[test]
1054 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1055 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1056 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1057 assert_eq!(gathered.len(), 3);
1058 assert_eq!(gathered.value_at(0), Value::Null);
1059 assert_eq!(gathered.value_at(2), Value::Null);
1060 }
1061
1062 #[test]
1065 fn gathering_a_constant_stays_a_constant() {
1066 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1067 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1068 assert_eq!(gathered.form(), Form::Constant);
1069 assert_eq!(gathered.len(), 3);
1070 assert_eq!(gathered.value_at(2), Value::Integer(4));
1071 }
1072
1073 #[test]
1078 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1079 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
1080 .unwrap()
1081 .with_validity(Validity::from_iter(3, |index| index != 2));
1082 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1083 let gathered = outer.gather(&[0, 1]).unwrap();
1084 assert_eq!(gathered.form(), Form::Flat);
1085 assert_eq!(gathered.value_at(0), Value::Integer(8));
1086 assert_eq!(gathered.value_at(1), Value::Null);
1087 }
1088
1089 #[test]
1094 fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
1095 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1096 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1097 let (codes, values) = outer.dictionary_parts().unwrap();
1098 assert_eq!(codes, [1, 0]);
1099 assert_eq!(values.form(), Form::Flat);
1100 assert_eq!(outer.value_at(0), Value::Integer(8));
1101 assert_eq!(outer.value_at(1), Value::Integer(7));
1102 }
1103
1104 #[test]
1107 fn stacking_dictionaries_does_not_make_them_deeper() {
1108 let mut vector = integers(&[10, 20, 30, 40]);
1109 for _ in 0..4 {
1110 vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
1111 }
1112 let (codes, values) = vector.dictionary_parts().unwrap();
1113 assert_eq!(values.form(), Form::Flat);
1114 assert_eq!(codes, [0, 1, 2, 3]);
1115 assert_eq!(
1116 vector.iter().collect::<Vec<_>>(),
1117 integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
1118 );
1119 }
1120
1121 #[test]
1124 fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
1125 let values =
1126 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
1127 let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
1128 let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
1129 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
1130 assert_eq!(outer.value_at(0), Value::Null);
1131 assert_eq!(outer.value_at(1), Value::Integer(3));
1132 }
1133
1134 #[test]
1138 fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
1139 let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
1140 .unwrap()
1141 .with_validity(Validity::from_iter(3, |index| index != 1));
1142 let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
1143 assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
1144 assert_eq!(outer.value_at(0), Value::Null);
1145 assert_eq!(outer.value_at(1), Value::Integer(3));
1146 assert_eq!(outer.value_at(2), Value::Integer(1));
1147 }
1148
1149 #[test]
1150 fn flattening_a_flat_vector_is_the_same_vector() {
1151 let vector = integers(&[1, 2, 3]);
1152 assert_eq!(vector.flatten().unwrap(), vector);
1153 }
1154
1155 #[test]
1156 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1157 let ty = LogicalType::decimal(9, 2).unwrap();
1158 let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
1159 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1160 assert_eq!(vector.value_at(0).to_string(), "12.34");
1161 }
1162
1163 #[test]
1164 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1165 for (width, scale, unscaled) in
1168 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1169 {
1170 let ty = LogicalType::decimal(width, scale).unwrap();
1171 let value = Value::Decimal { unscaled, width, scale };
1172 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1173 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1174 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1175 }
1176 }
1177
1178 #[test]
1179 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1180 let ty = LogicalType::decimal(4, 1).unwrap();
1183 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1184 let error = Vector::from_values(ty, &[value]).unwrap_err();
1185 assert!(error.to_string().contains("does not fit"), "{error}");
1186 }
1187}