1use rudb_common::{Error, LogicalType, Result, Value};
19
20use crate::string::StringColumn;
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> {
257 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
258 return Err(Error::internal(format!(
259 "dictionary code {bad} is past the end of a {} value dictionary",
260 values.len()
261 )));
262 }
263 Ok(Self {
264 ty: values.ty.clone(),
265 len: codes.len(),
266 validity: Validity::AllValid,
267 body: Body::Dictionary { codes, values: Box::new(values) },
268 })
269 }
270
271 #[must_use]
273 pub fn with_validity(mut self, validity: Validity) -> Self {
274 self.validity = validity;
275 self
276 }
277
278 #[must_use]
280 pub fn logical_type(&self) -> &LogicalType {
281 &self.ty
282 }
283
284 #[must_use]
286 pub fn len(&self) -> usize {
287 self.len
288 }
289
290 #[must_use]
292 pub fn is_empty(&self) -> bool {
293 self.len == 0
294 }
295
296 #[must_use]
298 pub fn validity(&self) -> &Validity {
299 &self.validity
300 }
301
302 #[must_use]
304 pub fn form(&self) -> Form {
305 match self.body {
306 Body::Flat(_) => Form::Flat,
307 Body::Constant(_) => Form::Constant,
308 Body::Sequence { .. } => Form::Sequence,
309 Body::Dictionary { .. } => Form::Dictionary,
310 }
311 }
312
313 #[must_use]
318 pub fn data(&self) -> Option<&Data> {
319 match &self.body {
320 Body::Flat(data) => Some(data),
321 _ => None,
322 }
323 }
324
325 #[must_use]
332 pub fn constant_value(&self) -> Option<&Value> {
333 match &self.body {
334 Body::Constant(value) => Some(value.as_ref()),
335 _ => None,
336 }
337 }
338
339 #[must_use]
353 pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
354 match &self.body {
355 Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
356 _ => None,
357 }
358 }
359
360 #[must_use]
362 pub fn sequence_parts(&self) -> Option<(i64, i64)> {
363 match self.body {
364 Body::Sequence { start, step } => Some((start, step)),
365 _ => None,
366 }
367 }
368
369 #[must_use]
375 pub fn value_at(&self, index: usize) -> Value {
376 if index >= self.len || !self.validity.is_valid(index) {
377 return Value::Null;
378 }
379 match &self.body {
380 Body::Constant(value) => value.as_ref().clone(),
381 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
382 Body::Dictionary { codes, values } => match codes.get(index) {
383 Some(&code) => values.value_at(code as usize),
384 None => Value::Null,
385 },
386 Body::Flat(data) => value_from(&self.ty, data, index),
387 }
388 }
389
390 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
392 (0..self.len).map(|index| self.value_at(index))
393 }
394
395 pub fn flatten(&self) -> Result<Self> {
406 if let Body::Flat(_) = self.body {
407 return Ok(self.clone());
408 }
409 self.copied((0..self.len).collect(), false)
410 }
411
412 pub fn gather(&self, indices: &[u32]) -> Result<Self> {
428 self.copied(indices.iter().map(|&index| index as usize).collect(), true)
429 }
430
431 fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
438 let rows = at.len();
439 let (at, leaf) = self.resolve(at);
440 let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
441 let validity = Validity::from_run(&live);
442 let body = match &leaf.body {
443 Body::Constant(value) => {
446 if constants_stay && matches!(validity, Validity::AllValid) {
447 return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
448 }
449 let mut data = empty_data_for(&self.ty)?;
450 for &index in &at {
451 push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
452 }
453 Body::Flat(data)
454 }
455 Body::Sequence { start, step } => Body::Flat(Data::Int64(
458 at.iter()
459 .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
460 .collect(),
461 )),
462 Body::Flat(Data::Empty) => {
466 return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
467 }
468 Body::Flat(data) => Body::Flat(copy_of(data, &at)),
469 Body::Dictionary { .. } => {
471 return Err(Error::internal("a dictionary survived being resolved"));
472 }
473 };
474 Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
475 }
476
477 fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
483 let mut source = self;
484 loop {
485 for slot in &mut at {
486 if *slot >= source.len || !source.validity.is_valid(*slot) {
487 *slot = NOWHERE;
488 }
489 }
490 let Body::Dictionary { codes, values } = &source.body else {
491 return (at, source);
492 };
493 for slot in &mut at {
494 *slot = match codes.get(*slot) {
495 Some(&code) => code as usize,
496 None => NOWHERE,
497 };
498 }
499 source = values.as_ref();
500 }
501 }
502}
503
504const NOWHERE: usize = usize::MAX;
509
510fn copy_of(data: &Data, at: &[usize]) -> Data {
516 macro_rules! copied {
517 ($values:expr, $variant:path, $zero:expr) => {{
518 let values = $values;
519 let mut out = Vec::with_capacity(at.len());
520 for &index in at {
521 out.push(values.get(index).copied().unwrap_or($zero));
524 }
525 $variant(out)
526 }};
527 }
528 match data {
529 Data::Empty => Data::Empty,
530 Data::Bool(values) => copied!(values, Data::Bool, false),
531 Data::Int8(values) => copied!(values, Data::Int8, 0),
532 Data::Int16(values) => copied!(values, Data::Int16, 0),
533 Data::Int32(values) => copied!(values, Data::Int32, 0),
534 Data::Int64(values) => copied!(values, Data::Int64, 0),
535 Data::Int128(values) => copied!(values, Data::Int128, 0),
536 Data::UInt8(values) => copied!(values, Data::UInt8, 0),
537 Data::UInt16(values) => copied!(values, Data::UInt16, 0),
538 Data::UInt32(values) => copied!(values, Data::UInt32, 0),
539 Data::UInt64(values) => copied!(values, Data::UInt64, 0),
540 Data::UInt128(values) => copied!(values, Data::UInt128, 0),
541 Data::Float32(values) => copied!(values, Data::Float32, 0.0),
542 Data::Float64(values) => copied!(values, Data::Float64, 0.0),
543 Data::Interval(values) => copied!(values, Data::Interval, (0, 0, 0)),
544 Data::Varlen(values) => {
547 let mut out = StringColumn::with_capacity(at.len());
548 for &index in at {
549 out.push(values.get(index).unwrap_or(""));
550 }
551 Data::Varlen(out)
552 }
553 }
554}
555
556fn layout_of(data: &Data) -> rudb_common::PhysicalType {
558 use rudb_common::PhysicalType as P;
559 match data {
560 Data::Empty => P::Empty,
561 Data::Bool(_) => P::Bool,
562 Data::Int8(_) => P::Int8,
563 Data::Int16(_) => P::Int16,
564 Data::Int32(_) => P::Int32,
565 Data::Int64(_) => P::Int64,
566 Data::Int128(_) => P::Int128,
567 Data::UInt8(_) => P::UInt8,
568 Data::UInt16(_) => P::UInt16,
569 Data::UInt32(_) => P::UInt32,
570 Data::UInt64(_) => P::UInt64,
571 Data::UInt128(_) => P::UInt128,
572 Data::Float32(_) => P::Float32,
573 Data::Float64(_) => P::Float64,
574 Data::Interval(_) => P::Interval,
575 Data::Varlen(_) => P::Varlen,
576 }
577}
578
579fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
584 let signed = || data.signed_at(index);
585 let unsigned = || data.unsigned_at(index);
586 let value = match ty {
587 LogicalType::Boolean => match data {
588 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
589 _ => None,
590 },
591 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
592 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
593 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
594 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
595 LogicalType::HugeInt => signed().map(Value::HugeInt),
596 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
597 LogicalType::USmallInt => {
598 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
599 }
600 LogicalType::UInteger => {
601 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
602 }
603 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
604 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
605 LogicalType::Float => match data {
606 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
607 _ => None,
608 },
609 LogicalType::Double => match data {
610 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
611 _ => None,
612 },
613 LogicalType::Decimal { width, scale } => {
614 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
615 }
616 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
617 LogicalType::Blob | LogicalType::Bit => {
618 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
619 }
620 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
621 LogicalType::Time | LogicalType::TimeTz => {
622 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
623 }
624 LogicalType::Timestamp
625 | LogicalType::TimestampS
626 | LogicalType::TimestampMs
627 | LogicalType::TimestampNs
628 | LogicalType::TimestampTz => {
629 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
630 }
631 LogicalType::Interval => match data {
632 Data::Interval(v) => {
633 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
634 }
635 _ => None,
636 },
637 _ => None,
638 };
639 value.unwrap_or(Value::Null)
640}
641
642fn empty_data_for(ty: &LogicalType) -> Result<Data> {
644 use rudb_common::PhysicalType as P;
645 Ok(match ty.physical() {
646 P::Empty => Data::Empty,
647 P::Bool => Data::Bool(Vec::new()),
648 P::Int8 => Data::Int8(Vec::new()),
649 P::Int16 => Data::Int16(Vec::new()),
650 P::Int32 => Data::Int32(Vec::new()),
651 P::Int64 => Data::Int64(Vec::new()),
652 P::Int128 => Data::Int128(Vec::new()),
653 P::UInt8 => Data::UInt8(Vec::new()),
654 P::UInt16 => Data::UInt16(Vec::new()),
655 P::UInt32 => Data::UInt32(Vec::new()),
656 P::UInt64 => Data::UInt64(Vec::new()),
657 P::UInt128 => Data::UInt128(Vec::new()),
658 P::Float32 => Data::Float32(Vec::new()),
659 P::Float64 => Data::Float64(Vec::new()),
660 P::Interval => Data::Interval(Vec::new()),
661 P::Varlen => Data::Varlen(StringColumn::new()),
662 other => {
663 return Err(Error::not_implemented(format!(
664 "a flat vector of {other:?} data, which arrives with the storage layer"
665 )));
666 }
667 })
668}
669
670fn push_value(data: &mut Data, value: &Value) -> Result<()> {
675 macro_rules! push {
676 ($vec:expr, $variant:path, $zero:expr) => {
677 match value {
678 Value::Null => $vec.push($zero),
679 $variant(x) => $vec.push(*x),
680 other => {
681 return Err(Error::internal(format!(
682 "{other:?} does not belong in this vector"
683 )));
684 }
685 }
686 };
687 }
688 macro_rules! decimal {
694 ($vec:expr, $ty:ty, $unscaled:expr) => {
695 match <$ty>::try_from(*$unscaled) {
696 Ok(x) => $vec.push(x),
697 Err(_) => {
698 return Err(Error::internal(format!(
699 "an unscaled decimal of {} does not fit the run its precision chose",
700 $unscaled
701 )));
702 }
703 }
704 };
705 }
706 match data {
707 Data::Empty => {}
708 Data::Bool(v) => push!(v, Value::Boolean, false),
709 Data::Int8(v) => push!(v, Value::TinyInt, 0),
710 Data::Int16(v) => match value {
711 Value::Null => v.push(0),
712 Value::SmallInt(x) => v.push(*x),
713 Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
714 other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
715 },
716 Data::Int32(v) => match value {
717 Value::Null => v.push(0),
718 Value::Integer(x) | Value::Date(x) => v.push(*x),
719 Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
720 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
721 },
722 Data::Int64(v) => match value {
723 Value::Null => v.push(0),
724 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
725 Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
726 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
727 },
728 Data::Int128(v) => match value {
729 Value::Null => v.push(0),
730 Value::HugeInt(x) => v.push(*x),
731 Value::Decimal { unscaled, .. } => v.push(*unscaled),
732 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
733 },
734 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
735 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
736 Data::UInt32(v) => push!(v, Value::UInteger, 0),
737 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
738 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
739 Data::Float32(v) => push!(v, Value::Float, 0.0),
740 Data::Float64(v) => push!(v, Value::Double, 0.0),
741 Data::Interval(v) => match value {
742 Value::Null => v.push((0, 0, 0)),
743 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
744 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
745 },
746 Data::Varlen(column) => match value {
747 Value::Null => {
748 column.push("");
749 }
750 Value::Varchar(text) => {
751 column.push(text);
752 }
753 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
757 Ok(text) => {
758 column.push(text);
759 }
760 Err(_) => {
761 return Err(Error::not_implemented(
762 "a blob that is not valid UTF-8, which needs the byte column from M2",
763 ));
764 }
765 },
766 other => return Err(Error::internal(format!("{other:?} is not a string"))),
767 },
768 }
769 Ok(())
770}
771
772#[cfg(test)]
773mod tests {
774 use rudb_common::{LogicalType, Value};
775
776 use super::{Data, Form, VECTOR_SIZE, Vector};
777 use crate::string::StringColumn;
778 use crate::validity::Validity;
779
780 fn integers(values: &[i32]) -> Vector {
781 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec())).unwrap()
782 }
783
784 #[test]
785 fn the_vector_size_is_the_one_the_design_is_built_around() {
786 assert_eq!(VECTOR_SIZE, 1024);
789 assert_eq!(VECTOR_SIZE / 64, 16);
790 }
791
792 #[test]
793 fn a_flat_vector_reads_back_what_was_put_in_it() {
794 let vector = integers(&[1, 2, 3]);
795 assert_eq!(vector.form(), Form::Flat);
796 assert_eq!(vector.len(), 3);
797 assert_eq!(vector.value_at(1), Value::Integer(2));
798 assert_eq!(
799 vector.iter().collect::<Vec<_>>(),
800 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
801 );
802 }
803
804 #[test]
805 fn a_vector_built_from_values_reads_the_same_values_back() {
806 let vector = Vector::from_values(
807 LogicalType::Varchar,
808 &[
809 Value::Varchar("a".to_string()),
810 Value::Null,
811 Value::Varchar("a string too long to sit inside a view".to_string()),
812 ],
813 )
814 .expect("strings and a null");
815 assert_eq!(vector.len(), 3);
816 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
817 assert_eq!(vector.value_at(1), Value::Null);
818 assert_eq!(
819 vector.value_at(2),
820 Value::Varchar("a string too long to sit inside a view".to_string())
821 );
822 }
823
824 #[test]
827 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
828 let vector = Vector::from_values(
829 LogicalType::Integer,
830 &[Value::Integer(1), Value::Null, Value::Integer(3)],
831 )
832 .expect("integers and a null");
833 assert_eq!(vector.value_at(2), Value::Integer(3));
834 assert!(vector.validity().has_nulls(3), "the middle one is null");
835 }
836
837 #[test]
838 fn a_value_the_type_cannot_hold_is_refused() {
839 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
840 assert!(wrong.is_err(), "a string is not an integer");
841 }
842
843 #[test]
844 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
845 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1]));
847 assert!(wrong.is_err());
848 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1]));
849 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
850 }
851
852 #[test]
853 fn a_constant_vector_costs_one_value_whatever_its_length() {
854 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
855 assert_eq!(vector.form(), Form::Constant);
856 assert_eq!(vector.len(), VECTOR_SIZE);
857 assert_eq!(vector.value_at(0), Value::Integer(7));
858 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
859 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
860 }
861
862 #[test]
863 fn a_constant_null_is_all_invalid_without_being_told() {
864 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
865 assert_eq!(vector.validity(), &Validity::AllInvalid);
866 assert_eq!(vector.value_at(3), Value::Null);
867 }
868
869 #[test]
870 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
871 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
872 assert_eq!(vector.form(), Form::Sequence);
873 assert_eq!(vector.value_at(0), Value::BigInt(100));
874 assert_eq!(vector.value_at(923), Value::BigInt(1023));
875 let stepped = Vector::sequence(0, 5, 4);
876 assert_eq!(
877 stepped.iter().collect::<Vec<_>>(),
878 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
879 );
880 }
881
882 #[test]
883 fn a_dictionary_vector_reads_through_its_codes() {
884 let mut column = StringColumn::new();
885 column.push("red");
886 column.push("green");
887 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
888 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
889 assert_eq!(vector.form(), Form::Dictionary);
890 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
891 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
892 assert_eq!(vector.len(), 4);
893 }
894
895 #[test]
896 fn a_dictionary_code_past_the_end_is_refused() {
897 let values = integers(&[1, 2]);
900 assert!(Vector::dictionary(vec![0, 2], values).is_err());
901 }
902
903 #[test]
904 fn every_form_flattens_to_the_same_values_it_reads_out() {
905 let mut column = StringColumn::new();
909 column.push("alpha");
910 column.push("beta");
911 let dictionary = Vector::dictionary(
912 vec![1, 0, 1],
913 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
914 )
915 .unwrap();
916 let cases = [
917 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
918 Vector::sequence(7, -2, 5),
919 dictionary,
920 ];
921 for vector in cases {
922 let flat = vector.flatten().unwrap();
923 assert_eq!(flat.form(), Form::Flat);
924 assert_eq!(flat.len(), vector.len());
925 for index in 0..vector.len() {
926 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
927 }
928 }
929 }
930
931 #[test]
932 fn a_null_still_occupies_a_position_after_flattening() {
933 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
937 let flat = vector.flatten().unwrap();
938 assert_eq!(flat.value_at(0), Value::BigInt(0));
939 assert_eq!(flat.value_at(1), Value::Null);
940 assert_eq!(flat.value_at(2), Value::BigInt(2));
941 assert_eq!(flat.value_at(3), Value::BigInt(3));
942 }
943
944 #[test]
949 fn a_null_behind_a_dictionary_survives_flattening() {
950 let values =
951 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
952 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
953 let flat = dictionary.flatten().unwrap();
954 assert_eq!(flat.value_at(0), Value::Null);
955 assert_eq!(flat.value_at(1), Value::Integer(3));
956 assert_eq!(flat.value_at(2), Value::Null);
957 }
958
959 #[test]
962 fn gathering_reads_what_reading_one_position_at_a_time_reads() {
963 let mut column = StringColumn::new();
964 column.push("alpha");
965 column.push("beta");
966 column.push("gamma");
967 let cases = [
968 integers(&[10, 20, 30, 40]),
969 integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
970 Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
971 Vector::sequence(100, -7, 4),
972 Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
973 Vector::dictionary(
974 vec![2, 0, 1, 2],
975 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
976 )
977 .unwrap(),
978 Vector::dictionary(
979 vec![1, 0, 1, 0],
980 Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
981 .unwrap(),
982 )
983 .unwrap(),
984 ];
985 let wanted = [3_u32, 0, 2, 2, 1];
986 for vector in cases {
987 let gathered = vector.gather(&wanted).unwrap();
988 assert_eq!(gathered.len(), wanted.len());
989 assert_eq!(gathered.logical_type(), vector.logical_type());
990 for (slot, &index) in wanted.iter().enumerate() {
991 assert_eq!(
992 gathered.value_at(slot),
993 vector.value_at(index as usize),
994 "slot {slot} of {:?}",
995 vector.form()
996 );
997 }
998 }
999 }
1000
1001 #[test]
1005 fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
1006 let vector = integers(&[1, 2, 3]);
1007 let gathered = vector.gather(&[2, 9]).unwrap();
1008 assert_eq!(gathered.value_at(0), Value::Integer(3));
1009 assert_eq!(gathered.value_at(1), Value::Null);
1010 }
1011
1012 #[test]
1016 fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
1017 let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
1018 let gathered = vector.gather(&[0, 1, 2]).unwrap();
1019 assert_eq!(gathered.len(), 3);
1020 assert_eq!(gathered.value_at(0), Value::Null);
1021 assert_eq!(gathered.value_at(2), Value::Null);
1022 }
1023
1024 #[test]
1027 fn gathering_a_constant_stays_a_constant() {
1028 let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
1029 let gathered = vector.gather(&[7, 7, 99]).unwrap();
1030 assert_eq!(gathered.form(), Form::Constant);
1031 assert_eq!(gathered.len(), 3);
1032 assert_eq!(gathered.value_at(2), Value::Integer(4));
1033 }
1034
1035 #[test]
1038 fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
1039 let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
1040 let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
1041 let gathered = outer.gather(&[1, 0]).unwrap();
1042 assert_eq!(gathered.form(), Form::Flat);
1043 assert_eq!(gathered.value_at(0), Value::Integer(7));
1044 assert_eq!(gathered.value_at(1), Value::Integer(8));
1045 }
1046
1047 #[test]
1048 fn flattening_a_flat_vector_is_the_same_vector() {
1049 let vector = integers(&[1, 2, 3]);
1050 assert_eq!(vector.flatten().unwrap(), vector);
1051 }
1052
1053 #[test]
1054 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
1055 let ty = LogicalType::decimal(9, 2).unwrap();
1056 let vector = Vector::flat(ty, Data::Int32(vec![1234])).unwrap();
1057 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
1058 assert_eq!(vector.value_at(0).to_string(), "12.34");
1059 }
1060
1061 #[test]
1062 fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
1063 for (width, scale, unscaled) in
1066 [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
1067 {
1068 let ty = LogicalType::decimal(width, scale).unwrap();
1069 let value = Value::Decimal { unscaled, width, scale };
1070 let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
1071 assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
1072 assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
1073 }
1074 }
1075
1076 #[test]
1077 fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
1078 let ty = LogicalType::decimal(4, 1).unwrap();
1081 let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
1082 let error = Vector::from_values(ty, &[value]).unwrap_err();
1083 assert!(error.to_string().contains("does not fit"), "{error}");
1084 }
1085}