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)]
36pub enum Form {
37 Flat,
39 Constant,
41 Sequence,
43 Dictionary,
45}
46
47#[derive(Debug, Clone, PartialEq)]
52#[non_exhaustive]
53pub enum Data {
54 Empty,
56 Bool(Vec<bool>),
58 Int8(Vec<i8>),
60 Int16(Vec<i16>),
62 Int32(Vec<i32>),
64 Int64(Vec<i64>),
66 Int128(Vec<i128>),
68 UInt8(Vec<u8>),
70 UInt16(Vec<u16>),
72 UInt32(Vec<u32>),
74 UInt64(Vec<u64>),
76 UInt128(Vec<u128>),
78 Float32(Vec<f32>),
80 Float64(Vec<f64>),
82 Interval(Vec<(i32, i32, i64)>),
84 Varlen(StringColumn),
86}
87
88impl Data {
89 #[must_use]
91 pub fn len(&self) -> usize {
92 match self {
93 Self::Empty => 0,
94 Self::Bool(v) => v.len(),
95 Self::Int8(v) => v.len(),
96 Self::Int16(v) => v.len(),
97 Self::Int32(v) => v.len(),
98 Self::Int64(v) => v.len(),
99 Self::Int128(v) => v.len(),
100 Self::UInt8(v) => v.len(),
101 Self::UInt16(v) => v.len(),
102 Self::UInt32(v) => v.len(),
103 Self::UInt64(v) => v.len(),
104 Self::UInt128(v) => v.len(),
105 Self::Float32(v) => v.len(),
106 Self::Float64(v) => v.len(),
107 Self::Interval(v) => v.len(),
108 Self::Varlen(v) => v.len(),
109 }
110 }
111
112 #[must_use]
114 pub fn is_empty(&self) -> bool {
115 self.len() == 0
116 }
117
118 #[must_use]
123 pub fn signed_at(&self, index: usize) -> Option<i128> {
124 match self {
125 Self::Int8(v) => v.get(index).map(|&x| i128::from(x)),
126 Self::Int16(v) => v.get(index).map(|&x| i128::from(x)),
127 Self::Int32(v) => v.get(index).map(|&x| i128::from(x)),
128 Self::Int64(v) => v.get(index).map(|&x| i128::from(x)),
129 Self::Int128(v) => v.get(index).copied(),
130 _ => None,
131 }
132 }
133
134 #[must_use]
136 pub fn unsigned_at(&self, index: usize) -> Option<u128> {
137 match self {
138 Self::UInt8(v) => v.get(index).map(|&x| u128::from(x)),
139 Self::UInt16(v) => v.get(index).map(|&x| u128::from(x)),
140 Self::UInt32(v) => v.get(index).map(|&x| u128::from(x)),
141 Self::UInt64(v) => v.get(index).map(|&x| u128::from(x)),
142 Self::UInt128(v) => v.get(index).copied(),
143 _ => None,
144 }
145 }
146
147 #[must_use]
149 pub fn str_at(&self, index: usize) -> Option<&str> {
150 match self {
151 Self::Varlen(column) => column.get(index),
152 _ => None,
153 }
154 }
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub struct Vector {
160 ty: LogicalType,
161 len: usize,
162 validity: Validity,
163 body: Body,
164}
165
166#[derive(Debug, Clone, PartialEq)]
168enum Body {
169 Flat(Data),
170 Constant(Box<Value>),
171 Sequence { start: i64, step: i64 },
172 Dictionary { codes: Vec<u32>, values: Box<Vector> },
173}
174
175impl Vector {
176 pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
184 let len = data.len();
185 if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
186 return Err(Error::internal(format!(
187 "a {ty} vector cannot hold {:?} data",
188 layout_of(&data)
189 )));
190 }
191 Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
192 }
193
194 pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
206 let mut data = empty_data_for(&ty)?;
207 for value in values {
208 push_value(&mut data, value)?;
209 }
210 let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
211 Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
212 }
213
214 #[must_use]
219 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
220 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
221 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
222 }
223
224 #[must_use]
229 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
230 Self {
231 ty: LogicalType::BigInt,
232 len,
233 validity: Validity::AllValid,
234 body: Body::Sequence { start, step },
235 }
236 }
237
238 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
248 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
249 return Err(Error::internal(format!(
250 "dictionary code {bad} is past the end of a {} value dictionary",
251 values.len()
252 )));
253 }
254 Ok(Self {
255 ty: values.ty.clone(),
256 len: codes.len(),
257 validity: Validity::AllValid,
258 body: Body::Dictionary { codes, values: Box::new(values) },
259 })
260 }
261
262 #[must_use]
264 pub fn with_validity(mut self, validity: Validity) -> Self {
265 self.validity = validity;
266 self
267 }
268
269 #[must_use]
271 pub fn logical_type(&self) -> &LogicalType {
272 &self.ty
273 }
274
275 #[must_use]
277 pub fn len(&self) -> usize {
278 self.len
279 }
280
281 #[must_use]
283 pub fn is_empty(&self) -> bool {
284 self.len == 0
285 }
286
287 #[must_use]
289 pub fn validity(&self) -> &Validity {
290 &self.validity
291 }
292
293 #[must_use]
295 pub fn form(&self) -> Form {
296 match self.body {
297 Body::Flat(_) => Form::Flat,
298 Body::Constant(_) => Form::Constant,
299 Body::Sequence { .. } => Form::Sequence,
300 Body::Dictionary { .. } => Form::Dictionary,
301 }
302 }
303
304 #[must_use]
309 pub fn data(&self) -> Option<&Data> {
310 match &self.body {
311 Body::Flat(data) => Some(data),
312 _ => None,
313 }
314 }
315
316 #[must_use]
322 pub fn value_at(&self, index: usize) -> Value {
323 if index >= self.len || !self.validity.is_valid(index) {
324 return Value::Null;
325 }
326 match &self.body {
327 Body::Constant(value) => value.as_ref().clone(),
328 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
329 Body::Dictionary { codes, values } => match codes.get(index) {
330 Some(&code) => values.value_at(code as usize),
331 None => Value::Null,
332 },
333 Body::Flat(data) => value_from(&self.ty, data, index),
334 }
335 }
336
337 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
339 (0..self.len).map(|index| self.value_at(index))
340 }
341
342 pub fn flatten(&self) -> Result<Self> {
353 if let Body::Flat(_) = self.body {
354 return Ok(self.clone());
355 }
356 let values: Vec<Value> = self.iter().collect();
357 let mut data = empty_data_for(&self.ty)?;
358 for value in &values {
359 push_value(&mut data, value)?;
360 }
361 let validity = Validity::from_iter(self.len, |index| !values[index].is_null());
365 Ok(Self { ty: self.ty.clone(), len: self.len, validity, body: Body::Flat(data) })
366 }
367}
368
369fn layout_of(data: &Data) -> rudb_common::PhysicalType {
371 use rudb_common::PhysicalType as P;
372 match data {
373 Data::Empty => P::Empty,
374 Data::Bool(_) => P::Bool,
375 Data::Int8(_) => P::Int8,
376 Data::Int16(_) => P::Int16,
377 Data::Int32(_) => P::Int32,
378 Data::Int64(_) => P::Int64,
379 Data::Int128(_) => P::Int128,
380 Data::UInt8(_) => P::UInt8,
381 Data::UInt16(_) => P::UInt16,
382 Data::UInt32(_) => P::UInt32,
383 Data::UInt64(_) => P::UInt64,
384 Data::UInt128(_) => P::UInt128,
385 Data::Float32(_) => P::Float32,
386 Data::Float64(_) => P::Float64,
387 Data::Interval(_) => P::Interval,
388 Data::Varlen(_) => P::Varlen,
389 }
390}
391
392fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
397 let signed = || data.signed_at(index);
398 let unsigned = || data.unsigned_at(index);
399 let value = match ty {
400 LogicalType::Boolean => match data {
401 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
402 _ => None,
403 },
404 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
405 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
406 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
407 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
408 LogicalType::HugeInt => signed().map(Value::HugeInt),
409 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
410 LogicalType::USmallInt => {
411 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
412 }
413 LogicalType::UInteger => {
414 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
415 }
416 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
417 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
418 LogicalType::Float => match data {
419 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
420 _ => None,
421 },
422 LogicalType::Double => match data {
423 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
424 _ => None,
425 },
426 LogicalType::Decimal { width, scale } => {
427 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
428 }
429 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
430 LogicalType::Blob | LogicalType::Bit => {
431 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
432 }
433 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
434 LogicalType::Time | LogicalType::TimeTz => {
435 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
436 }
437 LogicalType::Timestamp
438 | LogicalType::TimestampS
439 | LogicalType::TimestampMs
440 | LogicalType::TimestampNs
441 | LogicalType::TimestampTz => {
442 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
443 }
444 LogicalType::Interval => match data {
445 Data::Interval(v) => {
446 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
447 }
448 _ => None,
449 },
450 _ => None,
451 };
452 value.unwrap_or(Value::Null)
453}
454
455fn empty_data_for(ty: &LogicalType) -> Result<Data> {
457 use rudb_common::PhysicalType as P;
458 Ok(match ty.physical() {
459 P::Empty => Data::Empty,
460 P::Bool => Data::Bool(Vec::new()),
461 P::Int8 => Data::Int8(Vec::new()),
462 P::Int16 => Data::Int16(Vec::new()),
463 P::Int32 => Data::Int32(Vec::new()),
464 P::Int64 => Data::Int64(Vec::new()),
465 P::Int128 => Data::Int128(Vec::new()),
466 P::UInt8 => Data::UInt8(Vec::new()),
467 P::UInt16 => Data::UInt16(Vec::new()),
468 P::UInt32 => Data::UInt32(Vec::new()),
469 P::UInt64 => Data::UInt64(Vec::new()),
470 P::UInt128 => Data::UInt128(Vec::new()),
471 P::Float32 => Data::Float32(Vec::new()),
472 P::Float64 => Data::Float64(Vec::new()),
473 P::Interval => Data::Interval(Vec::new()),
474 P::Varlen => Data::Varlen(StringColumn::new()),
475 other => {
476 return Err(Error::not_implemented(format!(
477 "a flat vector of {other:?} data, which arrives with the storage layer"
478 )));
479 }
480 })
481}
482
483fn push_value(data: &mut Data, value: &Value) -> Result<()> {
488 macro_rules! push {
489 ($vec:expr, $variant:path, $zero:expr) => {
490 match value {
491 Value::Null => $vec.push($zero),
492 $variant(x) => $vec.push(*x),
493 other => {
494 return Err(Error::internal(format!(
495 "{other:?} does not belong in this vector"
496 )));
497 }
498 }
499 };
500 }
501 match data {
502 Data::Empty => {}
503 Data::Bool(v) => push!(v, Value::Boolean, false),
504 Data::Int8(v) => push!(v, Value::TinyInt, 0),
505 Data::Int16(v) => push!(v, Value::SmallInt, 0),
506 Data::Int32(v) => match value {
507 Value::Null => v.push(0),
508 Value::Integer(x) | Value::Date(x) => v.push(*x),
509 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
510 },
511 Data::Int64(v) => match value {
512 Value::Null => v.push(0),
513 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
514 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
515 },
516 Data::Int128(v) => match value {
517 Value::Null => v.push(0),
518 Value::HugeInt(x) => v.push(*x),
519 Value::Decimal { unscaled, .. } => v.push(*unscaled),
520 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
521 },
522 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
523 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
524 Data::UInt32(v) => push!(v, Value::UInteger, 0),
525 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
526 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
527 Data::Float32(v) => push!(v, Value::Float, 0.0),
528 Data::Float64(v) => push!(v, Value::Double, 0.0),
529 Data::Interval(v) => match value {
530 Value::Null => v.push((0, 0, 0)),
531 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
532 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
533 },
534 Data::Varlen(column) => match value {
535 Value::Null => {
536 column.push("");
537 }
538 Value::Varchar(text) => {
539 column.push(text);
540 }
541 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
545 Ok(text) => {
546 column.push(text);
547 }
548 Err(_) => {
549 return Err(Error::not_implemented(
550 "a blob that is not valid UTF-8, which needs the byte column from M2",
551 ));
552 }
553 },
554 other => return Err(Error::internal(format!("{other:?} is not a string"))),
555 },
556 }
557 Ok(())
558}
559
560#[cfg(test)]
561mod tests {
562 use rudb_common::{LogicalType, Value};
563
564 use super::{Data, Form, VECTOR_SIZE, Vector};
565 use crate::string::StringColumn;
566 use crate::validity::Validity;
567
568 fn integers(values: &[i32]) -> Vector {
569 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec())).unwrap()
570 }
571
572 #[test]
573 fn the_vector_size_is_the_one_the_design_is_built_around() {
574 assert_eq!(VECTOR_SIZE, 1024);
577 assert_eq!(VECTOR_SIZE / 64, 16);
578 }
579
580 #[test]
581 fn a_flat_vector_reads_back_what_was_put_in_it() {
582 let vector = integers(&[1, 2, 3]);
583 assert_eq!(vector.form(), Form::Flat);
584 assert_eq!(vector.len(), 3);
585 assert_eq!(vector.value_at(1), Value::Integer(2));
586 assert_eq!(
587 vector.iter().collect::<Vec<_>>(),
588 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
589 );
590 }
591
592 #[test]
593 fn a_vector_built_from_values_reads_the_same_values_back() {
594 let vector = Vector::from_values(
595 LogicalType::Varchar,
596 &[
597 Value::Varchar("a".to_string()),
598 Value::Null,
599 Value::Varchar("a string too long to sit inside a view".to_string()),
600 ],
601 )
602 .expect("strings and a null");
603 assert_eq!(vector.len(), 3);
604 assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
605 assert_eq!(vector.value_at(1), Value::Null);
606 assert_eq!(
607 vector.value_at(2),
608 Value::Varchar("a string too long to sit inside a view".to_string())
609 );
610 }
611
612 #[test]
615 fn a_null_in_the_middle_does_not_move_the_values_after_it() {
616 let vector = Vector::from_values(
617 LogicalType::Integer,
618 &[Value::Integer(1), Value::Null, Value::Integer(3)],
619 )
620 .expect("integers and a null");
621 assert_eq!(vector.value_at(2), Value::Integer(3));
622 assert!(vector.validity().has_nulls(3), "the middle one is null");
623 }
624
625 #[test]
626 fn a_value_the_type_cannot_hold_is_refused() {
627 let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
628 assert!(wrong.is_err(), "a string is not an integer");
629 }
630
631 #[test]
632 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
633 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1]));
635 assert!(wrong.is_err());
636 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1]));
637 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
638 }
639
640 #[test]
641 fn a_constant_vector_costs_one_value_whatever_its_length() {
642 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
643 assert_eq!(vector.form(), Form::Constant);
644 assert_eq!(vector.len(), VECTOR_SIZE);
645 assert_eq!(vector.value_at(0), Value::Integer(7));
646 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
647 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
648 }
649
650 #[test]
651 fn a_constant_null_is_all_invalid_without_being_told() {
652 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
653 assert_eq!(vector.validity(), &Validity::AllInvalid);
654 assert_eq!(vector.value_at(3), Value::Null);
655 }
656
657 #[test]
658 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
659 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
660 assert_eq!(vector.form(), Form::Sequence);
661 assert_eq!(vector.value_at(0), Value::BigInt(100));
662 assert_eq!(vector.value_at(923), Value::BigInt(1023));
663 let stepped = Vector::sequence(0, 5, 4);
664 assert_eq!(
665 stepped.iter().collect::<Vec<_>>(),
666 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
667 );
668 }
669
670 #[test]
671 fn a_dictionary_vector_reads_through_its_codes() {
672 let mut column = StringColumn::new();
673 column.push("red");
674 column.push("green");
675 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
676 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
677 assert_eq!(vector.form(), Form::Dictionary);
678 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
679 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
680 assert_eq!(vector.len(), 4);
681 }
682
683 #[test]
684 fn a_dictionary_code_past_the_end_is_refused() {
685 let values = integers(&[1, 2]);
688 assert!(Vector::dictionary(vec![0, 2], values).is_err());
689 }
690
691 #[test]
692 fn every_form_flattens_to_the_same_values_it_reads_out() {
693 let mut column = StringColumn::new();
697 column.push("alpha");
698 column.push("beta");
699 let dictionary = Vector::dictionary(
700 vec![1, 0, 1],
701 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
702 )
703 .unwrap();
704 let cases = [
705 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
706 Vector::sequence(7, -2, 5),
707 dictionary,
708 ];
709 for vector in cases {
710 let flat = vector.flatten().unwrap();
711 assert_eq!(flat.form(), Form::Flat);
712 assert_eq!(flat.len(), vector.len());
713 for index in 0..vector.len() {
714 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
715 }
716 }
717 }
718
719 #[test]
720 fn a_null_still_occupies_a_position_after_flattening() {
721 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
725 let flat = vector.flatten().unwrap();
726 assert_eq!(flat.value_at(0), Value::BigInt(0));
727 assert_eq!(flat.value_at(1), Value::Null);
728 assert_eq!(flat.value_at(2), Value::BigInt(2));
729 assert_eq!(flat.value_at(3), Value::BigInt(3));
730 }
731
732 #[test]
737 fn a_null_behind_a_dictionary_survives_flattening() {
738 let values =
739 Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
740 let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
741 let flat = dictionary.flatten().unwrap();
742 assert_eq!(flat.value_at(0), Value::Null);
743 assert_eq!(flat.value_at(1), Value::Integer(3));
744 assert_eq!(flat.value_at(2), Value::Null);
745 }
746
747 #[test]
748 fn flattening_a_flat_vector_is_the_same_vector() {
749 let vector = integers(&[1, 2, 3]);
750 assert_eq!(vector.flatten().unwrap(), vector);
751 }
752
753 #[test]
754 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
755 let ty = LogicalType::decimal(9, 2).unwrap();
756 let vector = Vector::flat(ty, Data::Int32(vec![1234])).unwrap();
757 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
758 assert_eq!(vector.value_at(0).to_string(), "12.34");
759 }
760}