use rudb_common::{LogicalType, Value};
use rudb_vector::{Validity, Vector};
pub(crate) fn nulls_of(vector: &Vector) -> Validity {
let Some((codes, values)) = vector.dictionary_parts() else {
return vector.validity().clone();
};
let inside = match values.validity() {
Validity::AllValid => Validity::AllValid,
Validity::AllInvalid if codes.is_empty() => Validity::AllValid,
Validity::AllInvalid => Validity::AllInvalid,
inner => {
let live: Vec<bool> = codes.iter().map(|&code| inner.is_valid(code as usize)).collect();
Validity::from_run(&live)
}
};
match vector.validity() {
Validity::AllValid => inside,
outer => outer.and(&inside, vector.len()),
}
}
pub(crate) fn identity(index: usize) -> usize {
index
}
pub(crate) fn first(_: usize) -> usize {
0
}
pub(crate) fn single(ty: &LogicalType, value: &Value) -> Option<Vector> {
Vector::from_values(ty.clone(), std::slice::from_ref(value)).ok()
}
#[cfg(test)]
mod tests {
use super::*;
fn live(validity: &Validity, len: usize) -> Vec<bool> {
(0..len).map(|row| validity.is_valid(row)).collect()
}
fn values() -> Vector {
Vector::from_values(
LogicalType::Varchar,
&[Value::Varchar("a".into()), Value::Varchar("b".into()), Value::Null],
)
.expect("builds")
}
#[test]
fn a_vector_that_is_not_a_dictionary_is_its_own_validity() {
let flat = Vector::from_values(
LogicalType::Integer,
&[Value::Integer(1), Value::Null, Value::Integer(3)],
)
.expect("builds");
assert_eq!(live(&nulls_of(&flat), 3), [true, false, true]);
}
#[test]
fn a_dictionary_whose_nulls_are_in_its_values_reads_them_through_the_codes() {
let dictionary = Vector::dictionary(vec![0, 2, 1, 2], values()).expect("builds");
assert_eq!(live(&nulls_of(&dictionary), 4), [true, false, true, false]);
}
#[test]
fn a_dictionary_whose_nulls_are_at_its_own_level_reads_them_there() {
let plain = Vector::from_values(
LogicalType::Varchar,
&[Value::Varchar("a".into()), Value::Varchar("b".into())],
)
.expect("builds");
let dictionary = Vector::dictionary(vec![0, 1, 0, 1], plain)
.expect("builds")
.with_validity(Validity::from_run(&[true, false, false, true]));
assert_eq!(live(&nulls_of(&dictionary), 4), [true, false, false, true]);
}
#[test]
fn a_dictionary_with_a_null_in_both_places_is_null_wherever_either_one_says_so() {
let dictionary = Vector::dictionary(vec![0, 2, 1, 1], values())
.expect("builds")
.with_validity(Validity::from_run(&[true, true, false, true]));
assert_eq!(live(&nulls_of(&dictionary), 4), [true, false, false, true]);
}
#[test]
fn an_all_invalid_dictionary_is_all_invalid_however_valid_its_values_are() {
let plain = Vector::from_values(LogicalType::Varchar, &[Value::Varchar("a".into())])
.expect("builds");
let dictionary = Vector::dictionary(vec![0, 0], plain)
.expect("builds")
.with_validity(Validity::AllInvalid);
assert_eq!(live(&nulls_of(&dictionary), 2), [false, false]);
}
}