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 #[must_use]
199 pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
200 let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
201 Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
202 }
203
204 #[must_use]
209 pub fn sequence(start: i64, step: i64, len: usize) -> Self {
210 Self {
211 ty: LogicalType::BigInt,
212 len,
213 validity: Validity::AllValid,
214 body: Body::Sequence { start, step },
215 }
216 }
217
218 pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
228 if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
229 return Err(Error::internal(format!(
230 "dictionary code {bad} is past the end of a {} value dictionary",
231 values.len()
232 )));
233 }
234 Ok(Self {
235 ty: values.ty.clone(),
236 len: codes.len(),
237 validity: Validity::AllValid,
238 body: Body::Dictionary { codes, values: Box::new(values) },
239 })
240 }
241
242 #[must_use]
244 pub fn with_validity(mut self, validity: Validity) -> Self {
245 self.validity = validity;
246 self
247 }
248
249 #[must_use]
251 pub fn logical_type(&self) -> &LogicalType {
252 &self.ty
253 }
254
255 #[must_use]
257 pub fn len(&self) -> usize {
258 self.len
259 }
260
261 #[must_use]
263 pub fn is_empty(&self) -> bool {
264 self.len == 0
265 }
266
267 #[must_use]
269 pub fn validity(&self) -> &Validity {
270 &self.validity
271 }
272
273 #[must_use]
275 pub fn form(&self) -> Form {
276 match self.body {
277 Body::Flat(_) => Form::Flat,
278 Body::Constant(_) => Form::Constant,
279 Body::Sequence { .. } => Form::Sequence,
280 Body::Dictionary { .. } => Form::Dictionary,
281 }
282 }
283
284 #[must_use]
289 pub fn data(&self) -> Option<&Data> {
290 match &self.body {
291 Body::Flat(data) => Some(data),
292 _ => None,
293 }
294 }
295
296 #[must_use]
302 pub fn value_at(&self, index: usize) -> Value {
303 if index >= self.len || !self.validity.is_valid(index) {
304 return Value::Null;
305 }
306 match &self.body {
307 Body::Constant(value) => value.as_ref().clone(),
308 Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
309 Body::Dictionary { codes, values } => match codes.get(index) {
310 Some(&code) => values.value_at(code as usize),
311 None => Value::Null,
312 },
313 Body::Flat(data) => value_from(&self.ty, data, index),
314 }
315 }
316
317 pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
319 (0..self.len).map(|index| self.value_at(index))
320 }
321
322 pub fn flatten(&self) -> Result<Self> {
333 if let Body::Flat(_) = self.body {
334 return Ok(self.clone());
335 }
336 let mut data = empty_data_for(&self.ty)?;
337 for index in 0..self.len {
338 push_value(&mut data, &self.value_at(index))?;
339 }
340 let validity = Validity::from_iter(self.len, |index| self.validity.is_valid(index));
341 Ok(Self { ty: self.ty.clone(), len: self.len, validity, body: Body::Flat(data) })
342 }
343}
344
345fn layout_of(data: &Data) -> rudb_common::PhysicalType {
347 use rudb_common::PhysicalType as P;
348 match data {
349 Data::Empty => P::Empty,
350 Data::Bool(_) => P::Bool,
351 Data::Int8(_) => P::Int8,
352 Data::Int16(_) => P::Int16,
353 Data::Int32(_) => P::Int32,
354 Data::Int64(_) => P::Int64,
355 Data::Int128(_) => P::Int128,
356 Data::UInt8(_) => P::UInt8,
357 Data::UInt16(_) => P::UInt16,
358 Data::UInt32(_) => P::UInt32,
359 Data::UInt64(_) => P::UInt64,
360 Data::UInt128(_) => P::UInt128,
361 Data::Float32(_) => P::Float32,
362 Data::Float64(_) => P::Float64,
363 Data::Interval(_) => P::Interval,
364 Data::Varlen(_) => P::Varlen,
365 }
366}
367
368fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
373 let signed = || data.signed_at(index);
374 let unsigned = || data.unsigned_at(index);
375 let value = match ty {
376 LogicalType::Boolean => match data {
377 Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
378 _ => None,
379 },
380 LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
381 LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
382 LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
383 LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
384 LogicalType::HugeInt => signed().map(Value::HugeInt),
385 LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
386 LogicalType::USmallInt => {
387 unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
388 }
389 LogicalType::UInteger => {
390 unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
391 }
392 LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
393 LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
394 LogicalType::Float => match data {
395 Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
396 _ => None,
397 },
398 LogicalType::Double => match data {
399 Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
400 _ => None,
401 },
402 LogicalType::Decimal { width, scale } => {
403 signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
404 }
405 LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
406 LogicalType::Blob | LogicalType::Bit => {
407 data.str_at(index).map(|s| Value::Blob(s.as_bytes().to_vec()))
408 }
409 LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
410 LogicalType::Time | LogicalType::TimeTz => {
411 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
412 }
413 LogicalType::Timestamp
414 | LogicalType::TimestampS
415 | LogicalType::TimestampMs
416 | LogicalType::TimestampNs
417 | LogicalType::TimestampTz => {
418 signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
419 }
420 LogicalType::Interval => match data {
421 Data::Interval(v) => {
422 v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
423 }
424 _ => None,
425 },
426 _ => None,
427 };
428 value.unwrap_or(Value::Null)
429}
430
431fn empty_data_for(ty: &LogicalType) -> Result<Data> {
433 use rudb_common::PhysicalType as P;
434 Ok(match ty.physical() {
435 P::Empty => Data::Empty,
436 P::Bool => Data::Bool(Vec::new()),
437 P::Int8 => Data::Int8(Vec::new()),
438 P::Int16 => Data::Int16(Vec::new()),
439 P::Int32 => Data::Int32(Vec::new()),
440 P::Int64 => Data::Int64(Vec::new()),
441 P::Int128 => Data::Int128(Vec::new()),
442 P::UInt8 => Data::UInt8(Vec::new()),
443 P::UInt16 => Data::UInt16(Vec::new()),
444 P::UInt32 => Data::UInt32(Vec::new()),
445 P::UInt64 => Data::UInt64(Vec::new()),
446 P::UInt128 => Data::UInt128(Vec::new()),
447 P::Float32 => Data::Float32(Vec::new()),
448 P::Float64 => Data::Float64(Vec::new()),
449 P::Interval => Data::Interval(Vec::new()),
450 P::Varlen => Data::Varlen(StringColumn::new()),
451 other => {
452 return Err(Error::not_implemented(format!(
453 "a flat vector of {other:?} data, which arrives with the storage layer"
454 )));
455 }
456 })
457}
458
459fn push_value(data: &mut Data, value: &Value) -> Result<()> {
464 macro_rules! push {
465 ($vec:expr, $variant:path, $zero:expr) => {
466 match value {
467 Value::Null => $vec.push($zero),
468 $variant(x) => $vec.push(*x),
469 other => {
470 return Err(Error::internal(format!(
471 "{other:?} does not belong in this vector"
472 )));
473 }
474 }
475 };
476 }
477 match data {
478 Data::Empty => {}
479 Data::Bool(v) => push!(v, Value::Boolean, false),
480 Data::Int8(v) => push!(v, Value::TinyInt, 0),
481 Data::Int16(v) => push!(v, Value::SmallInt, 0),
482 Data::Int32(v) => match value {
483 Value::Null => v.push(0),
484 Value::Integer(x) | Value::Date(x) => v.push(*x),
485 other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
486 },
487 Data::Int64(v) => match value {
488 Value::Null => v.push(0),
489 Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
490 other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
491 },
492 Data::Int128(v) => match value {
493 Value::Null => v.push(0),
494 Value::HugeInt(x) => v.push(*x),
495 Value::Decimal { unscaled, .. } => v.push(*unscaled),
496 other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
497 },
498 Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
499 Data::UInt16(v) => push!(v, Value::USmallInt, 0),
500 Data::UInt32(v) => push!(v, Value::UInteger, 0),
501 Data::UInt64(v) => push!(v, Value::UBigInt, 0),
502 Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
503 Data::Float32(v) => push!(v, Value::Float, 0.0),
504 Data::Float64(v) => push!(v, Value::Double, 0.0),
505 Data::Interval(v) => match value {
506 Value::Null => v.push((0, 0, 0)),
507 Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
508 other => return Err(Error::internal(format!("{other:?} is not an interval"))),
509 },
510 Data::Varlen(column) => match value {
511 Value::Null => {
512 column.push("");
513 }
514 Value::Varchar(text) => {
515 column.push(text);
516 }
517 Value::Blob(bytes) => match std::str::from_utf8(bytes) {
521 Ok(text) => {
522 column.push(text);
523 }
524 Err(_) => {
525 return Err(Error::not_implemented(
526 "a blob that is not valid UTF-8, which needs the byte column from M2",
527 ));
528 }
529 },
530 other => return Err(Error::internal(format!("{other:?} is not a string"))),
531 },
532 }
533 Ok(())
534}
535
536#[cfg(test)]
537mod tests {
538 use rudb_common::{LogicalType, Value};
539
540 use super::{Data, Form, VECTOR_SIZE, Vector};
541 use crate::string::StringColumn;
542 use crate::validity::Validity;
543
544 fn integers(values: &[i32]) -> Vector {
545 Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec())).unwrap()
546 }
547
548 #[test]
549 fn the_vector_size_is_the_one_the_design_is_built_around() {
550 assert_eq!(VECTOR_SIZE, 1024);
553 assert_eq!(VECTOR_SIZE / 64, 16);
554 }
555
556 #[test]
557 fn a_flat_vector_reads_back_what_was_put_in_it() {
558 let vector = integers(&[1, 2, 3]);
559 assert_eq!(vector.form(), Form::Flat);
560 assert_eq!(vector.len(), 3);
561 assert_eq!(vector.value_at(1), Value::Integer(2));
562 assert_eq!(
563 vector.iter().collect::<Vec<_>>(),
564 vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
565 );
566 }
567
568 #[test]
569 fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
570 let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1]));
572 assert!(wrong.is_err());
573 let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1]));
574 assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
575 }
576
577 #[test]
578 fn a_constant_vector_costs_one_value_whatever_its_length() {
579 let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
580 assert_eq!(vector.form(), Form::Constant);
581 assert_eq!(vector.len(), VECTOR_SIZE);
582 assert_eq!(vector.value_at(0), Value::Integer(7));
583 assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
584 assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
585 }
586
587 #[test]
588 fn a_constant_null_is_all_invalid_without_being_told() {
589 let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
590 assert_eq!(vector.validity(), &Validity::AllInvalid);
591 assert_eq!(vector.value_at(3), Value::Null);
592 }
593
594 #[test]
595 fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
596 let vector = Vector::sequence(100, 1, VECTOR_SIZE);
597 assert_eq!(vector.form(), Form::Sequence);
598 assert_eq!(vector.value_at(0), Value::BigInt(100));
599 assert_eq!(vector.value_at(923), Value::BigInt(1023));
600 let stepped = Vector::sequence(0, 5, 4);
601 assert_eq!(
602 stepped.iter().collect::<Vec<_>>(),
603 vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
604 );
605 }
606
607 #[test]
608 fn a_dictionary_vector_reads_through_its_codes() {
609 let mut column = StringColumn::new();
610 column.push("red");
611 column.push("green");
612 let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
613 let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
614 assert_eq!(vector.form(), Form::Dictionary);
615 assert_eq!(vector.logical_type(), &LogicalType::Varchar);
616 assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
617 assert_eq!(vector.len(), 4);
618 }
619
620 #[test]
621 fn a_dictionary_code_past_the_end_is_refused() {
622 let values = integers(&[1, 2]);
625 assert!(Vector::dictionary(vec![0, 2], values).is_err());
626 }
627
628 #[test]
629 fn every_form_flattens_to_the_same_values_it_reads_out() {
630 let mut column = StringColumn::new();
634 column.push("alpha");
635 column.push("beta");
636 let dictionary = Vector::dictionary(
637 vec![1, 0, 1],
638 Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
639 )
640 .unwrap();
641 let cases = [
642 Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
643 Vector::sequence(7, -2, 5),
644 dictionary,
645 ];
646 for vector in cases {
647 let flat = vector.flatten().unwrap();
648 assert_eq!(flat.form(), Form::Flat);
649 assert_eq!(flat.len(), vector.len());
650 for index in 0..vector.len() {
651 assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
652 }
653 }
654 }
655
656 #[test]
657 fn a_null_still_occupies_a_position_after_flattening() {
658 let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
662 let flat = vector.flatten().unwrap();
663 assert_eq!(flat.value_at(0), Value::BigInt(0));
664 assert_eq!(flat.value_at(1), Value::Null);
665 assert_eq!(flat.value_at(2), Value::BigInt(2));
666 assert_eq!(flat.value_at(3), Value::BigInt(3));
667 }
668
669 #[test]
670 fn flattening_a_flat_vector_is_the_same_vector() {
671 let vector = integers(&[1, 2, 3]);
672 assert_eq!(vector.flatten().unwrap(), vector);
673 }
674
675 #[test]
676 fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
677 let ty = LogicalType::decimal(9, 2).unwrap();
678 let vector = Vector::flat(ty, Data::Int32(vec![1234])).unwrap();
679 assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
680 assert_eq!(vector.value_at(0).to_string(), "12.34");
681 }
682}